Skip to content

refactor: extract AgentProvider abstraction for multi-provider support - #130

Merged
aterrylu merged 1 commit into
mainfrom
terry/multi-provider
Apr 13, 2026
Merged

refactor: extract AgentProvider abstraction for multi-provider support#130
aterrylu merged 1 commit into
mainfrom
terry/multi-provider

Conversation

@aterrylu

Copy link
Copy Markdown
Owner

Summary

  • Extract all Claude Code-specific logic from sessions.ts into providers/claude-code.ts implementing the AgentProvider interface
  • Create provider registry (providers/index.ts) with getProvider() / getAllProviders() — sessions.ts delegates to the provider instead of hardcoding CC flags
  • Expand AgentProvider interface with resolveBinary(), buildArgs(), buildEnv(), attachStartupWatcher(), and ProviderCapabilities type
  • Add PtyHandle abstraction to keep node-pty dependency out of the core package
  • Add ResolvedSpawnOptions type for pre-resolved spawn configuration passed to providers

This is Phase 0 of multi-provider support (Codex CLI + Gemini CLI). Pure refactor — zero behavior change, all 70 tests pass.

sessions.ts (before):  ~830 lines, CC flags hardcoded throughout
sessions.ts (after):   ~470 lines, provider-agnostic orchestration
providers/claude-code.ts: ~370 lines, all CC-specific logic
providers/index.ts:    ~40 lines, provider registry

Architecture

sessions.ts (orchestrator)
  │
  ├── validates options, generates IDs
  ├── resolves provider via getProvider(name)
  ├── calls provider.buildArgs() + provider.buildEnv()
  ├── spawns PTY with provider.resolveBinary()
  ├── calls provider.attachStartupWatcher() if configured
  └── manages lifecycle, output buffer, persistence
          │
          ▼
providers/claude-code.ts
  ├── resolveBinary() — finds claude in PATH
  ├── buildArgs() — --session-id, --append-system-prompt, --settings, --mcp-config, etc.
  ├── buildEnv() — AUTONOMOS_* vars, ANTHROPIC_* overrides, PATH setup
  ├── attachStartupWatcher() — auto-dismiss trust/channels prompts
  └── capabilities — 13 hook events, channels messaging, session fork, etc.

Why this matters

sessions.ts was an 830-line monolith with CC-specific flags hardcoded throughout. Adding Codex or Gemini support would have required forking the entire function. Now, adding a new provider means creating a single file that implements AgentProvider — the orchestration layer is shared.

Research backing this: docs/research/multi-provider-support.md (POC validated with both Codex v0.118.0 and Gemini v0.30.0).

Test plan

  • make check passes (lint + typecheck + 70/70 tests)
  • Rebased on latest main
  • Polished by 3 review agents (code-reviewer, code-simplifier, silent-failure-hunter)
  • Fixed behavioral regression in attachStartupWatcher expectChannels logic (caught by code-reviewer)
  • Fixed redundant capability re-resolution in buildArgs (caught by code-reviewer)
  • Improved error logging in PTY write failures and timeout warnings (caught by silent-failure-hunter)

🤖 Generated with Claude Code

Extract all Claude Code-specific logic (binary resolution, CLI flag
building, env var setup, startup watcher) from sessions.ts into a
providers/claude-code.ts module implementing the AgentProvider interface.

sessions.ts now delegates to the provider registry for spawn configuration,
making it provider-agnostic. This is the prerequisite (Phase 0) for adding
Codex CLI and Gemini CLI as alternative agent runtimes.

Key changes:
- Expand AgentProvider interface with resolveBinary(), buildArgs(),
  buildEnv(), attachStartupWatcher(), and ProviderCapabilities
- Add PtyHandle abstraction to avoid node-pty dependency in core package
- Add ResolvedSpawnOptions for pre-resolved spawn configuration
- Create provider registry with getProvider() and getAllProviders()
- Net removal of ~260 lines from sessions.ts monolith

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@nox-0x nox-0x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean abstraction — well-structured provider interface, sessions.ts is now cleanly provider-agnostic, and all CC-specific logic is correctly extracted. The attachStartupWatcher improvements (agent labels, ptyDead guard, cleaner console output) are a meaningful upgrade. No blocking issues. LGTM.

@aterrylu
aterrylu marked this pull request as ready for review April 13, 2026 05:20
@aterrylu
aterrylu merged commit 5b07871 into main Apr 13, 2026
1 check passed
@aterrylu
aterrylu deleted the terry/multi-provider branch April 13, 2026 05:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants