Skip to main content

Harnesses

A harness is the underlying CLI that drives a workspace agent — the binary that runs in tmux. The model is what the binary calls. They are picked independently per spawn.
Supported today: claude-code (default), ohmypi, codex, and acp. For the wider field of coding-agent harnesses Overdeck could adopt next — and how each one handles skills, MCP, and AGENTS.md — see the Harness Landscape.

Supported harnesses

Claude Code (default)

  • Shipped by Anthropic; Overdeck installs no special integration — drop in claude and run.
  • Works with both subscription auth (Claude Code OAuth) and API-key auth.
  • All role runs (plan, work, review, test, ship) default here.
  • Proxied models use a dedicated Claude Code context policy rather than copying every value from the generic model registry. GPT-5.6 Sol, Terra, and Luna use the current ChatGPT/Codex-client route’s 372000-token capacity for both CLAUDE_CODE_MAX_CONTEXT_TOKENS and CLAUDE_CODE_AUTO_COMPACT_WINDOW. The maximum tells Claude Code the route’s capacity; the auto-compact window is the capacity used by Claude Code’s normal proactive compaction calculation, not an instruction to compact at exactly that token count. GPT-5.5 keeps its separately measured conservative 150000 auto-compact policy and Kimi K2.7 Code keeps its 262144 auto-compact policy without a maximum override. Kimi K3 exports both values from its model capability: 262144 for k3 and 1048576 for k3[1m], matching Kimi’s Claude Code recipe. Anthropic models receive neither override, so Claude Code’s native context behavior remains in control.

oh-my-pi / ohmypi (alternative)

  • Adds RPC mode (omp --mode rpc) so Overdeck can write structured commands to omp’s stdin via a named pipe (mkfifo at ~/.overdeck/agents/<agentId>/rpc.in).
  • Vendored extension at packages/ohmypi-extension/ reports lifecycle events: session_start writes a ready.json, tool_execution_end updates a heartbeat, and a /pan-done slash command writes a completion marker.
  • Multi-provider — drives Anthropic, OpenAI, Google, OpenRouter, Minimax, DashScope through omp’s own provider routing.

OpenAI Codex CLI (alternative)

  • First-party OpenAI agent loop for the GPT model family (GPT-5.6 Sol/Terra/Luna, GPT-5.5, GPT-5.4, GPT-5.3-Codex, …) with ChatGPT-subscription or API-key auth.
  • gpt-5.6-sol is the default OpenAI model surfaced by this harness.
  • Work agents use a persistent codex app-server child by default. Overdeck talks newline-delimited JSON-RPC over stdio, so message delivery, approvals, readiness, and interruption are structured protocol events rather than TUI keystrokes.
  • Set codex.transport: tui as a temporary escape hatch to the legacy live, attachable TUI path (codexMode: work-tui) under the PTY supervisor. Both transports are persistent sessions — never one-shot codex exec.
  • The app-server transport requires Codex CLI 0.144.0 or newer. Upgrade with your normal Codex CLI install method, then verify with codex --version.
  • Runtime adapter at src/lib/runtimes/codex.ts; per-agent thread-id pinning enables session introspection and cost parsing (src/lib/cost-parsers/codex-parser.ts).
  • Native AGENTS.md and Claude-Code-compatible skills; pan sync distributes context layers and skills to it like any other harness.
  • Role-declared MCP servers, such as Playwright for the test role, are provisioned as [mcp_servers.<name>] entries in the per-agent Codex config so browser UAT can run on Codex.

Codex command approvals

Overdeck gives each managed Codex session an isolated CODEX_HOME, but links its rules/ directory to your native ~/.codex/rules/ directory when that user rule layer exists. Execpolicy approvals you deliberately persist in Codex therefore apply to later Overdeck agents instead of prompting once per managed home. For example, this user rule permits the read-only GitHub query without enabling network access for every sandboxed process:
An allow decision runs every matching command outside the sandbox without a prompt, so keep patterns as narrow as the operation permits. In particular:
  • gh issue create and gh issue comment accept file-backed body arguments, so allowing either whole prefix also lets the command read and publish any file the host user can access.
  • A broad git push prefix includes force pushes, deletion refspecs, arbitrary remotes, and option reordering. Keep it prompt-gated unless you route the push through a command that validates the remote, branch, and non-force semantics.
  • [sandbox_workspace_write] network_access = true enables networking for every process in the workspace sandbox. It is broader than a command rule and is unnecessary when only specific trusted commands need network access.
Inspect a rule before relying on it:
See the Codex rules documentation for rule precedence and the full execpolicy syntax.

Agent Client Protocol / Kimi Code CLI (alternative)

Agent Client Protocol (ACP) is an open, newline-delimited JSON-RPC protocol for driving coding agents as persistent child processes. Overdeck’s native acp harness launches the agent without a shell and keeps structured prompts, tool calls, approvals, cancellation, and session resume off the terminal keystroke path. Kimi Code CLI is the first ACP agent wired into Overdeck; other ACP-capable agents require a provider adapter before they can be selected. Install Kimi Code CLI using its getting-started guide, then complete the one-time interactive login before starting an ACP session:
The kimi acp subprocess reuses those saved credentials. If /login has not been completed, Overdeck stops the launch with an authentication-required error rather than silently switching harnesses. pan doctor probes whether the optional kimi prerequisite is available on PATH. Kimi remains on its built-in claude-code default until you opt its provider into ACP in ~/.overdeck/config.yaml:
The provider setting normalizes internally to providerHarnesses.kimi: acp. Version one supports only acp.permissionMode: auto: Overdeck chooses an allow option the ACP agent actually advertised, preferring a session-scoped allow and then a one-shot allow. A configured ACP route fails loudly when its binary or saved authentication is missing; it never falls back to Claude Code. Each session runs through the authenticated acp-host process, with its socket, token, ACP session id, and append-only transcript stored under ~/.overdeck/agents/<agentId>/. The runtime adapter is src/lib/runtimes/acp.ts; Kimi-specific launch and authentication behavior is in src/lib/acp/kimi.ts.

Installing oh-my-pi

oh-my-pi is not auto-installed. Install it once, then run pan doctor to confirm.
pan doctor also checks that packages/ohmypi-extension/dist/index.js exists in the Overdeck workspace. If it doesn’t, run:
After installing omp, run pan sync once. Overdeck writes ~/.omp/agent/settings.json with a skills array pointing at ~/.claude/skills so omp loads the same skill tree Claude Code does. Existing keys in settings.json are preserved.

Provider authentication

Overdeck bridges configured API keys into omp’s environment at launch time, so you do not need to configure auth separately in omp for most providers. When you spawn an ohmypi agent with a Kimi, MiniMax, Z.AI, MiMo, OpenRouter, Nous, or DashScope model, Overdeck injects the native provider env var (KIMI_API_KEY, MINIMAX_API_KEY, etc.) automatically from your dashboard Settings or ~/.overdeck.env. Providers that rely on OAuth / subscription auth (Anthropic, OpenAI Codex) still require you to log in through omp directly (/login inside an omp session) or via Overdeck’s dedicated subscription flows (Claude Code OAuth, Codex CLIProxy auth). Use pan ohmypi-auth to manage omp credentials from the CLI.

Where you pick the harness

The harness is chosen per spawn at four user-initiated surfaces: There is no per-issue lock — an issue planned with ohmypi can have a Claude Code review agent on the same PR, and vice versa.

Switching harness on a live conversation (experimental)

Changing harnesses on an already-running conversation is best-effort. Overdeck attempts to convert the transcript into the new harness format, but that converter is intentionally unsupported and may lose fidelity. If conversion or resume fails, Overdeck falls back to starting a fresh session with the selected harness and model. Use this as an escape hatch, not a support promise. If the converted transcript looks wrong, report the case and continue in the fresh fallback session.

Role runs (plan / work / review / test / ship)

Pipeline-spawned roles do not prompt at runtime. They read per-role harness + model defaults from the dashboard Settings page. A harness selector sits next to each role’s model dropdown to mix and match. Sub-roles such as work.inspect and review.security inherit from the parent role unless configured more specifically. The Settings page is also where you wire up tracker API keys and project configuration, so harness routing for autonomous role runs lives alongside the rest of the orchestrator’s defaults — set the harness once per role here and every pipeline spawn for that role inherits it.

ToS rules

There is exactly one blocked combination, gated by canUseHarness(harness, model, authMode) in src/lib/harness-policy.ts:
Blocked: ohmypi + Anthropic model + Anthropic auth = subscription
This is required by the Claude Code subscription terms — only the claude-code binary may invoke Anthropic models when you’re authenticated via the Claude Code OAuth subscription. Everything else is allowed: The gate is evaluated at every spawn entry point and at every picker UI so a stale Settings selection cannot bypass it. When the pipeline routes a role run into the blocked cell, it falls back to claude-code and emits a console.warn rather than failing the whole pipeline.

What you see in the pickers

The pickers consult the same canUseHarness(harness, model, authMode) policy as the spawn entry points, so the blocked combination is caught before you click Start. The UI surfaces the block in two places:
  • Model list: when the selected harness cannot run a model, that model row is disabled (locked) and its tooltip shows the reason.
  • Harness list: when the current model is blocked for a harness, the harness option is disabled (non-clickable) and renders the decision reason as visible inline text — not only in the tooltip — so the block is readable without hover.
The inline reason names the restriction as a Claude Code subscription Terms of Service rule, and tells you how to proceed: switch Anthropic to API-key auth, or pick a non-Anthropic model for ohmypi. This behavior applies in the plan kickoff dialog, work-agent start menu, conversation panel, and Settings per-role harness selectors. Blocked clicks are inert — they do not fire onChange / onHarnessChange and do not auto-flip the model.

Auth mode is exclusive

Anthropic auth is exclusively subscription or API key, never both. If you log into the Claude Code subscription, Overdeck ignores any ANTHROPIC_API_KEY in the environment. Set one or the other, not both.

Troubleshooting

”omp not on PATH” or wrong version

Run pan doctor. The ohmypi check reports OK / missing / too-old with the resolved version. The fix message includes the install/upgrade command.

omp spawns but the agent never reaches “ready”

Check ~/.overdeck/agents/<id>/ready.json — the vendored extension writes this on session_start. If it never appears:
  1. Confirm packages/ohmypi-extension/dist/index.js exists (pan doctor will warn).
  2. Tail the tmux session: tmux -L overdeck attach -t agent-<id>. omp prints stdout to the pane; structural errors show up there.
  3. Verify the named pipe exists at ~/.overdeck/agents/<id>/rpc.in. If a stale regular file is in its place, createOhmypiFifo replaces it on next spawn.

ohmypi heartbeat is stale but the agent is working

OhmypiRuntime.getHeartbeat() walks three sources in priority order: active heartbeat (<60s old) → JSONL session mtime → tmux session created timestamp. If your dashboard shows a stale heartbeat, check ~/.overdeck/heartbeats/<id>.json — omp writes there on every tool_execution_end.

Codex app-server is unavailable or too old

Run codex --version. The app-server transport requires Codex CLI 0.144.0 or newer and the codex app-server subcommand. If the version is too old, upgrade Codex CLI and start a fresh session. To keep work moving during a rollout, set codex.transport: tui to use the legacy TUI transport temporarily.

Tradeoffs

RPC over named pipe vs tmux paste-buffer

ohmypi’s harness uses a per-agent mkfifo (~/.overdeck/agents/<id>/rpc.in) for command delivery. Claude Code uses tmux’s load-buffer + paste-buffer pattern. The fifo path:
  • skips the 300ms paste-render wait Claude Code needs;
  • gives omp its own structured RPC channel separate from the visible tmux pane;
  • keeps the agent inside tmux for crash isolation and visual attach (omp’s stdout still flows into the pane).
The downside: a reader-less fifo throws ENXIO immediately, so writeOhmypiCommand returns a typed OhmypiNotReady error and the runtime adapter recycles the agent rather than blocking on the open call.

Multi-provider via ohmypi vs CLIProxy

Both ohmypi (with native multi-provider routing) and Claude Code (via the CLIProxy auth shim) can drive non-Anthropic models. ohmypi gives you provider routing without an extra middleware process; CLIProxy gives you Claude Code’s tooling/UX with non-Anthropic providers. Pick by which UX you want — there is no correctness difference today.

When to pick which

  • Default to claude-code for Anthropic-subscription users and for roles whose instructions rely on Claude Code agent definitions.
  • Switch to ohmypi when you need a non-Anthropic provider, when you want omp’s compact-context behavior, or when you’re driving a long-running session where the named-pipe RPC is materially faster than paste-buffer delivery.
  • Mix per role in Settings if you want, e.g., an ohmypi work role feeding a Claude Code review role.

Implementation

  • src/lib/runtimes/ohmypi.tsOhmypiRuntime (the AgentRuntime adapter for omp)
  • src/lib/runtimes/ohmypi-fifo.tscreateOhmypiFifo, writeOhmypiCommandSync, OhmypiNotReady
  • src/lib/cost-parsers/ohmypi-parser.ts — omp JSONL active-branch walker
  • src/lib/harness-policy.tscanUseHarness ToS gate
  • packages/ohmypi-extension/ — vendored lifecycle extension omp loads via --extension

See also