> ## Documentation Index
> Fetch the complete documentation index at: https://panopticon-cli.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Harnesses

> Choosing the coding-agent harness that drives a workspace agent

export const ThemedImage = ({light, dark, alt = ""}) => {
  const [darkMode, setDarkMode] = useState(null);
  useEffect(() => {
    const root = document.documentElement;
    const syncTheme = () => setDarkMode(root.classList.contains("dark"));
    const observer = new MutationObserver(syncTheme);
    syncTheme();
    observer.observe(root, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => observer.disconnect();
  }, []);
  if (darkMode === null) return null;
  return <img src={darkMode ? dark ?? light : light} alt={alt} loading="lazy" />;
};

# Harnesses

A **harness** is the underlying CLI that drives a workspace agent — the binary
that runs in a terminal-backend pane (Herdr by default; see
[Terminal backend](/configuration/terminal-backend)). The **model** is what the binary calls. They are picked
independently per spawn.

<Info>
  **Supported today:** `claude-code` (default), `ohmypi`, `codex`, `acp`, `kimi-code`, `opencode`, `muse`, and `prime-agent`. 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](/reference/harness-landscape).
</Info>

| Harness | Binary | Default for | Notes |
| - | - | - | - |
| `claude-code` | [Anthropic Claude Code](https://github.com/anthropics/claude-code) | All workflows | Default if you don't pick. Required for Anthropic-subscription users. |
| `ohmypi` | [oh-my-pi](https://github.com/oh-my-pi/pi-coding-agent) (`omp`) | Multi-provider work, large workspaces | Adds oh-my-pi RPC over a named pipe; reads `~/.claude/skills` for skill parity. |
| `codex` | [OpenAI Codex CLI](https://github.com/openai/codex) (`codex`) | OpenAI-model work | Uses persistent `codex app-server` sessions by default; requires Codex CLI `0.144.0` or newer. |
| `acp` | [Kimi Code CLI](https://www.kimi.com/code/docs/en/kimi-code-cli/guides/getting-started.html) (`kimi`) | Opt-in Kimi work | Uses the open Agent Client Protocol over a persistent authenticated host; Kimi is the first wired ACP agent. |
| `kimi-code` | [Kimi Code CLI](https://www.kimi.com/code/docs/en/kimi-code-cli/guides/getting-started.html) (`kimi`) | Kimi models (built-in default) | Drives Kimi's own native terminal UI directly — no ACP host, no Anthropic-compatibility endpoint. Kimi models only. Set `providerHarnesses.kimi` to `acp` or `claude-code` to opt back out. |
| `opencode` | [OpenCode](https://opencode.ai) (`opencode`) | OpenCode Go and Zen | Persistent ACP sessions, native credentials, and model discovery; verified with 1.18.31. |
| `muse` | Muse Code (`muse`) | Meta Muse Spark models | Persistent native terminal sessions with separate Standard and Contributor model choices. |
| `prime-agent` | [Prime Agent](https://github.com/PrimeIntellect-ai/prime-agent) (`prime-agent`) | Opt-in multi-provider work | RPC mode behind an Overdeck host, with one private Prime daemon per agent; supports 0.8.x. |

## 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`, `muse`, and `prime-agent`. 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.

## Steering a running turn

Pressing **Enter** in the dashboard composer queues your message while the agent is busy: Claude Code feeds it to the model at the next tool boundary, or after the turn ends. To change course now, **steer**. Press **Ctrl+Enter** (**Cmd+Enter** on macOS), or choose **Steer** in the composer delivery selector, which then applies to Enter as well. From a shell, `pan tell --steer <id> "<message>"` does the same.

| Harness | Delivery modes | What Steer does |
| - | - | - |
| Claude Code | Auto, Steer | Interrupts the running turn and sends the message at once, like the TUI's Ctrl+Enter. Under the hood Overdeck types the message and presses Claude Code's send-now chord, Ctrl+X Ctrl+S. An idle agent just receives the message. |
| Pi (`ohmypi`) | Auto, Steer, Follow-up | Steers over the Pi control channel. Conversations only. |
| Codex | Auto | Not yet; see [PAN-4303](https://github.com/eltmon/overdeck/issues/4303). |
| ACP, OpenCode, Kimi Code, Muse Code, Prime Agent | Auto | None. |

A steer never falls back silently to a queued message. A harness without steer answers `steer-unsupported` and delivers nothing. A Claude Code agent launched before steer support has a PTY supervisor that presses Enter instead, and the delivery reports that it went out as a normal submit.

## Supported harnesses

### Claude Code (default)

* Shipped by Anthropic; Overdeck installs no special integration — drop in
  `claude` and run.
* **Local models through Ollama.** Ollama 0.14 and newer serves the Anthropic
  Messages API, so Claude Code drives a GPU model on your own machine the same
  way it drives a cloud one. Model ids are `ollama:<tag>`, the run costs nothing,
  and model traffic stays on the host. No local model has completed a work-agent task
  yet, so treat it as experimental. See
  [Local models (Ollama)](/configuration/local-models).
* Works with both subscription auth (Claude Code OAuth) and API-key auth.
* All role runs (`plan`, `work`, `review`, `test`, `ship`) default here.
* The model picker includes Claude Opus 5.5 (`claude-opus-5-5`): 1M context,
  128K maximum output, always-on adaptive thinking, and low through max effort.
  API pricing is \$4/M input and \$20/M output; subscription availability depends
  on the Anthropic account.
* The model picker includes Claude Sonnet 5.5 (`claude-sonnet-5-5`): 1M
  context, 128K maximum output, adaptive thinking, and low through max
  effort. API pricing is \$2/M input, \$10/M output and \$0.10/M cache
  reads (cut from \$0.20/M on 2026-10-07). It requires Claude
  Code 2.1.284 or newer; older versions treat it as an unrecognized model
  with a 200K window. It is the default for the Sonnet tier
  (`workhorses.mid`, the default conversation model, status review, fork
  summaries and provider fallback). Overdeck omits `temperature` for models
  that reject sampling parameters (Sonnet 5 and newer, Opus 4.7 and newer,
  Haiku 5.5, Fable).
* The model picker includes Claude Haiku 5.5 (`claude-haiku-5-5`): 1M
  context, 128K maximum output, adaptive thinking on by default with
  medium as the default effort, and low through max effort. Manual extended
  thinking (`budget_tokens`) and non-default sampling parameters return 400.
  API pricing depends on prompt size: up to 100K tokens it is \$0.10/M
  input, \$0.50/M output and \$0.01/M cache reads; above 100K tokens every
  rate is 5×. Its tokenizer counts about 30% more tokens than Haiku 4.5 for
  the same text. It requires Claude Code 2.1.293 or newer. Haiku 4.5 remains
  the default for the cheap slot and background calls.
* Overdeck passes every Claude model to `claude --model` as its full API ID,
  never the short `opus`, `sonnet` or `haiku` alias. Claude Code moves those
  aliases to each new release: 2.1.293 points `haiku` at Haiku 5.5, and
  `opus` resolves to Opus 5.5, so an alias launches a different model than
  the one configured.
* The `workhorses.expensive` slot and the `flywheel` role default to
  `claude-opus-5-5` (from v0.67.0; previously `claude-opus-4-8`).
* To set the workhorse slots, roles, tiers and background models to one
  provider's eval-backed lineup in one step, use a
  [model preset](/configuration/model-presets).
* Proxied models use a dedicated Claude Code context policy rather than copying
  every value from the generic model registry. GPT-6 Astra, Sol, and Luna and
  GPT-5.6 Sol, Terra, and Luna default to a `272000`-token pin for both
  `CLAUDE_CODE_MAX_CONTEXT_TOKENS` and
  `CLAUDE_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. The `gpt-5.6-sol[372k]`, `gpt-5.6-terra[372k]`,
  and `gpt-5.6-luna[372k]` picker variants opt into a `372000`-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.
  The GPT-6 models (`gpt-6-astra`, `gpt-6-sol`, `gpt-6-luna`, `gpt-6.1-sol`) have no
  `[372k]` variant — the 372K pin was measured on `gpt-5.6-sol` and has not been
  re-measured for GPT-6.
  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.

#### Claude Code version requirements

Some models need a newer Claude Code CLI than an older install recognizes.
Overdeck tracks each model's minimum on its capability row and checks it
before every `claude-code` launch:

| Model | Minimum Claude Code |
| - | - |
| Claude Fable 5.1 (`claude-fable-5-1`) | 2.1.255 |
| Claude Sonnet 5.5 (`claude-sonnet-5-5`) | 2.1.284 |
| Claude Haiku 5.5 (`claude-haiku-5-5`) | 2.1.293 |

A launch whose Claude Code is too old is refused before a terminal session is
created. The error names the model, the installed and required versions, the
launch binary's path, and the exact upgrade command — for example:

```
Claude Sonnet 5.5 (claude-sonnet-5-5) needs Claude Code 2.1.284 or newer, but
Overdeck would launch Claude Code 2.1.280 at /usr/local/bin/claude. Upgrade it
with `npm install -g --prefix /usr/local @anthropic-ai/claude-code@latest`
(or the Upgrade Claude Code button in the dashboard), then launch again.
Running sessions keep their current Claude Code. No terminal session was
created.
```

The dashboard shows the same check as a banner in the system notices row
while any configured model's minimum is unmet. A user-writable npm, native
(`claude update`), or reachable-`brew` install gets an **Upgrade Claude
Code** button that runs the upgrade in a terminal session and re-checks when
it finishes; a root-owned npm prefix, an unrecognized install, or Windows
shows a copyable command instead, since Overdeck never runs `sudo` or a
root-owned install itself. Either way, running agents and conversations keep
their current Claude Code — only new launches use the upgraded one.

`pan doctor` reports the installed Claude Code version, its install method
and path, one row per configured model with a documented minimum, and a
warning row for every other `claude` binary on `PATH` ("shadow" binaries) that
could confuse a shell running `claude` directly.

### Muse Code

Install Muse Code and sign in with `muse 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:

| Model ID | Input / million tokens | Cached input / million tokens | Output / million tokens |
| - | - | - | - |
| `muse-spark-1.3` | \$1.25 | \$0.15 | \$4.25 |
| `muse-spark-1.3-contributor` | \$0.10 | \$0.002 | \$0.20 |

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`:

```yaml theme={null}
models:
  providers:
    meta:
      enabled: true
      harness: muse
```

Choose a Muse model explicitly for a conversation or role; enabling the
provider does not change your configured default model. Muse runs with high
reasoning effort by default and keeps its native tool-approval behavior.

Overdeck supplies its context layers and role instructions through a managed
developer-context file. Muse sessions are isolated by agent identity, and
resume uses the native session UUID. The dashboard displays committed user
and assistant messages and reports token costs. Use the Terminal tab for
Muse's detailed tool activity and approval prompts. Native reasoning and
internal configuration records are excluded from the chat feed.

### 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. (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/Sol/Luna,
  GPT-6.1 Sol, 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. `gpt-6-astra`
  is the newest and most capable OpenAI model but is opt-in — pick it explicitly.
  `gpt-6-sol` and `gpt-6-luna` (September 2026) are the GPT-6 successors to
  GPT-5.6 Sol and Luna at half their API price; they are opt-in too. Under
  ChatGPT sign-in, `gpt-6-sol` and `gpt-6-luna` need Codex CLI `0.156.1` or
  newer — OpenAI answers HTTP 400 below that version
  ([openai/codex#47784](https://github.com/openai/codex/issues/47784)).
  `gpt-6.1-sol` (September 29, 2026) is the GPT-6.1 successor to GPT-6 Sol at
  the same \$2/\$10 price with \$0.10 cached input; it is opt-in. Under ChatGPT
  sign-in it needs Codex CLI `0.159.0` or newer.
  `gpt-6-astra` and API-key auth have no floor. Overdeck refuses such a
  launch before it starts (`pan start`, the dashboard, conversations, and
  every other spawn path), names the required version, and never
  substitutes another model. Upgrade with `npm install -g @openai/codex`;
  `pan install` does not manage the Codex CLI. `pan doctor` shows a
  `Codex model floor` row per model. On the claude-code harness through
  CLIProxy, CLIProxy `7.3.16` (the version `pan install` pins) was verified
  on 2026-09-29 to serve all three models under ChatGPT sign-in.
* 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`.
* Conversations (not work or review agents) run their app-server on a private
  native endpoint, a Unix socket at
  `~/.overdeck/agents/<id>/codex-native/app.sock` (directory `0700`, socket
  `0600`), and Overdeck connects to it as a WebSocket client instead of stdio.
  That lets **Terminal** attach the native Codex CLI to the same thread with
  `codex resume --remote`, while the dashboard keeps its structured connection;
  see [Native Codex CLI in Terminal](/features/conversations#native-codex-cli-in-terminal).
  The native CLI needs Codex CLI `0.153.4` or newer. With an older CLI the
  conversation keeps working over stdio and Terminal explains the upgrade.
  Conversations started before this release show **Restart required for the
  native CLI** until they are stopped and resumed. Protocol evidence:
  `docs/CODEX-APP-SERVER-PROTOCOL.md`.
* 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` prepares 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 `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:

```starlark theme={null}
prefix_rule(pattern=["gh", "issue", "view"], decision="allow")
```

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:

```bash theme={null}
codex execpolicy check --pretty \
  --rules ~/.codex/rules/default.rules \
  -- gh issue view 1896
```

See the [Codex rules documentation](https://learn.chatgpt.com/docs/agent-configuration/rules)
for rule precedence and the full execpolicy syntax.

### Agent Client Protocol / Kimi Code CLI (alternative)

[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) 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](https://www.kimi.com/code/docs/en/kimi-code-cli/guides/getting-started.html),
then complete the one-time interactive login before starting an ACP session:

```text theme={null}
kimi
/login
```

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'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`:

```yaml theme={null}
providers:
  kimi:
    harness: acp

acp:
  permissionMode: auto
  kimi:
    # Optional — Overdeck already searches PATH and `~/.kimi-code/bin`.
    binaryPath: /opt/kimi/bin/kimi
```

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 transcript records agent reasoning
(`agent_thought_chunk` updates) under a separate `thought` role, and the
conversation feed renders it as thinking rows, as it does for Claude Code
thinking blocks. The runtime adapter is
`src/lib/runtimes/acp.ts`; Kimi-specific launch and authentication behavior is
in `src/lib/acp/kimi.ts`. When the agent rejects a prompt (for example an
OpenCode provider error such as `Rate limit exceeded`), the host records a
`prompt_failed` transcript entry and the conversation feed shows it as a red
**Prompt failed** row carrying the provider's message.

### 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:

| | `acp` | `kimi-code` |
| - | - | - |
| Drives | `kimi acp` (Agent Client Protocol JSON-RPC host) | native `kimi` terminal UI |
| Delivery | Persistent authenticated host process | PTY supervisor + tmux paste fallback |
| Transcript | Normalized `acp-session.jsonl` | Kimi's own `wire.jsonl` |
| Why pick it | Portable across any ACP-capable agent | Reaches Kimi-specific behavior the ACP lowest-common-denominator surface can't |

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](#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](https://www.kimi.com/code/docs/en/kimi-code-cli/guides/getting-started.html).
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:

```yaml theme={null}
kimiCode:
  binaryPath: /opt/kimi-code/bin/kimi
```

Then complete the one-time interactive login before starting a `kimi-code`
session:

```text theme={null}
kimi
/login
```

`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](#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`:

```yaml theme={null}
providers:
  kimi:
    harness: acp   # or claude-code
```

### 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:

| Row label | Model id | Launch route |
| - | - | - |
| `Kimi K3 (256K) — Claude Code` | `k3` | Claude Code against Kimi's Anthropic-compatibility endpoint |
| `Kimi K3 (1M) — Kimi Code CLI` | `kimi-code/k3` | the native `kimi` binary directly |
| `Kimi K3 (1M) — ACP (Kimi Code)` | `kimi-code/k3` | the native `kimi` binary over ACP |

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.31**. Install or update the
CLI with `npm install -g opencode-ai@latest`, then check `opencode --version`.
The official release feed is [anomalyco/opencode](https://github.com/anomalyco/opencode/releases).

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](https://opencode.ai/docs/go/) and [Zen](https://opencode.ai/docs/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:

```yaml theme={null}
models:
  providers:
    opencode:
      enabled: true
      harness: opencode
    opencode-go:
      enabled: true
      harness: opencode
```

Choose an exact model ID from `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 conversation's **Terminal** view attaches the native OpenCode
CLI (`opencode attach http://127.0.0.1:<port> --session <id> --dir <cwd>`) to
the same server and session, with the ACP host log under **Runtime log**; see
[Conversations](/features/conversations#native-opencode-cli-in-terminal).
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.

#### Permission deadlock protection

OpenCode can lose a permission request from a Task subagent before ACP sends it
to Overdeck. Overdeck prevents that request from blocking the parent turn by
setting this launch-time policy:

```json theme={null}
{"external_directory":"allow","doom_loop":"allow","read":{"*.env":"allow","*.env.*":"allow"}}
```

These are the only permissions that OpenCode defaults to `ask`. The policy does
not change `question`, `plan_enter`, `plan_exit`, or other permission keys. The
`OPENCODE_PERMISSION` environment value takes precedence over matching rules in
the user's `opencode.jsonc`, so an explicit deny for these three keys is also
overridden. This narrow override prevents an unobservable subagent ask from
deadlocking the complete conversation.

Each OpenCode ACP host also reserves a loopback HTTP port and records it in
`~/.overdeck/agents/<conversation>/opencode-port`. While a prompt is running,
the host checks once per minute. After 180 seconds without an ACP runtime event,
it lists pending permissions and replies `always` to each one. A recovered ask
is recorded in `acp-session.jsonl` with `"source":"watchdog"`.

If an older host is already stuck, inspect and answer its pending request:

```bash theme={null}
CONVERSATION=conv-YYYYMMDD-NNNN
OPENCODE_PORT=$(cat "$HOME/.overdeck/agents/$CONVERSATION/opencode-port")
curl -sS "http://127.0.0.1:$OPENCODE_PORT/permission"
curl -sS -X POST \
  "http://127.0.0.1:$OPENCODE_PORT/permission/<permission-id>/reply" \
  -H 'content-type: application/json' \
  -d '{"reply":"always"}'
```

For hosts created before the port file existed, use `ss -ltnp` to find the
loopback port owned by that conversation's `opencode acp` process.

The same port file and `acp-session-id` drive the native CLI in Terminal. A
conversation without `opencode-port` shows a restart-required message there;
stop and resume it to record the port.

#### Stalled turn detection

OpenCode retries a provider error such as a `429 Rate limit exceeded`
internally, so the ACP prompt call does not return and nothing reaches the
transcript. While a prompt is running and no ACP runtime event has arrived for
30 seconds, the host polls `GET /session/status` on the same loopback port
every 30 seconds. When a session reports `{"type":"retry"}`, the host writes one
`prompt_stalled` entry to `acp-session.jsonl` with OpenCode's retry message
(for example `opencode is retrying the turn (attempt 4): Rate limit exceeded.`)
and prints it in the pane. The conversation feed shows it as a red **Prompt
stalled** row. The turn keeps running: the host does not cancel it, and a later
completion still records `turn_completed`.

Every ACP provider, Kimi included, also has an inactivity check. A turn with no
runtime event for 10 minutes gets the same `prompt_stalled` entry. Set
`OVERDECK_ACP_TURN_STALL_MS` in the `acp-host` process environment (it inherits
the terminal backend's environment) to change the timeout, in milliseconds. `0` turns the inactivity check off, but
the OpenCode status check still runs. Each prompt gets at most one
`prompt_stalled` entry.

### Prime Agent

[Prime Agent](https://github.com/PrimeIntellect-ai/prime-agent) is Prime
Intellect's coding and research agent (`prime-agent`). Overdeck runs it in RPC
mode behind its own host process, so dashboard messages, `pan tell`, stop,
resume, transcripts, and cost work the same way as for other harnesses.

#### Install and version

Install the supported release line and check the version:

```bash theme={null}
npm install -g prime-agent@0.8
prime-agent --version
```

Overdeck supports Prime Agent **0.8.0 – \<0.9.0** (daemon protocol 7). A launch
with a version outside that range fails before any pane opens, and the error
names the found version and the supported range. `pan doctor` reports the
installed version, and it warns (it does not fail) when Prime Agent is not
installed.

#### Choosing Prime Agent

Set `harness: prime-agent` for a role, or pick **Prime Agent** as a provider's
harness under **Settings → Providers**. The settings offer it for the providers
it can reach:

| Overdeck provider | Prime provider | API-key env var | `auth.json` key |
| - | - | - | - |
| `anthropic` | `anthropic` | `ANTHROPIC_API_KEY` | `anthropic` |
| `openai` | `openai` | `OPENAI_API_KEY` | `openai` |
| `openai` (subscription) | `openai-codex` | — | `openai-codex` |
| `google` | `google` | `GEMINI_API_KEY` | `google` |
| `kimi` | `kimi-coding` | `KIMI_API_KEY` | `kimi-coding` |
| `minimax` | `minimax` | `MINIMAX_API_KEY` | `minimax` |
| `openrouter` | `openrouter` | `OPENROUTER_API_KEY` | `openrouter` |
| `zai` | `zai` | `ZAI_API_KEY` | `zai` |
| `mimo` | `xiaomi` | `XIAOMI_API_KEY` | `xiaomi` |
| `xai` | `xai` | `XAI_API_KEY` | `xai` |
| `groq` | `groq` | `GROQ_API_KEY` | `groq` |
| `cerebras` | `cerebras` | `CEREBRAS_API_KEY` | `cerebras` |
| `mistral` | `mistral` | `MISTRAL_API_KEY` | `mistral` |

Anthropic models under Anthropic **subscription** auth are blocked for Prime
Agent by the Claude Code subscription terms (see [ToS rules](#tos-rules)); use
Anthropic API-key auth instead. The model ID passes through unchanged. Prime
Agent rejects an unknown model at startup, and the launch error shows its message. Any other provider fails with a
mapping error; Overdeck never picks a fallback model.

#### Credentials

A launch is allowed when one of these holds, checked in order:

1. Prime Agent's `~/.prime/agent/auth.json` has the Prime provider key (run
   `prime-agent`, then `/login`). Overdeck reads only the key names, never the
   values.
2. Prime's env var for that provider (see the table) is set in the dashboard's
   environment.
3. The provider's API key is set in Overdeck **Settings**.

For sources 2 and 3, Overdeck passes the key in the agent pane's launch
environment. It never writes a credential into a launcher script, a state file,
or a log. When no source has a key, the launch fails and the error names the
`auth.json` key, the env var, and the `/login` path. OpenAI subscription use
needs the `openai-codex` sign-in in `auth.json`.

#### One private daemon per agent

Prime Agent's RPC mode starts a background supervisor that outlives its client.
Overdeck gives every agent and conversation its own supervisor by passing
`--daemon-socket $OVERDECK_HOME/sockets/pd-<hash>.sock`. When the agent stops,
Overdeck ends that supervisor's process group: `SIGTERM`, then `SIGKILL` if it is
still listed after 5 seconds. Your own Prime Agent daemon on its default socket
is never touched.

The socket path must fit the 100-byte unix socket limit. With a very long
`OVERDECK_HOME`, the launch fails with an error that names the path and its
length; set a shorter `OVERDECK_HOME`. `pan doctor` warns about any
Overdeck-owned Prime supervisor whose agent or conversation is gone, and shows
the `kill -TERM -- -<pid>` command that removes it.

#### Disabled Prime automation

Cloister owns lifecycle and messaging, so Overdeck launches Prime Agent with
`--no-extensions` and never passes `--goal`, `--autonomous`, `--continue`,
`--no-session`, or `--offline`. The host refuses Prime's schedules, heartbeats,
cross-agent messaging, `observe`, `refine`, and root-session changes
(`new_session`, `switch_session`, `fork`, `clone`). Extension dialogs that no
dashboard UI can answer are cancelled automatically. Every session also starts
with a managed policy that keeps RLM children inside the root session and away
from `pan` lifecycle commands.

#### Security boundary

Prime Agent runs model-generated Python and shell commands as your host user.
Its workers and IPython kernels are **not a sandbox**. A managed run starts in
the Overdeck workspace (or its container), but treat the agent as having the
same file and network access as your user account.

#### Messages, stop, and resume

A message goes to the host, which sends `prompt` when the session is idle and
`steer` while it is working. Stop sends `interrupt`, closes the pane, and reaps
the daemon. Resume reopens the recorded session file and checks that its session
ID matches the one recorded at launch. A mismatch or a missing session file
fails the resume; Overdeck never replaces it with a fresh session silently.

#### Transcript, cost, and context

The conversation feed renders Prime's own session JSONL under
`<agentDir>/prime-sessions/`: messages, thinking, tool calls and results,
compaction, and failed or aborted turns. Durable cost comes from the same file;
usage from RLM children is folded into the parent message once. Live token
counts come from Prime's `get_session_stats`.

Overdeck renders its context layers into `<agentDir>/prime-agent-context.md` and
passes them as `--append-system-prompt` values. Use `harness:prime-agent`
blocks for Prime-only instructions. Workspace `CLAUDE.md` and `AGENTS.md`
discovery stays on. Overdeck writes nothing under `~/.prime/agent`.

#### Limitations

* Prime Agent's ACP mode is not used; it cannot resume a session.
* RLM children are not Overdeck agents; their usage is attributed to the root.
* User extensions are disabled (`--no-extensions`).
* A plain transcript fork is unavailable; use a summary fork.
* The live cost display shows a session total only, with no per-token-type split.
* macOS and Linux only; Prime Agent does not support Windows natively.

#### Uninstall

Stop your Prime Agent agents and conversations, run
`npm uninstall -g prime-agent`, then run `pan doctor` and confirm it lists no
orphaned Prime Agent daemons.

## Installing oh-my-pi

oh-my-pi is **not** auto-installed. Install it once, then run `pan doctor` to confirm.

```bash theme={null}
npm install -g @oh-my-pi/pi-coding-agent

pan doctor                 # confirms `omp` is on PATH and reports the version
pan doctor --strict        # exits non-zero if omp is missing (good for CI)
```

`pan doctor` also checks that `packages/ohmypi-extension/dist/index.js` exists in the
Overdeck workspace. If it doesn't, run:

```bash theme={null}
cd packages/ohmypi-extension && npm run build
```

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`, `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:

| Surface | How |
| - | - |
| Plan kickoff (start-planning) | Harness/model picker in the kickoff dialog. |
| Work agent start (CLI) | `pan start <ISSUE> --harness ohmypi --model <id>`. Default is `claude-code`. |
| Work agent start (Dashboard) | "Start" button menu lets you pick harness + model before launch. |
| Conversation panel | Harness/model selector at the top of the panel. |

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
`review.security` inherit from the parent role unless configured more
specifically.

<ThemedImage light="/images/dashboard/settings-light.png" dark="/images/dashboard/settings-dark.png" alt="Overdeck Settings page showing per-role model routing, tracker API keys, and project configuration" />

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.

## Use Overdeck workers instead of harness plugins

To hand a task to another agent, run `pan worker run` (skill `/pan-worker`)
rather than a harness plugin such as the Codex plugin. A bundled rule tells
agents the same. See [Workers](/reference/workers) for the commands.

| | Overdeck worker (`pan worker run`) | Harness plugin (for example the Codex plugin) |
| - | - | - |
| Visibility | In the Agents Directory, under its parent and its issue | Codex-plugin jobs appear in the Agents Directory as read-only external agents; other plugins only if something runs `pan worker register` |
| Issue link | Always linked to an issue | Only when the job ran in a `workspaces/feature-<issue>` directory |
| Transcript | On the agent transcript route, like any agent | Codex-plugin jobs: the Codex rollout, read-only on the agent transcript route |
| Cost | Attributed to the issue | Not attributed |
| Control | `pan tell`, `pan kill`, restart | None from Overdeck |
| Harness and model | Any harness through role routing (`roles.worker`), or `--harness` / `--model` | The plugin's own |
| Result | The report comes back to the caller on stdout | The plugin returns its result as a tool result |
| Sandbox | None. `--read-only` adds a PATH shim against accidental git writes to the issue's repository; it restricts no file or network writes | The plugin's file-system and network sandbox |
| Setup | Needs the issue's workspace (`pan start` first) | None |

Codex-plugin jobs are registered automatically the first time the dashboard
sees them, so they are visible, but they stay read-only: Overdeck cannot tell,
stop or restart them, and their cost is not attributed. See
[Workers — Externally spawned agents](/reference/workers#externally-spawned-agents).

## ToS rules

There are exactly **two blocked combinations**, gated by
`canUseHarness(harness, model, authMode)` in `src/lib/harness-policy.ts`:

<Warning>
  **Blocked:** `ohmypi` + Anthropic model + Anthropic auth = `subscription`

  **Blocked:** `prime-agent` + Anthropic model + Anthropic auth = `subscription`
</Warning>

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:

| Harness | Model provider | Anthropic auth mode | Allowed? |
| - | - | - | - |
| claude-code | any | any | ✅ |
| ohmypi | non-Anthropic (OpenAI/Google/OpenRouter/Minimax/DashScope/...) | any | ✅ |
| ohmypi | Anthropic | API key | ✅ |
| ohmypi | Anthropic | subscription | 🚫 |
| ohmypi | Anthropic | unset (no Anthropic auth) | ✅ |
| prime-agent | non-Anthropic (see the Prime provider table) | any | ✅ |
| prime-agent | Anthropic | API key | ✅ |
| prime-agent | Anthropic | subscription | 🚫 |

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 gate is exhaustive over harnesses. Every runtime needs an explicit rule in
`canUseHarness`, and the decision map served to the pickers is typed over every
runtime name, so adding a harness without a policy entry is a type error. A
harness the gate does not recognise is denied, never allowed by default, and a
raw legacy `pi` value gets the `ohmypi` rules.

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](#kimi-rows-in-the-model-picker-name-their-launch-route)).

### 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.

Once a model's decisions have loaded, a harness missing from them is disabled
with a "No harness-policy decision" reason. Before the decisions load, the
options stay selectable and the server gate decides at spawn.

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. Watch the agent's pane: open it in the dashboard, or run the `Attach:`
   command `pan start <id>` prints (Herdr or tmux, whichever backend launched
   it). 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.

The native Codex CLI in a conversation's Terminal needs `0.153.4` or newer.
Below that, the conversation's host falls back to stdio and logs
`[terminal] native Codex terminal unavailable: cli-unsupported` in Runtime log.
Upgrade, then stop and resume the conversation.

### "needs Claude Code X or newer"

A `claude-code` launch was refused because the configured model's minimum
Claude Code version is newer than the launch binary. See
[Claude Code version requirements](#claude-code-version-requirements) — run
the upgrade command the error names, or click **Upgrade Claude Code** in the
dashboard banner, then launch again.

## 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.

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-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.
* **Switch to `kimi-code`** for Kimi models when you want native Kimi behavior
  without the ACP host layer; use `acp` instead 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` (the `AgentRuntime` adapter for omp)
* `src/lib/runtimes/ohmypi-fifo.ts` — `createOhmypiFifo`, `writeOhmypiCommandSync`, `OhmypiNotReady`
* `src/lib/cost-parsers/ohmypi-parser.ts` — omp JSONL active-branch walker
* `src/lib/harness-policy.ts` — `canUseHarness` ToS/model-provider gate
* `packages/ohmypi-extension/` — vendored lifecycle extension omp loads via `--extension`
* `src/lib/runtimes/kimi-code.ts` — `KimiCodeRuntimeSync` (native Kimi Code adapter)
* `src/lib/cost-parsers/kimi-parser.ts` — Kimi `wire.jsonl` usage/cost parser
* `src/lib/prime-agent/` — Prime Agent host (`host.ts`), RPC client and framing, managed policy, provider map, daemon reaper, and version pin; see [docs/PRIME-AGENT-HARNESS.md](https://github.com/eltmon/overdeck/blob/main/docs/PRIME-AGENT-HARNESS.md)
* `src/lib/runtimes/prime-agent.ts` — `PrimeAgentRuntimeSync` (Cloister adapter)

## Storage paths

Each harness has one module that knows where it keeps transcripts and
sessions: `src/lib/runtimes/storage/<harness>.ts`. Everything else asks that
module for a path instead of building one.

| Module | What it owns |
| - | - |
| `storage/claude-code.ts` | `~/.claude/projects/<encoded-cwd>/<session-id>.jsonl` (`claudeProjectsRoot`, `claudeProjectDir`, `sessionFilePath`) |
| `storage/codex.ts` | `$CODEX_HOME/sessions/**/rollout-*.jsonl`, the per-conversation `CODEX_HOME`, and each agent's `<agentDir>/codex-home/sessions` (`codexHome`, `codexSessionsRoot`, `codexAgentHome`, `codexAgentSessionsDir`, `findRolloutPath`) |
| `storage/kimi-code.ts` | `~/.kimi-code/sessions/<work-dir-key>/<session-id>/agents/main/wire.jsonl` (`kimiHomeDefault`, `kimiSessionsRoot`, `kimiWirePath`) |
| `storage/pi.ts` | `<agentDir>/sessions/**.jsonl` and the user's own `~/.pi/agent` (`piSessionsRoot`, `findPiTranscriptPath`) |
| `storage/acp.ts` | `<agentDir>/acp-session.jsonl`, the transcript for ACP agents including OpenCode (`ACP_TRANSCRIPT_FILE`, `acpTranscriptPath`) |
| `storage/muse.ts` | `<agentDir>/muse-data/muse/sessions/…/session.jsonl` (`museSessionsRoot`, `resolveMuseSessionPath`) |
| `storage/prime-agent.ts` | `<agentDir>/prime-sessions/*.jsonl`, the `prime-agent-session-file` pointer, the per-agent daemon socket `$OVERDECK_HOME/sockets/pd-<hash>.sock`, and the path of Prime's own `~/.prime/agent/auth.json` (`primeAgentSessionDir`, `readPrimeAgentSessionFile`, `primeAgentDaemonSocketPath`) |

These modules import only `node:*` and `src/lib/paths.ts`, so any layer can
use them without an import cycle. The transcript resolver
(`src/lib/agents/transcript-resolver.ts`) still prefers the absolute path
recorded in `sessions.json`; it uses these modules only for entries recorded
before PAN-3959.

`npm run lint:harness-storage` (part of `npm run lint`) fails when a storage
path literal appears in `src/` outside `src/lib/runtimes/storage/`. A line that
needs one for another reason, such as a permission rule, goes in the allowlist
at the top of `scripts/lint-harness-storage.sh` as `file|anchor # reason`. The
anchor is a fixed piece of the allowed line's text, so edits elsewhere in the
file don't break the row.

## See also

* [Harness Landscape](/reference/harness-landscape) — survey of coding-agent
  harnesses and their extensibility mechanisms
* [Template Conversations](/reference/template-conversations) — proposal for
  loading curated skill bundles into a single conversation
* [Skills System](/features/skills) — how Overdeck distributes skills across
  harnesses

## Context and reasoning effort

Model pickers show the configured session context beside each model. This budget differs from the provider's maximum API context and from the remaining space shown in a running session. Runtime overhead and response reservations reduce usable space.

Astra and GPT 5.6 Sol, Terra, and Luna default to **272K**. The explicit GPT 5.6 **372K** variants opt into a larger budget. Managed Codex sessions pass this budget and default to **High** reasoning effort. A dashboard effort change on Codex app-server or Kimi ACP applies after the runtime accepts it, starting with subsequent turns. Terminal-only routes use their launch setting and native terminal controls.

Fable 5.1 supports **1M** context and requires **Claude Code 2.1.255 or newer**. Model availability and extended-context access still depend on your provider and subscription. Kimi K3 offers separate **256K** and **1M** choices; K2.7 Code uses **256K** and does not offer adjustable reasoning effort.

Subscription usage allowances are not API token prices. A larger window can consume more of your allowance, but API long-input multipliers should not be read as subscription-credit multipliers.

### How each harness receives effort

| Harness | Mechanism | `low` | `medium` | `high` | `xhigh` | `max` |
| - | - | - | - | - | - | - |
| Claude Code | `claude --effort <level>` at launch; `/effort` live | low | medium | high | xhigh | max (clamped to the model, e.g. Sonnet 4.6 `xhigh`→`high`) |
| Codex (TUI) | `model_reasoning_effort` in the agent's `CODEX_HOME/config.toml` | low | medium | high | xhigh | max on models that advertise it |
| Codex (app-server) | host `--effort` at launch, per-turn `effort`, live `set-effort` | same as Codex TUI | | | | |
| OpenCode | ACP `setConfigOption("effort", …)`; model variants pass through | low | medium | high | xhigh | max (only levels/variants the model exposes) |
| Kimi K3 (ACP) | ACP `thinking` option | low | high | high | max | max |
| Kimi K3 (native) | `KIMI_MODEL_THINKING_EFFORT` env per process | low | high | high | max | max |
| Pi (`omp`) | `--thinking <level>`; live `set_thinking_level` | low | medium | high | xhigh | xhigh |
| Muse Code | `--reasoning-effort <level>` | low | medium | high | xhigh | xhigh |
| Prime Agent | `--thinking <level>` (1:1) | low | medium | high | xhigh | max |

Overdeck resolves and clamps effort before launch (see [Reasoning effort](/configuration/effort)), and a launch path that reaches a harness without a resolved effort fails with a `requires …Effort` error instead of silently falling back to that harness's own default.

The Pi and Muse CLIs parse `max` (`omp` 17.4.1, `pi` 0.85.0, `muse` 1.4.2), but Overdeck sends at most `xhigh` because their harness rows stop there — relaxing that is a separate decision, not a bug.

**GPT through Claude Code (CLIProxy):** Claude Code sends the level as `output_config.effort` with adaptive thinking; CLIProxy `v7.3.16` maps it to the Codex request's `reasoning.effort` and clamps it to the model, so `--effort` is honored end to end. Overdeck always passes `--effort` on a Claude Code launch, so CLIProxy's own fallbacks (`xhigh` for adaptive thinking without a level, `medium` with no thinking block) never apply. One caveat: `gpt-5.5` is a deprecated alias of `gpt-5.6-sol` in the model catalog, so its effective effort levels and clamping come from the `gpt-5.6-sol` row, not from any levels set on `gpt-5.5` itself.

## OpenRouter favorites

Saved OpenRouter favorites remain selectable even when OpenRouter's model catalog
omits them. Overdeck displays the model ID and marks pricing and context as
unknown until the catalog includes the model again. Catalog omission alone does
not determine whether OpenRouter can serve a model. You can remove these saved
models from Settings → OpenRouter like any other favorite.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.