Skip to content

Otter Parity Matrix

Source baseline: research/otter/SPEC.md (Apr 25 2026), upstream tree walk under packages/opencode/src/ (cli, agent, command, mcp, lsp, acp, plugin, config, permission). Updated: 2026-04-25, after wave-1 ship (O1–O15). Refreshed 2026-04-30 by D1 at the wave-9 close — five YELLOW rows promoted to GREEN as the wave-9 batch (O1/O2/O3/O4/O5) closed the carry-over gaps. Legend: GREEN = shipped / at parity (or superset); YELLOW = partial; RED = deferred.

Wave-9 close (2026-04-30, D1). Five carry-over items from the wave-1 follow-up list landed in this wave:

  • agents create (interactive scaffolder) — O1/W9, chimera/otter/agents.py.
  • mcp add / mcp auth (live add + OAuth device-flow) — O2/W9, chimera/otter/mcp_cli.py.
  • -f / --file (one-shot file attachment, stdin via -, 100 KB warn / 500 KB cap) — O3/W9, chimera/otter/cli.py.
  • --title + sessions rename (titleable runs) — O4/W9, chimera/otter/cli.py + chimera/otter/sessions.py.
  • chimera completion bash|zsh|fish [--cli all|<animal>] — O5/W9 cross-CLI shell-completion generator, chimera/cli/completion.py.

All five reports live under research/otter/{O1..O4}-W9-REPORT.md and research/O5-COMPLETION.md. Live tests against the new files pass: 10 (test_agents_create.py) + 25 (test_mcp_cli.py) + 16 (test_file_attachment.py) + 19 (test_session_title.py) + 25 (test_completion.py) = 95 new tests. The trademark scrub still exits OK at the codename-aggregate level (passed: 7).

Trademark hygiene. Throughout this document the upstream project is referred to as “the open-source coding agent” or “the upstream”. Live references to filesystem paths such as ~/.opencode/config.json are kept because they are facts (the directory chimera otter reads from on disk), not brand claims. See docs/otter/security-and-trademarks.md.

The upstream CLI registers about twenty top-level commands (see packages/opencode/src/index.ts). Otter’s surface is intentionally narrower: the long tail of account / db / github / pr / upgrade / uninstall / web / import / export / generate / stats / debug is out of scope for wave-1 because Chimera already covers those flows through different surfaces (chimera mink runs, chimera eval, pyproject.toml install, etc.). Wave-1 focuses on the six surfaces that make otter useful as a coding-agent driver.

Upstream surfaceOtter statusFileNotes
run [message..]GREENchimera/otter/cli.py (-p/--print)Mirrors the one-shot run flow: prompt arg, --model, --output-format text|json|stream-json, --cwd, --allowed-tools, --no-save, --run-id.
serve (HTTP)GREENchimera/otter/server.py, dispatched from cli.pyMinimum REST + SSE surface (/healthz, /session, /turn, /events). Backs an out-of-tree TUI client.
acpGREENchimera/otter/acp.py (invoked via serve --acp)JSON-RPC 2.0 over stdio. initialize, session/new, session/message, session/cancel, permission round-trip.
session list | deleteGREEN / YELLOWchimera/otter/sessions.py, cli.pysessions list + sessions show <id> shipped (read-only). delete not yet wired (covered by rm -rf <eventlog-dir>).
agent create | <list>GREENchimera/otter/agents.py (cmd_agents_create)agents list/show (read-only) + agents create [<name>] [--user] interactive scaffolder shipped. Stdlib-only (no $EDITOR, no readline); writes .opencode/agent/<name>.md. Wave-9 close (O1/W9).
mcp list | add | authGREENchimera/otter/mcp.py + chimera/otter/mcp_cli.pymcp list walks user + project scopes; mcp add <name> [-- <command...>] (or --mcp-http) writes the entry atomically to the chosen scope’s config; mcp auth <name> runs OAuthDeviceFlow for HTTP entries with manual paste fallback. Wave-9 close (O2/W9).
models [provider]GREENchimera/otter/providers.py--model provider/model honored everywhere; OTTER_MODEL env var pinned. Refresh-cache flag deferred.
providers (auth login/list)YELLOWchimera/otter/providers.pyDefault chain (Anthropic → OpenRouter → OpenAI); device-flow OAuth ridden via chimera.auth. Plugin-driven auth methods deferred.
statsGREENchimera otter sessions cost (G6)sessions cost --since 7d --format json aggregates ~/.chimera/eventlog/otter-*/summary.json. Same rollup the GET /runs/cost HTTP route serves.
export / importYELLOWchimera/otter/share_cmd.py covers exportshare <id> --sink file --format json writes a portable transcript. Import flow deferred.
pr <number> (PR checkout)REDn/aOut of scope for wave-1; users run gh pr checkout then chimera otter.
github (CI bot)REDn/aDefer; orthogonal to coding-agent runtime.
db (sqlite shell)REDn/aOtter persists JSONL eventlogs, not sqlite. No equivalent needed.
account (auth/team)REDn/aSingle-tenant; no central account service.
upgrade / uninstallREDpip install -U chimera-run covers upgradeUse the upstream packaging story.
web (web tunnel)REDn/aOut of scope.
generate (OpenAPI dump)REDn/aDefer; generated when needed via chimera/otter/server.py.
tui thread | attachYELLOWchimera otter REPLInteractive REPL ships; multi-window thread mode deferred.
plugin (install/list/…)GREENchimera/otter/plugins.pyReads ~/.opencode/plugin/<name>/ and project-level overrides; agents/commands/MCP entries are forwarded to existing Chimera registries.
completionGREENchimera/cli/completion.py (chimera completion bash|zsh|fish)Cross-CLI shell-completion generator, walks the live argparse tree. Honors --cli all|<animal>. Wave-9 close (O5).

The upstream RunCommand (see packages/opencode/src/cli/cmd/run.ts) exposes 17 flags. Otter mirrors the ones that affect agent semantics and skips the ones that depend on opencode-specific server/session plumbing.

Upstream flagOtter statusOtter equivalentNotes
--commandYELLOW/<custom-command> in REPLOne-shot --command invocation deferred; custom commands run in REPL today.
--continue/-cYELLOWchimera otter sessions show <id> + manual resumeWave-2 will add --continue flag wired to EventSourcedSession.resume.
--session/-sYELLOWchimera otter sessions show <id>Same as above; live one-shot resume deferred.
--forkREDn/aRequires the --continue story; deferred.
--shareYELLOWchimera otter share <id>Out-of-band share subcommand instead of in-line flag.
--model/-mGREEN--model, $OTTER_MODELIdentical syntax: provider/model.
--agentGREENshimmed via chimera.cli.code agent resolutionHonors chimera otter agents list.
--formatGREEN--output-format text|json|stream-jsonAdds stream-json (one event per line) on top of upstream’s default|json.
--file/-fGREEN-f / --file PATH (repeatable; - for stdin)Stacks via action="append"; wraps each file in <file path="X" lines="N">…</file> and prepends to -p prompt. 100 KB per-file warn, 500 KB cumulative cap with truncation marker. Wave-9 close (O3/W9).
--titleGREEN--title "..." + sessions rename <id> <title...>Persists in summary.json, surfaces in sessions list (TITLE column) + sessions show (title: line). Empty title clears the label. Wave-9 close (O4/W9).
--attachREDn/aRemote-server attach is covered by chimera mink --remote ssh://... instead.
--password/-pREDbasic auth managed via reverse proxyOtter server is unauthenticated by default; production deployments front it with the user’s reverse proxy.
--dirGREEN--cwdSame semantics.
--portGREENchimera otter serve --portSame.
--variantYELLOWn/aProvider-specific reasoning effort flag deferred.
--thinkingYELLOWenv var CHIMERA_THINKING_LEVELSurface via env var instead of flag for now.
--print-logs/--log-levelYELLOWCHIMERA_LOG_LEVEL env varOtter inherits chimera-wide log handling.
--pureREDn/aOtter has no equivalent of opencode’s “no external plugins” mode; use --allowed-tools to narrow surface.

The upstream TUI registers about thirty slash-eligible commands (see packages/opencode/src/cli/cmd/tui/app.tsx). Otter ships the core conversational subset (twenty-five) and skips terminal-window controls that don’t apply to a CLI REPL.

Upstream slashOtter statusOtter handler
/helpGREENcmd_help (shared registry)
/exit (/quit, /q)GREENcmd_exit, cmd_quit
/sessions (/resume, /continue)GREENcmd_sessions (chimera/otter/slash.py)
/new (/clear)GREENcmd_new, cmd_clear
/shareGREENcmd_share -> chimera/otter/share_cmd.py
/modelsGREENcmd_models (alias of shared /model)
/agentsGREENcmd_agents (alias of shared /agent)
/agentGREENshared cmd_agent
/modelGREENshared cmd_model
/initGREENshared cmd_init
/costGREENshared cmd_cost
/toolsGREENshared cmd_tools
/mcp / /mcpsGREENshared cmd_mcp, cmd_mcps
/connectYELLOWcmd_connect (late-binds providers)
/statusGREENshared cmd_status
/themesYELLOWcmd_themes stub
/yoloGREENshared cmd_yolo
/compactGREENshared cmd_compact
/doctorGREENshared cmd_doctor
/configGREENshared cmd_config
/undoYELLOWcmd_undo stub
/redoYELLOWcmd_redo stub
/editYELLOWcmd_edit stub
/variantsREDn/a
/workspacesREDn/a (single-cwd model)
terminal-title toggleREDn/a
heap-snapshot / debug overlayREDn/a

The upstream’s plugin SDK defines a Hooks interface with sixteen extension points (see the upstream’s plugin/index.ts server module and SDK index.ts). Otter maps each to existing Chimera primitives.

Upstream hookOtter statusMapping
eventGREENchimera.events.EventBus
configYELLOWchimera.config.config_file.ChimeraConfig.load
tool (custom tool registration)GREENchimera.plugins.PluginExtensionRegistry.tools
authYELLOWchimera.auth (device flow, OAuth); plugin-driven providers TODO
chat.messageGREENHook with event="chat.message" in chimera.hooks.events
chat.paramsYELLOWnot yet emitted (provider params bypass hooks today)
chat.headersYELLOWnot yet emitted
permission.askGREENchimera.permissions.audit + ConfirmationPolicy
command.execute.beforeYELLOWchimera.hooks PreCommand event TODO
tool.execute.beforeGREENHook event="tool.execute.before" (PreToolUse)
tool.execute.afterGREENHook event="tool.execute.after" (PostToolUse)
shell.envYELLOWBashOps.env injection point exists; plugin event TODO
experimental.chat.messages.transformREDnot exposed
experimental.chat.system.transformYELLOWsystem-prompt rules ingest covers static case
experimental.session.compactingYELLOWchimera.compaction ABC supports custom strategies
experimental.text.completeREDnot exposed
tool.definition (tool description rewrite)YELLOWToolGroup middleware can wrap definitions

Configuration keys (~/.opencode/config.json)

Section titled “Configuration keys (~/.opencode/config.json)”

Upstream’s config schema (see packages/opencode/src/config/config.ts) defines roughly sixty top-level keys. Otter ingests the subset that maps onto first-class Chimera primitives and ignores keys that drive TUI-only chrome.

Upstream keyOtter statusNotes
mcpGREENRead by chimera/otter/mcp.py. Both local (stdio) and remote (http) transports honored.
agentGREENCombined with .opencode/agent/*.md markdown agents.
commandGREENCombined with .opencode/command/*.md.
providerYELLOWDefault-chain wiring lives in chimera/otter/providers.py; per-provider overrides honored opportunistically.
permissionGREENMapped to chimera.permissions rules at session bootstrap.
instructionsGREENConcatenated by chimera/otter/rules.py.
keybindsREDOtter is a CLI; no keybinds.
themeREDTUI chrome only.
shareYELLOWchimera otter share covers the export sink; auto-share toggle deferred.
pluginGREENSpec list resolved by chimera/otter/plugins.py.
disabled_providersYELLOWHonored opportunistically when the env-var presence check fires.
experimental.*REDDefer until the upstream stabilizes them.
  • Top-level CLI subcommands: 10 GREEN, 2 YELLOW, 8 RED of the 20 upstream commands (refreshed at wave-9 close — agent create, mcp add/auth, and completion promoted to GREEN). Coverage focuses on the agent runtime; admin/install/account flows are intentionally not mirrored.
  • run flags: 7 GREEN, 5 YELLOW, 5 RED of the 17 upstream flags (refreshed at wave-9 close — --file/-f and --title promoted to GREEN).
  • Slash commands: 17 GREEN, 7 YELLOW, 4 RED of the 28 reviewed.
  • Plugin hooks: 5 GREEN, 8 YELLOW, 4 RED of the 17 reviewed.
  • Config keys: 6 GREEN, 4 YELLOW, 4 RED of the 14 reviewed.

Chimera-only capabilities (do not regress)

Section titled “Chimera-only capabilities (do not regress)”

Wave-1 of otter inherits the same Chimera-only superset that mink already advertises: cooperative CancellationToken, mid-turn MessageQueues steering, loop detection, ghost commits, instruction anchor, learning store, discipline guards, EventSourcedSession crash recovery, FileAwareCompaction, SessionTree in-place branching, RedactionMiddleware, CostTracker with cache/reasoning breakdown, the 26-event EventBus, and the multi-tier AgentConfig.from_markdown() registry.

Follow-up issues to file (or already filed)

Section titled “Follow-up issues to file (or already filed)”
  1. chimera otter --continue / --session <id> / --fork (one-shot resume).
  2. chimera otter agents create (interactive agent scaffolder). Shipped at wave-9 close (O1/W9).
  3. chimera otter mcp add / chimera otter mcp auth <name> (live add + OAuth). Shipped at wave-9 close (O2/W9).
  4. chimera otter session delete <id> (currently rm -rf the eventlog dir).
  5. Plugin-driven provider auth (mirror the upstream Hooks.auth flow).
  6. chimera otter stats --since=<duration> aggregating summary.json across ~/.chimera/eventlog/otter-*/. Shipped as chimera otter sessions cost (G6).
  7. File-attachment flag (--file <path>) for one-shot prompts. Shipped at wave-9 close (O3/W9; -f / --file PATH, repeatable, stdin via -).
  8. Theme switcher (/themes) for the REPL once a TUI palette lands.
  9. Workspace mode (multiple cwds in a single session).
  10. Shell-completion script generation (chimera otter completion). Shipped at wave-9 close as the cross-CLI chimera completion bash|zsh|fish [--cli all|<animal>] generator (O5).
  11. Session titles. Add a --title "..." flag and sessions rename <id> <title> subcommand. Shipped at wave-9 close (O4/W9).

When a user runs chimera otter from a project that already contains .opencode/config.json, every GREEN row above is expected to behave in lockstep with the upstream open-source coding agent at the black-box level (one-shot prompt, slash command, MCP server discovery, agent / command / rules ingest, plugin loading). YELLOW rows degrade gracefully and emit a hint where the gap is user-visible. RED rows are not implemented and will return a “not yet wired” notice with a pointer to the issue tracker entry.