deckspace.dev / DeckSpace / docs / panes-and-clis

Panes and agent CLIs

DeckSpace ships no model. It runs the agent CLIs already installed on your machine, side by side, as peers — and those CLIs do not accept the same flags.

A pane is a terminal. A pane running an agent is the same terminal with an agent CLI as its process. That is the whole mechanism: DeckSpace resolves the command on your login-shell PATH, launches it, and appends the flags that CLI publishes for the toggles you set. Your existing auth, config and subscriptions come along, because it is your CLI running.

The consequence is the thing to understand before you set anything up: a toggle in the DeckSpace UI is not a DeckSpace feature. It is a flag lookup. Where a CLI has no such flag, the toggle is a silent no-op for that pane.

The pane grid

Panes belong to a workspace, not to the app. Switching workspaces swaps the whole set of terminals; each workspace’s grid stays mounted while hidden, so its shells and running agents survive the switch.

LimitValueWhere it is set
Panes per workspace16MAX_PANES
Layout presets in the command palette1, 2, 4, 6, 8, 12plus Add pane for anything else
Layout presets in the setup wizard1, 2, 4, 6, 8, 10, 12tiles on the workspace step
Grid shapefixed per count16 panes tile 4×4; 12 tile 4×3; 9 tile 3×3

Two per-pane split buttons in the pane header add one pane at a time: split right puts a new column beside it, split down stacks one below it inside the same column. Both are disabled once the workspace holds 16 panes. Column and row splits are draggable and remembered per grid shape, so a 3×2 layout keeps its proportions across restarts.

Closing a pane kills its shell and any agent in it. Closing the last pane in a workspace does not empty the workspace — it replaces the dead shell with one fresh pane.

What happens at 16

The cap is enforced at every launch path, but each one handles it differently. None of them silently drop work.

LauncherBehaviour at the cap
Launch into a new paneFalls back to launching into the active pane.
Split buttonsDisabled.
OrchestratorLogs “Pane limit reached — waiting for a task to finish before launching more” and waits.
MaestroErrors: the grid is full — close panes, then resume.
HandoffAborts the handoff with the grid-full reason.
VoiceErrors back to you: the grid is full, 16 panes is the max.

The registry

Twelve CLIs are built in. Eleven are current; one is retired and kept only so old workspaces still resolve. Each entry is a key, a display name, the command DeckSpace looks for, and how a prompt is handed to it.

KeyDisplay nameBinaryHow the prompt is passed
claudeClaude Codeclaudepositional
codexCodexcodexpositional
aiderAideraider--message
agyAntigravityagy-p
geminiGemini (legacy CLI)gemini-pretired, see below
opencodeOpenCodeopencode--prompt
cursorCursor Agentcursor-agentpositional
droidDroiddroidexec
copilotCopilot CLIcopilot-p
grokGrok CLIgrokpositional
ampAmpamppositional
qwenQwen Codeqwen-p

Two entries carry a hard-coded exception, because getting them wrong breaks the pane rather than degrading it. Grok’s prompt is always positional — passing it through a -p-style flag makes the CLI print one reply and exit instead of opening its interface. OpenCode’s positional argument is a project path, not a task, so a prompt always goes through --prompt.

Which toggles each CLI actually supports

This is the table to read before choosing a CLI for a job. A blank cell is a real capability gap: the flag does not exist, so DeckSpace appends nothing and the toggle does nothing for that pane.

CLIFastPlanWalk-awayAuto-editModel pin
Claude Code--model haiku--permission-mode plan--dangerously-skip-permissions--permission-mode acceptEdits--model
Antigravity--model "Gemini 3.5 Flash (Low)"--mode plan--dangerously-skip-permissions--mode accept-edits--model
Grok CLI--permission-mode plan--always-approve--permission-mode acceptEdits-m
Codex--dangerously-bypass-approvals-and-sandbox--ask-for-approval never-m
Qwen Code--yolo--approval-mode auto_edit
OpenCode--auto-m
Aider
Droid
Copilot CLI
Cursor Agent
Amp
Gemini (legacy)-m gemini-2.5-flash--yolo--approval-mode auto_edit-m

Counting the eleven current CLIs: 2 support Fast, 3 support Plan, 6 support walk-away, 5 support auto-edit, 5 support a model pin. Exactly two — Claude Code and Antigravity — support all five. Five of them — Aider, Droid, Copilot CLI, Cursor Agent and Amp — support none of the five, so their launch is the command plus the prompt and nothing more, whatever you have switched on.

A no-op toggle looks identical to a working one

Nothing in the pane tells you a flag was skipped. If you set Fast Mode and launch Aider, the toggle stays lit and the launch is unchanged. Check this table, not the switch.

Flag order and precedence

When more than one toggle is on, DeckSpace resolves the conflicts before building the command, in this fixed order.

  1. Model pin first, if you pinned one and the CLI has a model flag. The value is single-quoted, because it is typed into a shell and some model names contain spaces and parentheses.
  2. Fast — skipped entirely if a model is pinned. For Claude Code both drive the same --model flag, and emitting it twice breaks the launch.
  3. Plan.
  4. Walk-away.
  5. Auto-edit — skipped if either plan or walk-away is on, for the same duplicate-flag reason.

Reasoning effort is not a CLI flag. For Claude Code panes it is exported as MAX_THINKING_TOKENS before the command runs; for every other CLI it does nothing.

The Gemini entry is retired

The gemini CLI stopped serving requests on 18 June 2026. Its registry entry is still present so saved workspaces, presets and stored pane state keep resolving rather than erroring, but it is superseded by agy (Antigravity).

Launching the gemini key from a pane redirects to agy. The redirect in the pane-launch path is unconditional — it does not check what you have installed — so on a machine that still has a working gemini but no agy, that launch fails with a not-on-PATH error naming agy. Headless launches (background jobs and workflows) resolve differently: they keep the original binary while it is installed, and redirect only when it is absent and the replacement is present.

Practical advice

Install agy and use the Antigravity entry directly. The install hint stored against the gemini key is not an install command for it — it is a comment saying the CLI is retired, followed by the Antigravity installer.

Installing a CLI

DeckSpace does not install anything. Settings → AI providers runs a scan that checks your login-shell PATH for the known command names and asks each one for its version, with a three-second cap per CLI. Nothing is installed, nothing is changed, and nothing leaves the machine. The scan only ever runs when you click it.

For any CLI it did not find, the row shows a one-line install command with a Copy install button. These are the commands it copies.

CLIInstall command
Claude Codenpm i -g @anthropic-ai/claude-code
Codexnpm i -g @openai/codex
Aiderpython -m pip install aider-install && aider-install
Antigravitycurl -fsSL https://antigravity.google/cli/install.sh | bash
OpenCodenpm i -g opencode-ai
Cursor Agentcurl https://cursor.com/install -fsS | bash
Droidcurl -fsSL https://app.factory.ai/cli | sh
Copilot CLInpm i -g @github/copilot
Grok CLIcurl -fsSL https://x.ai/cli/install.sh | bash
Ampnpm i -g @sourcegraph/amp
Qwen Codenpm i -g @qwen-code/qwen-code

Run the command in a terminal yourself, then rescan. Custom agents you register get no install hint — their row reads “not found — install <command> and rescan” instead.

When a CLI is installed but the app cannot find it

This is the most common setup failure, and it is not specific to DeckSpace. An app launched from the Dock or Finder inherits a minimal PATH that is missing version-manager shims, so a claude that works in your terminal is invisible to the app.

DeckSpace works around it by asking your login shell for its real PATH once, with a 1.5-second cap so a hung shell profile cannot block the first pane, then merging in these directories under your home folder:

.local/bin, .grok/bin, .opencode/bin, .cargo/bin, .bun/bin, .npm-global/bin, .deno/bin, .volta/bin, .local/share/mise/shims, bin — plus /opt/homebrew/bin, /usr/local/bin, /usr/bin and /bin.

If your CLI lives somewhere else entirely, the scan will not see it. Register it as a custom agent with its absolute path, which is checked directly rather than searched for on PATH.

Environment variables, not just PATH

The same problem hits API keys exported from ~/.zshenv. DeckSpace reads your login shell’s environment once and passes through only the variables the app does not already have — PATH excluded, since it is handled separately. Anything the app itself sets wins, so this can supply a missing key but never quietly change one.

Two ways a pane starts an agent

Which one you get depends on how you launched, and it is worth knowing because the two behave differently.

Typed into a shellRun as the pane’s process
What the pane runsyour login shell, with the agent command typed into itthe agent CLI itself, no shell in between
Used bylaunching into an existing panelaunching into a new pane
Startupwaits for the shell to start firststarts the CLI directly
Your shell profilesourced by the shell as usualnever sourced — the missing variables are injected instead

Both paths arm the destructive-command guard on the pane. The shell path exports it before typing the command; the process path sets it in the spawn environment, because there is no shell to export into.

Registering a custom agent CLI

Any command on your PATH, or any absolute path, can be added to the registry. It then appears in every agent picker — palette, kanban, swarm, loop — alongside the built-ins, and is probed by the scan the same way.

Settings → AI providers → Custom agent CLIs. The form takes these fields.

FieldRequiredRules
Keyyeskebab-case, 2–24 characters of a–z, 0–9 or -. Auto-filled from the name until you edit it.
NamenoDisplay name. Falls back to the command if left blank.
CommandyesBare name resolved on your login-shell PATH, or an absolute path.
Prompt flagnoBlank means the prompt is passed positionally.
Fast flagnoBlank means Fast Mode is a no-op for it.
Plan flagnoBlank means Plan Mode is a no-op for it.
Walk-away flagnoBlank means walk-away is a no-op for it.
Auto-edit flagnoBlank means auto-accept-edits is a no-op for it.
Model flagnoBlank means a pinned model is dropped for it.
AccentnoHex colour for its chips. Defaults to a neutral grey.

A key that matches a built-in is rejected, and so is a duplicate of an existing custom key. Entries are stored as pretty-printed JSON in custom-agents.json in the app config directory, so you can read and version them outside the app.

Three things to know before you rely on one

The two positional-prompt exceptions are keyed to the built-in grok and opencode keys. A custom entry never gets that special handling. If you register a terminal-interface CLI and give it a -p-style prompt flag it does not support that way, the pane will print one reply and exit.

A malformed custom-agents.json is treated as empty. If you hand-edit the file and break the JSON, every custom agent disappears from the pickers with no error shown.

Removal is best-effort on disk. The entry leaves the list immediately, but if writing the file fails it comes back the next time the registry is read.

Older custom entries

The plan, walk-away, auto-edit and model fields were added after the original custom-agent format, which carried only the prompt and fast flags. Files written before that parse unchanged, but any entry registered then has those four fields empty — and empty means the matching toggle silently does nothing. Re-open the entry and fill them in if you want those toggles to work.

Platform notes

PlatformLogin-shell PATH and environment probe
macOSyes shell queried at startup
Linuxyes same path as macOS
Windowsnot run the app’s own environment is used, with .exe, .cmd and .bat extensions checked when resolving a command

The registry itself, the flag tables and the custom-agent form are identical on every platform. What differs is only how a command is found.

Where to go next