@ahmed-hobeishy/claude-coder
v0.2.0
Published
Drive Claude Code as a human: a subscription-funded fleet of named sessions over SDK + PTY transports, with a CLI, a multi-session TUI, and a loopback Anthropic-Messages API gateway (serve-api).
Downloads
164
Maintainers
Readme
claude-coder
Drive Claude Code as a human — funded by your
Claude Max/Pro subscription, not a metered API key. claude-coder is a TypeScript
library + CLI that manages a fleet of named, differently-configured Claude Code sessions
across two backends, with a scriptable control plane and an interactive multi-session TUI.
📚 Full documentation: https://claude-coder-docs.pages.dev/
Unofficial. This is an independent community project, not affiliated with or endorsed by Anthropic. It drives your own Claude Code login on your own machine — keep your usage within Anthropic's terms: personal tooling, not a hosted or multi-user service (the
serve-apigateway is loopback-only by construction for exactly this reason).
Subscription, not API key. Every turn runs against your logged-in Claude Code OAuth session.
claude-coderis fail-closed: it refuses to start a session ifANTHROPIC_API_KEY(or another billed-credential env var) is in force, so you can never accidentally bill an API account. See Authentication.
What it gives you
- A managed fleet of named sessions. Define profiles (cwd, model, permission mode, allowed tools, MCP servers, transport) and create/resume/fork named sessions against them, capped and queued so you never overload your subscription.
- Two backends, one contract. An SDK transport (the
@anthropic-ai/claude-agent-sdk, structured events) and a PTY transport (drives the realclaudeTUI over a pseudo-terminal vianode-pty). Both honor one capability-gradedSessionConfig. - An interactive TUI (
claude-coder tui) — a hand-rolled, zero-dependency, multi-session manager: a live session list, streaming transcripts, inline permission approval, interrupt, persistence/resume/fork, scrollback + search, and a?help overlay. - A scriptable control plane — the
FleetApifacade (used by the CLI and TUI) is a serializable-shaped, in-process API over the whole fleet; seeexamples/drive-fleet.ts.
Requirements
- Node.js >= 22
- A logged-in Claude Code subscription. Install the Claude Code CLI and run
claudeonce to authenticate (OAuth).claude-coderreuses that session. - The PTY transport additionally needs the
claudebinary on yourPATH.
Install
From npm (the package is scoped; the bin is plain claude-coder):
npm install -g @ahmed-hobeishy/claude-coder
claude-coder doctor # pure-read setup check (no spend)Or from source (development):
git clone https://github.com/ahmedEid1/claude-coder
cd claude-coder
npm install # `prepare` compiles dist/
node dist/cli/main.js --helpMore options (release tarballs, git-tag installs): installation guide.
Authentication
claude-coder only drives Claude inference through your subscription OAuth session
(apiKeySource ∈ {oauth, none}). It performs an auth preflight before any command that
could spawn claude and throws if a billed credential is present in the environment —
the deny set includes ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL, and AWS_BEARER_TOKEN_BEDROCK.
If you see an auth error, unset those variables; you should be relying on the Claude Code
login, not an API key.
Configuration: profiles
A profile is a named, reusable session configuration. Profiles are loaded from the first of:
--config <path>(explicit), else./claude-coder.config.json(project-local), else~/.claude/claude-coder/profiles.json(the documented default).
The file is a JSON array of profiles:
[
{ "name": "work", "transport": "sdk", "cwd": "/home/me/project" },
{
"name": "review",
"transport": "sdk",
"cwd": "/home/me/project",
"permissionMode": "default",
"model": "claude-opus-4-8"
},
{ "name": "tui-driver", "transport": "pty", "cwd": "/home/me/project" }
]Common per-profile fields: name (required), transport ("sdk" | "pty", required),
cwd, model, permissionMode ("default" | "acceptEdits" | "plan" |
"bypassPermissions"), allowedTools / disallowedTools, and mcpConfig. Credentials and
secrets are never read from the config file.
There is also a built-in profile, claude-code-expert (SDK transport, no MCP) — the
default profile that is always available, so the CLI and TUI work with no config file.
CLI
claude-coder <command> [args]
repl interactive multi-turn loop over a session (Ctrl-C interrupts, exit closes)
list list persisted + live-this-process sessions
resume reattach a persisted session (run a turn if a prompt is given)
fork branch a persisted session under a new name
history read a session's transcript history
tui open the interactive multi-session TUI over the fleet
doctor verify your setup (subscription auth, config, git-hooks) — read-only
serve-api run a loopback HTTP server (Anthropic Messages API wire format) for local dev — subscription-backed
Global flags: --config <path> --verbose --help --versionExamples
# Interactive multi-turn REPL over a session created from a profile
node dist/cli/main.js repl work
# Persisted sessions: list, resume with a follow-up (--json for the full result + cost), fork
node dist/cli/main.js list
node dist/cli/main.js resume work "now add a test"
node dist/cli/main.js resume work "say hi" --json
node dist/cli/main.js fork work --name work-experimentThe TUI
node dist/cli/main.js tui --config ./claude-coder.config.jsonA persistent left session list, the focused session's streaming transcript, and a
mode-aware status/help bar. Press ? at any time for the full, always-accurate keymap.
The essentials:
| Key | Action |
| ---------------------------- | ------------------------------------------------------------- |
| n | new session (pick a profile, name it) |
| e / Enter | edit / send a turn to the focused session |
| i | interrupt a busy turn |
| Tab / ↑ ↓ / 1–9 | move focus across sessions |
| r / f | resume / fork the focused persisted session |
| c | cancel a queued create |
| PgUp PgDn / Home End | scroll the transcript (pins; End re-follows) |
| /, then n / N | search the transcript, next / prev match |
| a / d / s | on a permission prompt: allow once / deny / allow for session |
| ? | help overlay |
| q / Ctrl-C | quit (graceful teardown, no orphaned claude) |
At the hard fleet cap (2 live sessions) a 3rd create surfaces as a queued row and is admitted FIFO when a slot frees. Permission requests appear inline; informative rate-limit heartbeats are silent (only real pressure notifies).
Architecture
Transport (SDK + PTY, one capability-graded contract)
→ Orchestration (profiles · admission/queue · persistence · secrets · failover · FleetApi)
→ CLI (repl/list/resume/fork/history/tui/doctor/serve-api)
→ TUI (pure Elm-style reducer + pure renderer + thin controller + impure driver)The TUI is split into a pure reducer (reduce(state, msg) → {state, effects} +
project(state) → ViewModel), a pure renderer (ViewModel → string[]), a thin
controller (mailbox, owns one FleetApi), and an impure driver (raw terminal) — so
nearly all of it is unit-tested deterministically.
Development
npm run build # tsc → dist/
npm run check # typecheck + eslint + prettier --check + vitest --coverage (the gate)
npm test # vitest runThe default gate spends no money, needs no auth, and spawns no real claude. The live
end-to-end smokes are spend-gated behind CC_LIVE=1 and live under test/tui/** /
scripts/live-e2e/ (never collected by the default gate).
Status & scope
The Transport, Orchestration, CLI, and TUI layers are implemented and
live-validated on a real Max subscription. Use within Anthropic's terms of service for
Claude Code; claude-coder automates an interactive client you are entitled to use — it does
not circumvent authentication or billing.
License
MIT © Ahmed
