composer-sidekick
v0.1.1
Published
Delegate bulk/parallel coding to Cursor Composer 2.5 from Claude Code — spend both subscriptions in parallel.
Maintainers
Readme
composer-sidekick
Delegate tasks Cursor Composer 2.5 from Claude Code and spend your Claude and Cursor subscriptions in parallel. Opus orchestrates and reviews; Composer workers do the grunt work.
Install
As a Claude Code plugin:
/plugin marketplace add Paul-Rusch/composer_sidekick
/plugin install composer-sidekickOr as a CLI:
npx composer-sidekick setup # checks your config
npx composer-sidekick doctor # diagnoses key / deps / sandbox / tierGet a Cursor API key
You need a paid Cursor plan (Pro, $20/mo, or higher — every paid tier can mint keys; the free tier
cannot). Generate one at cursor.com/dashboard/api, then put it in
your environment or a gitignored .env:
CURSOR_API_KEY=crsr_...Node ≥ 22 required (the @cursor/sdk bridge uses the built-in node:sqlite, which only exists in Node 22+); Linux / WSL / macOS (see Platform).
Footprint: Installed with its runtime dependencies it occupies ~44 MB on disk — almost entirely the @cursor/sdk native bridge (~30 MB); the bridge's own compiled code is ~210 kB. Worker worktrees under .composer-sidekick/ add to this over time; reap them with /compose-prune.
Skills (slash commands): /compose-launch — launch a worker (pick persona → self-contained task → delegate/fanout); /compose-steer — monitor and steer in-flight workers (status, activity, tail + continue/resume/cancel); /compose-doctor — diagnose setup; /compose-prune — reap stale worktrees.
Configuration / Environment Variables
Copy .env.example to .env (gitignored) or export variables in your shell. The table below is the canonical reference for every supported variable.
| Variable | Required? | Default | Description |
|---|---|---|---|
| CURSOR_API_KEY | Yes (delegate / continue / fanout / resume) | — | Cursor worker auth; format crsr_.... Generate at cursor.com/dashboard/api. |
| COMPOSER_BACKEND | No | sdk | Backend selector; sdk is the only supported backend. |
| COMPOSER_FAST | No | false | Fast tier (lower latency, ~6× pool cost); default is Standard. Set true for Fast. |
| COMPOSER_SANDBOX | No | true | Bubblewrap write+network jail; accepts true/false/on/off/1/0. |
| COMPOSER_AUTO_REVIEW | No | true | Cursor auto-review guardrail (blocks network shell + tool calls). |
| COMPOSER_MAX_CONCURRENT | No | 16 | Integer cap on concurrent SDK workers. |
| COMPOSER_INPLACE | No | false | Run in-place instead of worktree isolation. |
| COMPOSER_NOTIFY | No | off | Notification hook toggle/command (off, bell, desktop). |
| COMPOSER_HOME | No | unset (nearest git root or cwd) | Override for the state directory root; state lives at <root>/.composer-sidekick/. |
| COMPOSER_JOBS_ROOT | No | <state>/jobs | Override for the jobs store root. |
| COMPOSER_EVENTS_FILE | No | <state>/events.jsonl | Override path for the events.jsonl bus file. |
| CURSOR_FORCED_SHELL_EGRESS_NETWORK_DEFAULT | No | unset (auto allow on WSL2) | Advanced: set allow to skip network-namespace creation. |
| LOG_LEVEL | No | info | Structured logger verbosity: trace, debug, info, warn, error, fatal, silent. |
Quickstart
# 1. confirm setup (API key, sandbox, node, tier)
npx composer-sidekick doctor
# 2. delegate your first task — worktree-isolated; --json prints the result envelope
# (status, summary, branch, crossCheck, tokens)
npx composer-sidekick delegate "create hello.txt with a friendly greeting" --persona coder --json
# 3. review the worker's diff and merge its branch (printed as `branch` in the envelope)
git diff main..composer/<jobId>
git merge composer/<jobId>Run several at once with run_in_background (your harness re-invokes Claude on completion), or fan out a
bounded batch: composer-sidekick fanout --task-file a.md --task-file b.md --max-parallel 4. Inside
Claude Code this whole flow is the /compose-launch skill, with /compose-steer to watch and
answer in-flight workers.
Why
- Spend both subscriptions at once — your expensive Opus context stays on reasoning/review; cheap Composer workers do the bulk edits in parallel.
- Trustworthy returns — workers finish via a mandatory
submit_report, cross-checked against the real diff (claimed files ↔ actual changes), not free-text you have to verify by hand. - Multi-round — a blocked worker asks a question; you answer and it resumes with full context.
- See the swarm — a live monitor (
npm run swarm) shows every worker's status, current tool, tokens, and lineage. - Safe at scale — bounded concurrency, automatic retries on transient failures, and worktree-isolated writes.
- Secure by default — API keys are redacted from all persisted state, workers can be sandboxed (bubblewrap), and a concurrency ceiling caps blast radius. See
SECURITY.md.
How it works
Claude Code cannot point a native subagent at Composer — delegation crosses a tool boundary, bridged by the CLI:
composer-sidekick delegate "<task>" launched with run_in_background starts a worker and returns a jobId; the harness re-invokes you on completion (no ~60s tool-call cap). Poll/monitor with status, wait, swarm, and activity; the job's result envelope (summary, branch, diffStat, tokens, sessionId) lands under .composer-sidekick/jobs/<id>/.
The worker runs in-process via the Cursor @cursor/sdk backend (COMPOSER_BACKEND=sdk), behind one capability seam (ComposerBackend in src/core/backend.ts). It provides Standard-tier pinning, token metering, and resume for multi-round handoff. Phase 3 settled the SDK as the official mode of operations — see docs/PHASE3-RESULTS.md for the data behind it.
Why a CLI, not an MCP server
MCP's request/response model caps a tool call at ~60s with no completion callback — a straightjacket for steering long-running, multi-round subagents. A backgrounded CLI command has no such cap, and a CLI is host-agnostic: anything that can run a shell command can drive it, which is arguably more portable than MCP.
Cost & tiers
Composer workers run on composer-2.5 — an order of magnitude cheaper than frontier models.
| Model (per 1M tokens) | Input | Output | |---|---:|---:| | composer-2.5 — Standard | $0.50 | $2.50 | | composer-2.5 — Fast | $3.00 | $15.00 | | Claude Opus 4.8 | $5.00 | $25.00 | | OpenAI GPT-5.5 | $5.00 | $30.00 | | Claude Fable 5 | $10.00 | $50.00 |
Provider list prices, mid-2026 — verify against each provider for current rates.
Within subscription plans it's cheaper still. composer-2.5 draws from Cursor's included Auto + Composer pool, so it's ~$0 marginal up to the plan's limits. Cursor doesn't publish a hard Composer cap — it describes the pool only as "generous". Past the included pool, usage bills at the rates above.
Tiers: fast is the only knob. Fast is ~6× pricier but still pretty affordable.
Workers default to fast=false — Standard tier (DEFAULT_FAST in src/core/backend.ts); pass fast: true
per call when you need lower latency, or flip the global default with composer-sidekick config fast.
Platform
Linux, WSL, and macOS (Node ≥ 20). Windows needs WSL — there is no native Windows path. Worker
sandboxing uses bubblewrap, which is Linux-only: on macOS (or WSL without bubblewrap) workers run
unsandboxed with a one-time notice — writes are still confined to a throwaway git worktree, but there's
no OS-level jail. composer-sidekick doctor reports your sandbox status.
Troubleshooting
| Symptom | Fix |
|---|---|
| CURSOR_API_KEY is not set | Add it to .env or your environment (Get a Cursor API key); run composer-sidekick doctor. |
| this repo has no commits yet | Worktree isolation needs a HEAD — make an initial commit, or delegate with --inplace. |
| Not inside a git repo | Delegation needs git (worktree isolation). Run it inside a repository. |
| Researcher worker can't reach the network (curl) | autoReview gates outbound shell. Run composer-sidekick config no-autoreview before the task, then restore it. |
| workers run unsandboxed notice | Expected on macOS / WSL without bubblewrap (Linux-only). Writes stay worktree-confined; install bubblewrap to add an OS jail. |
| Rate-limited / pool exhausted | You hit Cursor's Composer pool limit; the scheduler auto-retries transient failures. Wait, or switch tier with config standard. |
Project layout
src/
core/
backend.ts ComposerBackend seam + envelope types
jobStore.ts Shared on-disk job format, result derivation
model.ts Locked composer-2.5 config (tier via DEFAULT_FAST in backend.ts)
worktree.ts Git worktree isolation + commitWorktree/harvestMerge
fanout.ts Parallel start + await helpers
events.ts F1 job event bus (emit/subscribe; events.jsonl)
scheduler.ts F3 bounded-concurrency swarm runner (+ retry)
snapshot.ts F2 SwarmSnapshot aggregator (live monitor data)
gc.ts F3 worktree + agent-store lifecycle GC
backends/
sdk.ts In-process @cursor/sdk agent (token metering, resume)
transport.ts Transient transport-reset resilience (T28)
telemetry/
metrics.ts Per-job metric log report.ts SDK job summary table
scripts/
resolve-model.ts List models / verify Standard config
harvest.ts Copy worktree output to main (or --merge)
smoke-*.ts / test-*.ts End-to-end + feature checks
docs/ PHASE0-FINDINGS.md · TOOLING-LOG.md · COMPOSER-PERFORMANCE.md · PLAN-v1.md (archived)
.claude/settings.json Permissions + Stop hookJob state lives under .composer-sidekick/jobs/<jobId>/ (meta.json, events.jsonl, result.json). Worktrees under .composer-sidekick/worktrees/. Both are gitignored.
Commands
| Command | Description |
|---|---|
| composer-sidekick delegate "<task>" [--persona <name>] | Delegate a task to a Composer worker (persona = .cursor/agents/<name>.md) |
| composer-sidekick continue <jobId> "<msg>" | Answer a blocked worker; resume the same session |
| composer-sidekick fanout --task-file <f>… [--max-parallel N] | Launch N parallel workers (one per task file), bounded concurrency |
| npm run resolve-model | List Composer models / verify config |
| npm run typecheck | tsc --noEmit |
| npm run swarm | Live terminal monitor of the swarm (F2) |
| npm run gc | Reap stale worktrees + report the agent store (F3) |
Status & what's next
v1 (shipped): both backends behind one seam, worktree commit/merge + harvest, read-only
retrieval, parallel fanout, and telemetry/bake-off report. Composer runs confirmed billing to the
included Auto+Composer pool.
v2 (shipped): SDK-only structured-return infra (mandatory submit_report + files-changed↔diff
cross-check), robust multi-round resume, autoReview/sandbox scaffolding, and the orchestration eval.
See docs/PLAN-v2.md (execution record).
v3 (next — see ROADMAP.md): the swarm-experience track — push notifications/event bus,
observability control tower, safe parallel execution, and activating the dormant Cursor SDK power
(sandbox, autoReview, cloud agents). F1 (event bus), F2 (live monitor), and F3 (safe parallel execution) are shipped; the SDK-enablement track (F4/F5) and beyond are on the backburner.
Decision (official — docs/PHASE3-RESULTS.md): directly driving the SDK
backend via the composer-sidekick CLI is the default mode of operations and the focus of all further
development. SDK is the only COMPOSER_BACKEND; the frozen v1 CLI backend, the Anthropic-side broker, and
the MCP server have all been removed.
Further reading
ROADMAP.md— current v3 roadmap (the next agent starts here)docs/PLAN-v2.md— archived v2 takeover plan (execution record)CLAUDE.md— orchestrator delegation rules + "use Composer to the fullest"docs/PHASE0-FINDINGS.md— locked model config, auth, dashboard verificationdocs/TOOLING-LOG.md— implementation friction log + CLI-vs-SDK signaldocs/COMPOSER-PERFORMANCE.md— how Composer performed as a subagentdocs/PLAN-v1.md— archived v1 plan + failure-mode table
