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, acp, kimi-code, opencode, and muse. 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.Composer commands across harnesses
The dashboard reserves/pan <verb> [args] for Overdeck operator commands. The dashboard parses and executes this namespace before a message reaches the coding harness, so /pan has the same syntax, validation, canonical arguments, confirmations, and result shape under claude-code, codex, ohmypi, acp, kimi-code, and muse. Unprefixed pan ... text is still delivered as an ordinary prompt.
Harness-native slash commands are a separate lane and are not uniform. The composer menu reads the active harness’s verified capability list: for example, Claude Code exposes native commands such as /model, while a harness with no verified inventory shows no native entries. Overdeck commands appear in their own Overdeck group, so choosing a harness never changes the /pan control-plane surface.
Managed Codex sessions use an isolated CODEX_HOME. On initialization and resume, Overdeck copies the Agent Skills standard directories synced by pan sync from ~/.agents/skills into that home’s skills/ directory. Managed skills are refreshed additively, per-agent-only skill directories are preserved, and Codex still keeps its sessions and configuration inside the isolated home.
Supported harnesses
Claude Code (default)
- Shipped by Anthropic; Overdeck installs no special integration — drop in
claudeand 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-6 Astra and GPT-5.6 Sol,
Terra, and Luna default to a
272000-token pin for bothCLAUDE_CODE_MAX_CONTEXT_TOKENSandCLAUDE_CODE_AUTO_COMPACT_WINDOW— OpenAI bills prompts with more than 272K input tokens at 2x input / 1.5x output for the full request, so the default keeps sessions under that tier. Thegpt-5.6-sol[372k],gpt-5.6-terra[372k], andgpt-5.6-luna[372k]picker variants opt into a372000-token pin for long-research sessions that accept the surcharge; the[372k]suffix is Overdeck-side only and is stripped before the model id reaches the API.gpt-6-astrahas no[372k]variant — the 372K pin was measured ongpt-5.6-soland has not been re-measured for astra. 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 conservative150000auto-compact policy and Kimi K2.7 Code keeps its262144auto-compact policy without a maximum override. Kimi K3 exports both values from its model capability:262144fork3and1048576fork3[1m], matching Kimi’s Claude Code recipe. Anthropic models receive neither override, so Claude Code’s native context behavior remains in control.
Muse Code
Install Muse Code and sign in withmuse login. For API-key authentication,
use muse auth set --api-key-stdin; Muse owns its credentials. Overdeck uses
the installed muse binary and does not route these models through CLIProxy.
The integration is verified with Muse Code 1.0.2.
Enable Meta (Muse) in Settings → Providers, then choose either model in
the model picker. Both use a 1,048,576-token context window:
The Contributor tier requires contributing prompts and completions for model
training. Choose it explicitly when that data use fits your work. Standard
and Contributor remain separate model IDs throughout launch and accounting.
These catalog prices are estimates; your Meta account’s billing terms apply.
You can also enable the provider in
~/.overdeck/config.yaml:
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 (mkfifoat~/.overdeck/agents/<agentId>/rpc.in). - Vendored extension at
packages/ohmypi-extension/reports lifecycle events:session_startwrites aready.json,tool_execution_endupdates a heartbeat, and a/pan-doneslash command writes a completion marker. - Multi-provider — drives Anthropic, OpenAI, Google, OpenRouter, Minimax,
DashScope through omp’s own provider routing. (QuantumLlama, a fictional
benchmark provider with no live endpoint, is also registered for pipeline
testing — see
benchmarks/specs/quantumllama.md.)
OpenAI Codex CLI (alternative)
- First-party OpenAI agent loop for the GPT model family (GPT-6 Astra, 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-solis the default OpenAI model surfaced by this harness.gpt-6-astrais the newest and most capable OpenAI model but is opt-in — pick it explicitly.- Work agents use a persistent
codex app-serverchild 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: tuias 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-shotcodex exec. - The app-server transport requires Codex CLI
0.144.0or newer. Upgrade with your normal Codex CLI install method, then verify withcodex --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 syncprepares the global context and skill sources, then each isolated Codex home receives an additive copy of the synced skill directories during initialization. - Role-declared MCP servers, such as Playwright for the
testrole, 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 isolatedCODEX_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:
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 createandgh issue commentaccept 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 pushprefix 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 = trueenables 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.
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 nativeacp 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:
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’s built-in default is the native kimi-code harness (below); opt its
provider into ACP instead from Settings → Providers → Kimi (Moonshot) →
Default harness, which offers ACP and Kimi Code alongside the shared
harnesses. The same choice can be written directly in ~/.overdeck/config.yaml:
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.
Kimi Code CLI, native (alternative)
kimi-code drives Moonshot’s own Kimi Code CLI directly through its native
terminal UI — no Agent Client Protocol host, no JSON-RPC, no shell-out to a
subprocess wrapper. Overdeck launches kimi in a tmux session under the PTY
supervisor (the same delivery path claude-code uses), reads Kimi’s own
wire.jsonl transcript for cost and conversation-feed rendering, and lets
Kimi’s server-side context cache discipline apply exactly as it would for a
human running kimi at a terminal.
This is a different harness from acp, even though both ultimately run
the same kimi binary:
Neither replaces
claude-code pointed at Kimi’s Anthropic-compatibility
endpoint (ANTHROPIC_BASE_URL + KIMI_API_KEY, still supported as an
operator override — see When to pick which): that route
runs the Claude Code binary itself against Kimi’s models, forfeiting Kimi’s
own server-side context cache accounting that kimi-code and acp both keep.
Install Kimi Code CLI using its
getting-started guide.
The binary installs to ~/.kimi-code/bin/kimi. The installer does not put
that directory on the PATH Overdeck inherits — on Linux it appends the export
to the interactive section of ~/.bashrc, which a non-interactive login shell
skips, so neither the dashboard’s own PATH nor its bash -lc command -v kimi
fallback can see the binary. Overdeck therefore searches ~/.kimi-code/bin
directly, alongside ~/.local/bin and ~/.claude/local, and a stock install
needs no configuration. Set the path explicitly only when the binary lives
somewhere else:
kimi-code
session:
kimi-code is Kimi-only: canUseHarness('kimi-code', model, authMode)
blocks every non-Kimi model with a reason naming the restriction, the same
way the ToS gate blocks ohmypi + Anthropic + subscription (see
ToS rules below — this is a model-provider restriction, not a
Terms of Service one, but it is enforced identically at every spawn entry
point and every picker). Pick a Kimi model, or use the model’s supported
harness.
kimi-code is the built-in default for Kimi models — no config change is
needed to use it. This is a behavior change: a Kimi model that previously
resolved to claude-code (routed through Kimi’s Anthropic-compatibility
endpoint) now resolves to the native kimi-code harness by default, which
requires the installed kimi binary and its own kimi login — not
config.apiKeys.kimi.
Migration note for existing model pins: the native CLI’s own catalog only
exposes kimi-code/k3, kimi-code/k3-256k, kimi-code/kimi-for-coding, and
kimi-code/kimi-for-coding-highspeed. A role pinned to the claude-code-routed
k3 or k3[1m] id is remapped automatically to the matching native alias
(kimi-code/k3-256k and kimi-code/k3 respectively — the context-window
sizes, not the bare-string names, decide the mapping). A role pinned to
kimi-k2.7-code, kimi-k2.6, kimi-k2.5, kimi-k2, or K2.6-code-preview
has no native equivalent and fails loudly at spawn with the list of valid
native aliases, rather than silently launching the wrong model.
To opt back out to claude-code or acp, override the provider’s harness in
~/.overdeck/config.yaml:
Kimi rows in the model picker name their launch route
Kimi models appear in the conversation model picker as one row per launch route, and the row label states the harness it spawns:
Clicking a row sets model and harness together, and the spawn honors the pick
as an explicit harness choice (policy-gated and fail-loud) — the row launches
what it says, regardless of the
providers.kimi.harness default above.
The two id spaces are not interchangeable. kimi-code/* ids exist only in the
native CLI’s catalog, so canUseHarness blocks them on every harness except
kimi-code and acp; bare ids (k3, k3[1m], kimi-k2.7-code) work on
every Kimi route because they translate into the native catalog. Effort levels
follow the route: native rows offer the kimi binary’s real low / high /
max (what its in-session /effort shows), while Claude Code rows offer the
full five-level slider.
Runtime adapter is src/lib/runtimes/kimi-code.ts; the per-agent
kimi-session-id file (captured post-launch, since Kimi generates its own
session id and it cannot be preset) enables transcript resolution
(resolveKimiWirePath in src/dashboard/server/routes/jsonl-resolver.ts) and
cost parsing (src/lib/cost-parsers/kimi-parser.ts).
OpenCode with Go and Zen
Overdeck supports the OpenCode harness with OpenCode Go and OpenCode Zen. The integration was verified against OpenCode 1.18.29. Install or update the CLI withnpm install -g opencode-ai@latest, then check opencode --version.
The official release feed is anomalyco/opencode.
Run opencode auth login on the host and select OpenCode Zen or OpenCode Go.
OpenCode owns the saved credentials. Overdeck does not copy them into a workspace
or require a second API key. The OPENCODE_API_KEY environment variable is also
recognized by OpenCode. Go requires an active Go subscription; Zen uses its own
billing. See Go and Zen.
Enable the provider under Settings → Providers, then select a model in the
conversation picker. Overdeck discovers the installed CLI’s available models,
prices, and effort variants with opencode models --verbose; the discovery cache
lasts one minute. Sign in to Go before expecting Go models to appear.
The provider IDs also work in configuration:
opencode models, such as opencode/<model-id>
for Zen or opencode-go/<model-id> for Go. These namespaces remain distinct from
OpenRouter and the model manufacturer’s direct API. OpenCode model IDs only
launch through the OpenCode harness; invalid combinations fail before launch.
There is no fallback model when the requested model is unavailable.
Overdeck runs a persistent opencode acp process through its ACP host. Dashboard
messages, interruption, restart, session resume, and transcript rendering use
that transport. The terminal shows the ACP host’s output; it is not the native
OpenCode TUI. Plain transcript forks are unavailable; use a summary fork instead.
The existing ACP transport does not report session token usage or billed cost.
Catalog prices shown in the picker are model rates, not a session billing report.
OpenCode receives Overdeck’s rendered context at session start. Use
harness:opencode blocks for OpenCode-specific instructions. Native OpenCode
rules and its Agent Skills discovery remain available. Effort defaults to high
when the selected model exposes effort controls. An unsupported explicit effort
or an unavailable model fails visibly instead of selecting another value.
Installing oh-my-pi
oh-my-pi is not auto-installed. Install it once, then runpan doctor to confirm.
pan doctor also checks that packages/ohmypi-extension/dist/index.js exists in the
Overdeck workspace. If it doesn’t, 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, QUANTUMLLAMA_API_KEY, etc.) automatically from your dashboard
Settings or ~/.overdeck.env. (QUANTUMLLAMA_API_KEY belongs to QuantumLlama,
a fictional benchmark provider with no live endpoint.)
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. Aharness 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 bycanUseHarness(harness, model, authMode) in src/lib/harness-policy.ts:
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.
The same gate enforces Kimi id-space correctness: a kimi-code/*
native-catalog id is blocked on every harness except kimi-code and acp, so
a stale role pin fails loudly instead of launching a session whose first turn
the provider endpoint rejects (see
Kimi rows in the model picker name their launch route).
What you see in the pickers
The pickers consult the samecanUseHarness(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.
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 anyANTHROPIC_API_KEY in
the environment. Set one or the other, not both.
Troubleshooting
”omp not on PATH” or wrong version
Runpan 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:
- Confirm
packages/ohmypi-extension/dist/index.jsexists (pan doctorwill warn). - Tail the tmux session:
tmux -L overdeck attach -t agent-<id>. omp prints stdout to the pane; structural errors show up there. - Verify the named pipe exists at
~/.overdeck/agents/<id>/rpc.in. If a stale regular file is in its place,createOhmypiFiforeplaces 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
Runcodex --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-agentmkfifo (~/.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).
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. CLIProxy auto-installs its pinned release on Linux, macOS, and Windows for amd64 and arm64 systems. On Windows, the sidecar is installed as~/.overdeck/bin/cliproxy.exe
using the OS-bundled curl and tar tools.
When to pick which
- Default to
claude-codefor Anthropic-subscription users and for roles whose instructions rely on Claude Code agent definitions. - Switch to
ohmypiwhen 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.
- Switch to
kimi-codefor Kimi models when you want native Kimi behavior without the ACP host layer; useacpinstead when you want a portable protocol surface (or plan to reuse the same setup with a future non-Kimi ACP agent).
Implementation
src/lib/runtimes/ohmypi.ts—OhmypiRuntime(theAgentRuntimeadapter for omp)src/lib/runtimes/ohmypi-fifo.ts—createOhmypiFifo,writeOhmypiCommandSync,OhmypiNotReadysrc/lib/cost-parsers/ohmypi-parser.ts— omp JSONL active-branch walkersrc/lib/harness-policy.ts—canUseHarnessToS/model-provider gatepackages/ohmypi-extension/— vendored lifecycle extension omp loads via--extensionsrc/lib/runtimes/kimi-code.ts—KimiCodeRuntimeSync(native Kimi Code adapter)src/lib/cost-parsers/kimi-parser.ts— Kimiwire.jsonlusage/cost parser
See also
- Harness Landscape — survey of coding-agent harnesses and their extensibility mechanisms
- Template Conversations — proposal for loading curated skill bundles into a single conversation
- Skills System — how Overdeck distributes skills across harnesses