Skip to content

[design] Structured engine adapters — parse each CLI's own JSON event stream, not a claude-or-raw switch #728

Description

@serge-ivo

Problem

The coding runner (packages/browser-runner/src/coding/headless.ts) picks the engine transcript mode with a single binary switch:

this.mode = config.clientType === "claude" ? "stream-json" : "raw";

The result: for any non-Claude engine the console/timeline shows noisy, truncated output; spend is unmetered (#556); acts are unattributed (#594); and the handoff/last-line is scraped from prose (#621). This is not a per-engine bug — it's that mode and handle() are hardcoded to Claude's schema, so a structured-capable CLI (Codex exec --json, Gemini, etc.) has nowhere to plug its events in.

Proposed direction

Replace the claude/raw switch with a small per-engine adapter interface. Each engine declares:

  1. how to build its structured-output launch argv (Claude: the stream-json flags in buildClaudeArgs; Codex: exec --json; …), and
  2. how to map ONE event line → a normalized event: { assistantText | toolUse | toolResult | usage | turnEnd | error }.

The existing Claude code becomes the Claude adapter (behaviour-identical — pin it with the current headless.test.ts). Raw stdout stays as the generic fallback adapter for any CLI with no structured mode. HeadlessSession keeps its public surface (start/snapshot/runState/ready/input/interrupt/stop/alive, takeUsage/takeActs) — only the guts behind handle()/mode move.

Why this is the right shape

Acceptance

Refs: #556, #674, #693, #621, #594

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2: correctnessReal defect, no live harm today — inert fields, miscounts, missing guardscoderThe Coder wedge agent (#68) — Engine, Pilot, Co-pilot, Loop, OverseerenhancementNew feature or requestrunnerpackages/browser-runner + packages/cli — ships only via an npm publish

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions