Adding a harness
The adapter boundary is the extension point. A new harness means one new file, registration in two places, and tests:
src/adapters/<name>.ts— export aHarnessAdapter. The interface is insrc/adapters/types.ts;opencode.tsis the smallest example,codex.tsthe most complete. You implement:name,versionCommand,supportedVersions,pathPrepend— identity, and the probe sonata runs to read the installed versionplan(input)→ aLaunchPlan: the bashscript, whether the harness isinteractive, andeffortHonoured(required — whether the plan passes a pinned<key>@<effort>level through). Optional on the plan:canWriteReport(false when this configuration cannot writereport.mdat all) andsilentUntilExit(true when nothing reaches the pane until the run exits)canPromptForApproval— whether the harness can stop and ask a humanpromptPatterns/describePrompt— how a pending approval looksapproveKeys— the tmux key sequences that answer oneusage(query)— required: the tokens a finished run spent, read from the harness's own store, orunobservablewith a reason. Never guessed, never zero- optional:
health(env)— runtime checks beyond "is it installed";update— howsonata initoffers to bring the harness up to date;fallbackReportFile— a file the harness writes its own final message to, used as a report fallback before the pane
src/adapters/index.ts— register it.src/config.ts— add the name toKNOWN_HARNESSES.tests/adapters/<name>.test.ts— follow an existing adapter's tests.
Optionally, src/detect.ts for sonata init discovery. It probes opencode, pi, codex (via codex app-server's model/list) and reasonix; the claude harness is the host and is never offered for discovery. Note the id shape — opencode, pi and reasonix take provider/model ids, while codex takes a bare id.
Probe the real binary before you write the adapter. Every adapter bug found so far was invisible in the documentation and obvious on the first real run: OpenCode silently eating a positional argument, codex rejecting a flag that its own exec accepts, both harnesses printing approval prompts that matched none of the patterns written for them. If you claim a harness prints something, capture it into tests/fixtures/panes/ and test against that.