Skip to content

feat(runtime): production ACP adapter for opencode and Claude Code #63

Description

@FreshlyBrewedCode

Parent

#62

What to build

Turn the spike adapter (src/runtime/acp-adapter.ts) into the production ACP adapter (ADR 0013
§1, §4, §5, §6). In this layer it sits beside the opencode adapter and is not yet the default
(#64 switches the default).

  • Agent definitions for claude (bundled @agentclientprotocol/claude-agent-acp) and
    opencode (opencode acp): command, env, session/new _meta, and how host settings are
    excluded. Settings are excluded when asked to (a flag on the definition or factory); the config
    knob that sets it lands in feat(workflow): choose agent and model separately, ACP as the default runtime #64.
  • Host-settings isolation (ADR 0013 §3, open item):
    • Claude: _meta.claudeCode.options.settingSources: ["project","local"]. Verify with a real
      prompt whether this keeps the user's skills and ~/.claude/CLAUDE.md out.
    • opencode: find a mechanism that hides ~/.config/opencode without hiding other tools'
      XDG config (gh auth in ~/.config/gh). Check opencode for a config-dir env var first. Record
      the result in finding 13's addendum.
  • Environment scrub: drop inherited CLAUDE_* / CLAUDECODE variables from the agent's
    environment.
  • Model handling: the adapter requires a model and fails before the prompt when the agent
    does not offer it. The error names the agent and gives a sample of offered ids.
  • Headless permission callback: prefer allow_always, then allow_once.
  • Usage: forward each ACP usage_update as a CUSTOM acp.usage chunk carrying a new
    usage signal (context: {used, size}, cost: {amount, currency}). Extend the
    AgentSignal union. Recording the signal in events is feat(events): context and cost per agent step, ACP-aware run detail #65, so the runtime may ignore it here.
  • Cancel: session/cancel, then kill after a grace period, and kill in finally.
  • Process exit mid-turn surfaces as a step error carrying the tail of stderr.
  • Availability check: a function the daemon can call to report which configured agents are
    missing (opencode not on PATH, Claude not logged in if detectable).
  • Tests: unit tests with a fake ACP agent over stdio (a small script speaking the SDK's
    AgentSideConnection). Cover model selection and rejection, the permission answer, usage
    signal, cancel and crash. Plus one live run per agent via spikes/13-acp-agents.ts.

Acceptance

  • bun run check green.
  • Live: bun spikes/13-acp-agents.ts run claude sonnet and … run opencode opencode/big-pickle
    complete; cancel leaves no processes.
  • Isolation verified for both agents, with the result written into finding 13.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    taskA single self-contained piece of work that ships as one PR

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions