Get started

Install a coding CLI

The Termdeck agent is a relay. It does not bring a coding agent with it, so every machine needs at least one of Claude Code, Codex, or Grok installed and signed in. You can install all three and pick per chat.

Setting this up for the first time? Use Claude Code and Codex in one UI walks through it in order, start to finish.

Why these are separate installs

Termdeck drives the official CLI, unmodified, under your own subscription. That is what keeps your local repository, environment variables, credentials, MCP servers, and model access working exactly as they do in a terminal. It also means Termdeck never sees your provider password: each CLI stores its own credentials in its own config directory, and Termdeck reads the state rather than the secret.

Claude Code

On the machine
npm install -g @anthropic-ai/claude-code
claude

Running claude once starts the login flow. Sign in with the Anthropic account whose plan you want the turns billed against.

  • Sessions on disk: ~/.claude/projects/<project slug>/<session id>.jsonl
  • Resume in a terminal: claude --resume
  • Config directory: ~/.claude, or wherever CLAUDE_CONFIG_DIR points

Claude is the engine with the deepest Termdeck integration: live permission prompts, sub agent status, checkpoint restore and MCP server state all come from Claude's own stream. Slash commands come from two places. The CLI names them, and Termdeck reads their descriptions and argument hints off disk, including any your project defines.

OpenAI Codex

On the machine
npm install -g @openai/codex
codex login
  • Sessions on disk: rollout files under $CODEX_HOME/sessions
  • Resume in a terminal: codex resume
  • Config directory: $CODEX_HOME, defaulting to ~/.codex

Codex has native plan mode, and Termdeck exposes it in the same picker as the other engines. The slash palette lists the skills installed for a Codex chat with their descriptions, but Codex has no slash commands of its own. Picking one writes it into the composer as text for the model to act on, rather than running a command.

xAI Grok

On the machine
npm install -g @vibe-kit/grok-cli
grok login
  • Sessions on disk: Grok's own session files, shared with the terminal
  • Protocol: Agent Client Protocol, driven through grok agent stdio

Use grok login so turns run against your SuperGrok subscription. Grok has no plan mode of its own, so Termdeck's Plan option behaves as read only there and the interface says so under the picker.

How Termdeck finds a CLI

The agent asks the operating system the same question your shell asks: where on Windows, command -v on macOS and Linux. Anything on the path counts as installed, which matches what happens when you type the command yourself.

A CLI installed after the machine connected is picked up without restarting anything. Press Recheck on the machine and it shows as installed; starting a chat on that engine finds it too.

If a binary lives somewhere unusual, name it explicitly in the agent's environment:

VariablePoints at
TERMDECK_CLAUDE_EXEThe Claude Code executable
TERMDECK_CODEX_EXEThe Codex executable
TERMDECK_GROK_EXEThe Grok executable

Add them to ~/.termdeck/agent.env and restart the agent. Note that a background service does not inherit your login shell's environment, so a CLI that only works after your shell profile runs is exactly the case these variables exist for.

A machine can hold more than one copy of the same CLI, for example an npm global and a package manager install both on the path. When that happens, Termdeck and your shell can disagree about which one is the binary, which shows up as a sign in that appears to hang. Removing the copy you do not want, or naming the right one with the variables above, resolves it.

Confirming a CLI is signed in

Open Settings, then Machines and accounts. Each machine card lists the three engines with one of five states:

StateMeaningWhat to do
Signed inInstalled and holding a usable login.Nothing. It can run turns.
Not signed inInstalled, no usable login. Turns will not start.Run the engine's login command on the machine.
Sign in expiredA login is saved, but the machine tried it and the provider refused it. Turns will not start.Run claude on the machine once to refresh it, or switch to another saved account on the card.
Not installedThe binary is not on the path.Install it, or point at it with an executable variable.
Could not checkThe machine did not answer.Nothing is broken by this alone. It is never treated as signed out.

A machine you have just connected shows the same states in the last step of the connect wizard, with the fix next to each one: the install command to copy for Not installed, a Sign in button for Not signed in or Sign in expired (Claude Code and Codex; Grok shows its login command to run on the machine). The wizard checks again every few seconds until one engine is ready, so a CLI you install in a terminal shows up there without a refresh.

The distinction in the last row matters more than it looks. "We could not tell" and "it is fine" are the two answers a diagnostic must never confuse, so Termdeck reports the uncertainty rather than guessing in either direction.

Signed in and Sign in expired are two different readings of the same row, and the difference is who was asked. Signed in means a login is saved on the machine. Sign in expired means the machine went and used it and the provider said no, which is the answer that counts. Termdeck only says expired when the machine established that itself, so a request that merely timed out is never reported as a login problem.

Where the engines differ

Termdeck uses one vocabulary across all three so switching engine mid project does not rename every control under you. The mapping is honest about the places where an engine behaves differently, and the interface prints the caveat under the picker.

CapabilityClaude CodeCodexGrok
Live tool approvalsYesYesYes
Image attachmentsYesYesNo, its protocol takes no images
File attachmentsText, data, source, PDF, notebooksText, data, source, notebooksText, data, source, notebooks
Plan modeNativeNativeBehaves as read only
Accept edits modeYesNot offeredYes
Slash commands from the composerYesNoYes
Checkpoint restoreYesNoNo
Sub agent status stripYesRows in the transcriptNo
Saved account switchingYesYesUse the CLI
Terminal resumeYesYesYes

Permission mode names and their per engine behaviour are covered in full on Approvals and permissions.

The model picker differs the same way. What a row can show is whatever that engine's own catalog publishes, so the same picker carries more detail for one engine than for another. Nothing is held back to the levels Termdeck already knew about either: a model released after your last update arrives with whatever thinking levels it ships with.

For Codex, the default thinking level is the one your Codex config sets. If ~/.codex/config.toml has a model_reasoning_effort line, a chat left on the default runs at that level, and the picker names it. Pick a level in the picker to override it for one chat. Whatever level you pick is the one the chat runs at, including the one marked Default: picking it pins that level even if your config changes later.

Running more than one at once

Nothing stops you from having a Claude chat, a Codex chat, and a Grok chat running at the same time, on the same machine or on different ones. They are separate processes with separate transcripts. A common split is a premium subscription on the hard problems and a cheaper engine on the routine work, with the usage dashboard showing whether the split is paying off.

Two agents writing the same transcript would fork it, so Termdeck never does that. If a session is attached to another process, for example a terminal running the CLI on the same chat, the composer stays locked and the browser follows along read only until the terminal lets go.