Skip to content

agent-driver: lift the driver layer out of the framework #1733

Description

@suleimansh

agent-driver@0.0.0 is reserved on npm (2026-08-27) as the second step after the branch-management skill. This is the plan for what goes into it, from a read of packages/framework/src/driver/ as it is today.

What the package is

One interface and its implementations: start a coding-agent session in a directory, send it a prompt, get a stream of events back, resume it later.

interface Driver { id; start(opts): DriverSession; readQuota?(opts) }
interface DriverSession { id; cwd; prompt(text, opts): Promise<DriverTurn>; readCode?(path); dispose() }
type DriverEvent = start | session | text | action | result | rate-limit | error | notice

(src/driver/types.ts, 289 lines — the seam already exists and is what the rest of the framework programs against.)

What moves (≈1.7k non-test lines, zero surgery)

file role
types.ts the interface above
cli-session.ts, session-support.ts, child-registry.ts spawn a CLI, parse NDJSON turns, kill process groups
claude-code.ts + claude-code-quota.ts claude -p --output-format stream-json, --resume, claude -p /usage
codex.ts codex exec --json
actions.ts + actions-zip.ts run the agent on a GitHub Actions runner, read the transcript artifact
fake.ts scripted test double

Their only import from outside the directory is the DriverImplId string union (driver-names.ts); it moves with them. Tests (≈1.5k lines) come along unchanged; spawn is injectable everywhere.

What stays

cloud.ts (Claude Code on the web). It is the one file coupled to the framework — it talks to the daemon's _web-start endpoint and pushes an anchor commit through @better-skills/branch-management. It keeps implementing the package's Driver interface from inside the framework, which is also the proof the interface is enough for a third party.

What the framework keeps

driver-names.ts (the user-facing driver choice: labels, the choice→impl mapping) and everything that consumes drivers: agent.ts, the quota poller, the dashboard. They import from agent-driver instead of ./driver.

Order

  1. Lift src/driver/ into packages/agent-driver (workspace package, workspace:* dep from the framework), same mechanics as Branch management lives in its own package (#1725) #1726. No behaviour change; the framework's tests are the proof.
  2. Publish agent-driver@0.0.1.
  3. Then, separately: ACP as the way to add more harnesses (what t3code does for Cursor/Grok/OpenCode) — not part of the lift.

Open questions

  • The process.on('exit') reaper in child-registry.ts is a global side effect; fine for a library, or make it opt-in?
  • t3code's Claude driver goes through @anthropic-ai/claude-agent-sdk; ours shells out to claude -p. Keep the CLI (works with the user's login and quota) or offer both?

🤖 curated · Fable 5, effort high

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions