npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

headlesscode

v1.0.3

Published

Standalone headless coding-agent harness: runs the Zoo Code agent loop (prompts, tools, modes) without a VS Code UI, driven by CLI, HTTP, and parallel worktree orchestration.

Readme

headlesscode

A small, purpose-built, genuinely headless coding-agent harness. It reuses what makes Zoo Code (an Apache-2.0 Roo Code fork) good — its system prompts, native tool schemas, and mode/rules configuration format — without carrying along the VS Code GUI dependency.

This repo implements:

  • The headless runtime engine — vendoring the portable Apache-2.0 core and the headless runtime (OpenRouter client, tool executor, tool-call parser, orchestration loop, CLI).
  • A headless orchestration layer — split an issue into worker groups, run each as a harness subprocess in its own git worktree, review, and merge (see docs/phase2-orchestration.md).
  • A memory subsystem — per-project knowledge facts + rolling session summaries, with local semantic recall and a pluggable MemoryStore contract for a remote backend.
  • Headless QA — run the target repo's qa-agent mode as a second harness session (see docs/phase4-qa.md) and a human-approval deploy gate in front of the repo's deploy-production.sh (see docs/phase4-deploy-gate.md).
  • A GitHub issue watcher (see docs/phase5-issue-watcher.md) — file an issue with a target label and a poll loop automatically splits and spawns it through the existing orchestration pipeline, with durable idempotency so a restart never double-spawns.
  • Cloud-scaling guardrails — a hard concurrent-session cap, a per-session cost/time/iteration budget, and a CloudProvider abstraction (container/VM per issue behind the same lifecycle as the local worktree flow) with an evaluation-only cloud-provider sketch (see docs/phase6-cloud.md). No live cloud resources are launched; the caps/budgets land before any scaling.

⚠️ Security warning: default-allow arbitrary command execution. headlesscode is a headless coding agent: by default it runs arbitrary shell commands with your full user privileges (no sandbox, no approval prompts) and can read and modify your files — including ~/.ssh, ~/.aws, and any other credentials your user can access. Run it only on machines and with tasks you trust, and isolate it (container/VM/dedicated user) whenever untrusted content is involved. See SECURITY.md for the full disclosure and the optional permissions layer that provides defense in depth (not a security boundary).

Purpose

Drive a coding agent headlessly against real git repos: read a target repo's .roomodes and .roo/rules-<slug>/ files, build a system prompt from mode + rules, call an LLM API (OpenRouter in Phase 1) with the tool schema, execute tool calls via plain fs/child_process (no vscode.* anywhere), and loop until completion. Non-interactive by design.

Quick start

headlesscode is not yet published to the npm registry, so install it from a checkout:

git clone https://github.com/Capsize-Games/headlesscode.git
cd headlesscode
npm install

# Required (except for --dry-run):
export HEADLESSCODE_OPENROUTER_API_KEY=sk-or-...

# Optional:
export OPENROUTER_MODEL=deepseek/deepseek-v4-flash-0731  # default model
export OPENROUTER_HTTP_REFERER=https://example.com       # OpenRouter app header
export OPENROUTER_APP_TITLE="headlesscode"               # OpenRouter X-Title header
export HEADLESSCODE_WORKSPACE_ROOT=/path/to/target/repo  # default workspace root

# Run a task against a target repo, straight from the checkout:
node bin/headlesscode.mjs --task "Fix the bug in src/index.ts" --workspace /path/to/target/repo

Systemwide headlesscode command

To avoid re-typing node <checkout>/bin/headlesscode.mjs from every project, install a headlesscode command onto your PATH once:

scripts/install-cli.sh

This writes a wrapper to ~/.local/bin/headlesscode (override with HEADLESSCODE_BIN_DIR) that runs this checkout's src/cli.ts via its local tsx, without cd-ing — so --repo/--workspace still default to whatever directory you're standing in when you invoke it. Re-run the script any time after git pull to point it at a moved checkout; the wrapper itself doesn't need updating for ordinary code changes.

# from any repo, no HEADLESSCODE_ROOT plumbing needed:
headlesscode orchestrate --repo . --issue 42

The rest of this README uses the plain headlesscode form for brevity — substitute node <checkout>/bin/headlesscode.mjs if you haven't run scripts/install-cli.sh yet.

The --dry-run flow (no API key needed)

--dry-run builds the full system prompt and validates configuration loading without calling the LLM — useful for CI and for checking that a target repo's .roomodes / .roo/rules-<slug>/ / AGENTS.md are picked up:

headlesscode --dry-run --mode code --workspace /path/to/target/repo

It prints the assembled system prompt plus a summary line (mode, custom modes loaded, exposed tools, prompt size). Exit code 0 means prompt building + mode / rules loading succeeded; non-zero means a config error.

Real-usage example against a target repo

export HEADLESSCODE_OPENROUTER_API_KEY=sk-or-...
export HEADLESSCODE_WORKSPACE_ROOT=~/Projects/some-target-repo

# Point the agent at an already-scoped issue, in an isolated worktree:
headlesscode \
  --mode code \
  --task "Implement issue #29: add retry logic to the HTTP client (see .roo/rules for project conventions)." \
  --workspace ~/Projects/some-target-repo \
  --max-iterations 50 \
  --log-file ./headlesscode-session.log

The agent reads files, runs commands, writes code, and finishes by calling attempt_completion (or by giving a final text answer). The final result is printed to stdout. Exit code 0 = success; 1 = task failed (max iterations or consecutive-mistake limit); 2 = usage/config error (e.g. missing HEADLESSCODE_OPENROUTER_API_KEY).

Registering a new project

To use headlesscode against a project that isn't set up as a headlesscode project yet, register it in one step:

headlesscode init --workspace ~/Projects/your-project

This detects the project's stack(s) (which drives per-session instruction selection), makes sure the project's .gitignore excludes .headlesscode/ session artifacts, and builds the codebase-search index and the codemap — no manual index/codemap/.gitignore steps needed. The index step calls the embedding API and costs real money unless you pass --skip-index or --embedding-backend ollama. See headlesscode init --help for the full options.

CLI reference

headlesscode --task "<task text>" [options]
headlesscode --task-file <path> [options]
headlesscode --dry-run [options]
headlesscode orchestrate --repo <path> --issue <n> [--issue <n> ...] [options]
headlesscode watch --owner <o> --repo <path> --label <name> [options]

  --mode <slug>                 Mode to run in (built-in or from .roomodes). Default: code
  --task <text>                 The task description for the agent
  --task-file <path>            Read the task from a file (relative to workspace)
  --workspace <root>            Workspace root (default: $HEADLESSCODE_WORKSPACE_ROOT or cwd)
  --model <id>                  OpenRouter model id (default: $OPENROUTER_MODEL or deepseek/deepseek-v4-flash-0731)
  --max-iterations <n>          Loop iteration cap (default: 50)
  --consecutive-error-limit <n> Consecutive mistakes before giving up (default: 3)
  --max-cost-usd <n>            Phase 6: per-session cost cap in USD (decimal). Default
                                $HEADLESSCODE_MAX_COST_USD; off when neither is set
  --max-duration-ms <n>         Phase 6: per-session wall-clock cap in ms. Default
                                $HEADLESSCODE_MAX_DURATION_MS; off when neither is set.
                                A tripped cap aborts with reason "budget"
  --log-file <path>             Also append structured logs to this file
  --memory-dir <path>           Phase 3 memory: store facts + session summaries under <path>
                                (enabled; default $HEADLESSCODE_MEMORY_DIR or
                                <workspace>/.headlesscode/memory). Memory is OFF unless set.
  --no-memory                   Explicitly disable memory even if HEADLESSCODE_MEMORY_DIR is set
  --allowed-commands <list>  Comma-separated command prefixes the agent may run.
                               Default: $HEADLESSCODE_ALLOWED_COMMANDS, else
                               .headlesscode/permissions.json, else empty (=
                               allow everything except --denied-commands; see
                               SECURITY.md)
  --denied-commands <list>   Comma-separated command prefixes that are ALWAYS
                               refused (deny wins over allow; dangerous shell
                               substitutions are always blocked regardless).
                               Default: $HEADLESSCODE_DENIED_COMMANDS, else
                               .headlesscode/permissions.json, else empty
  --protected-files <list>   Comma-separated glob patterns of files the agent may
                               not write. Default: $HEADLESSCODE_PROTECTED_FILES,
                               else .headlesscode/permissions.json, else
                               ".env,.env.*,*.pem,*.key,id_rsa*"
  --allow-protected-writes   Escape hatch: permit writes to protected files
                               (default: OFF). Also settable via
                               "allowProtectedWrites": true in
                               .headlesscode/permissions.json
  --dry-run                     Build the system prompt + validate config, then exit (no API key)
  --version / --help

orchestrate subcommand (Phase 2 — parallel worktrees, headless workers):
  --repo <path>                 Target repo root (required)
  --issue <n>                   Issue number to include (repeatable)
  --issues-json <file>          Read issues from a JSON array of {number,title,body}
                                (used when gh is unavailable, or for tests)
  --file-issues                 With --issues-json: file a REAL GitHub issue for
                                each synthetic entry (gh issue create --repo
                                <origin-owner>/<origin-repo>), swap in the real
                                number returned, and print one confirmation line
                                per created issue. A real, visible write to
                                GitHub — opt-in, never automatic. Requires
                                --issues-json
  --batch <name>                Batch id in the state file (default round-<date>)
  --review-mode <slug>          Mode slug for review sessions (default deepseek-reviewer)
  --no-review                   Spawn + watch only; skip the reviewer
  --qa                         Phase 4: run a headless QA session (--mode qa-agent)
                                on each group after its review passes; record
                                qa {status,verdict,evidence} in the state file
  --qa-mode <slug>              Mode slug for QA sessions (default qa-agent; the
                                target repo's .roomodes + .roo/rules-<slug>/ are
                                spliced automatically)
  --deploy                      Phase 4: after all groups done + reviewed + QA passed,
                                run the human-approval deploy gate
                                (scripts/deploy-gate.sh) — a hard stop that never runs
                                the repo's deploy-production.sh without explicit human
                                approval (interactive on a TTY, token/file otherwise)
  --deploy-args <str>           Deploy args forwarded to the deploy script after the
                                gate approves (space-separated flags; also DEPLOY_ARGS env)
  --poll-interval-ms <n>        Watcher poll interval (default 5000)
  --max-concurrent-sessions <n> Phase 6 global cap on concurrent sessions across
                                processes (default $HEADLESSCODE_MAX_CONCURRENT_
                                SESSIONS or 3). At/over the cap this run ABORTS
                                with a clear message, exit 1
  --dry-run                     Print the split plan + spawn commands, spawn nothing

watch subcommand (Phase 5 — GitHub issue watcher, poll-based intake):
  --owner <o>                   GitHub owner (required)
  --repo <path>                 Local clone of the target repo (required; worktrees
                                are spawned under <path>/.worktrees/). The GitHub repo
                                name defaults to the directory basename (--gh-repo overrides)
  --label <name>                The label that triggers processing, e.g. needs-agent
  --poll-interval-ms <n>        Sweep interval in continuous mode (default 60000)
  --run-once                    One sweep then exit 0 (or 1 if any spawn failed)
  --max-per-sweep <n>           Max NEW issues spawned per sweep (default 5); the rest
                                stay 'pending' in state and are picked up next sweep
  --max-concurrent-sessions <n> Phase 6 GLOBAL cap on concurrent sessions across
                                processes (default $HEADLESSCODE_MAX_CONCURRENT_
                                SESSIONS or 3). Interplay: maxPerSweep bounds one
                                sweep's burst; this bounds the total fleet — issues
                                beyond it stay 'pending' until slots free up
  --state-file <path>           Durable idempotency state (default
                                <repo>/.worktrees/.watcher-state.json)
  --mode <slug> / --memory-dir <path>
                                Forwarded to the spawner (ORCHESTRATOR_MODE /
                                HEADLESSCODE_MEMORY_DIR)
  --qa / --deploy               Pass-through: recorded per batch for the follow-up
                                orchestrate completion run
  --dry-run                     Sweep + print the spawn plan, spawn nothing, write no
                                state (still needs a GitHub token for listIssues)
  --retry-failed                Retry previously-failed spawns next sweep

Architecture

  • src/llm/openrouter.ts — OpenRouter chat-completions client using native fetch (no axios/node-fetch/openai SDK). Reads HEADLESSCODE_OPENROUTER_API_KEY, optional OPENROUTER_HTTP_REFERER / OPENROUTER_APP_TITLE; model default deepseek/deepseek-v4-flash-0731 (env OPENROUTER_MODEL overrides). Non-2xx → typed OpenRouterError with status + body excerpt; supports AbortSignal timeouts.
  • src/tools/executor.ts — headless executor for read_file, write_to_file, execute_command, list_files (plain fs/child_process), plus attempt_completion / ask_followup_question handlers and "not implemented" stubs for every other vendored tool schema. All file operations are resolved relative to the workspace root and rejected if they escape it (path-traversal guard via path.resolve + containment check). Command results are truncated (~30k chars) to keep context bounded.
  • src/tools/output-summarizer.ts — OPT-IN local summarization of oversized execute_command output: when HEADLESSCODE_LOCAL_SUMMARIZATION=1, a result that would exceed the 30k char cap is compressed by a local Ollama chat model before reaching the cloud model, with a [Output summarized by local model…] transparency header. OFF by default; on any failure it falls back to today's exact blunt truncation (never an error, never a hang). Endpoint/model configurable via HEADLESSCODE_OLLAMA_URL (default http://localhost:11434) and HEADLESSCODE_SUMMARIZATION_MODEL (default qwen3:8b). Deliberately limited to command output — file/diff content always stays verbatim.
  • src/engine/parser.ts — OpenAI function-calling parser: JSON.parses tool_calls[].function.arguments with a best-effort partial-JSON fallback; parse failures are marked and fed back as errors.
  • src/engine/prompt.ts — wraps the vendored SYSTEM_PROMPT builder: loads project .roomodes (same zod schema as Zoo Code's CustomModesManager), passes the workspace as cwd so .roo/rules-* / AGENTS.md splice in, and selects the mode's exposed tools.
  • src/engine/loop.tsHeadlessSession, the orchestration loop. System + user → LLM → assistant (with tool_calls) → parse → execute → tool role message → repeat. Terminates on attempt_completion (its args.result is the final answer) or a text-only reply; fails bounded on max iterations or consecutiveErrorLimit consecutive mistakes (tool errors / parse errors / identical repeated calls). History truncation is a Phase 1 placeholder: system + first user always kept, sliding window of the last ~40 messages. The loop accepts an injected llmClient (DI) so tests use a fake; the CLI wires OpenRouterClient.
  • src/engine/logger.ts — structured logger (timestamped lines to stdout/stderr, optional file).
  • src/memory/ — memory subsystem:
    • src/memory/types.ts — the MemoryFact / SessionSummary schema (per-project scoped, kinds convention|decision|failure|knowledge where "things that didn't work" are failure) and the two contracts: MemoryStore (the pluggable storage boundary) and Embedder. Hard data-isolation requirement documented: the harness knowledge is a dedicated schema, never reachable through any customer tenant route.
    • src/memory/local.tsLocalMemoryStore: the fully working file backend (facts/<project>.jsonl + sessions/<project>.jsonl, append-only, idempotent addFact by content hash, queryRecall = keyword matches (high weight) + local-embedder cosine similarity, deterministic ordering).
    • src/memory/embed.tscreateLocalEmbedder(): zero-dependency, deterministic lexical-hash embedder (lowercase word + char-bigram tokens → fixed-dim L2-normalized vector). Placeholder for a real local embedding model behind the same Embedder interface.
    • src/memory/summarizer.tsextractSessionSummary (deterministic; files/commands derived from the tool history, facts via keyword heuristics) + buildRollingSummary (compact markdown recap of the last N sessions, so a session never needs the infinite raw history).
    • src/memory/uwuchat.ts — a remote MemoryStore implementation stub for a future hosted memory API. Throws "not implemented" until its base-URL/token env vars are set.
    • Memory is wired into HeadlessSession as an opt-in config (memory
      • project); when unset the loop behaves exactly as before. When set, the loop injects a ## PROJECT MEMORY section (recalled facts + rolling recap) into the first user message and records the session + extracted facts afterwards — and memory failures are always non-fatal.
  • src/orchestrator/ — Phase 2 orchestration layer: split.ts (issue-splitting heuristics, deterministic + unit-tested), state.ts (.worktrees/.orchestrator-state.json read/write), reviewer.ts (adversarial fresh-context review run with a read-only executor), watch.ts (completion polling of .harness.done markers + stall guard), and cli.ts (the orchestrate subcommand — split → spawn via scripts/spawn-parallel-worktrees.sh → watch → review → QA → deploy gate).
  • src/qa/qa.ts — Phase 4 headless QA: runQa() runs a second harness session against a worktree in the target repo's qa-agent mode (auto-spliced from .roomodes + .roo/rules-qa-agent/), with a generic checklist fallback when the repo has no such mode. Read + command tools only (no write_to_file) — QA verifies and reports, it never edits. Verdict parsing is fail-closed (pass/fail/error, default fail).
  • src/deploy/gate.ts + src/deploy/gate-cli.ts — Phase 4 human-approval deploy gate: the pure, unit-tested decision function decideApproval (interactive y/N, one-time approval file, or DEPLOY_APPROVAL_TOKEN matching <repo>/.deploy-approval; never auto-approves) plus a thin CLI the bash wrapper calls.
  • src/watcher/ — Phase 5 GitHub issue watcher: github.ts (native-fetch GitHub REST client with label filter, PR filtering, pagination, GITHUB_API_BASE_URL override for tests/mocks), state.ts (durable idempotency state file — write-ahead spawneddone/failed, pending for capped issues, restart-safe), watch.ts (the poll loop: list by label → split → spawn via the existing bash spawner, bounded by maxPerSweep and the Phase 6 global cap), and cli.ts (the watch subcommand — continuous or --run-once, --dry-run, --retry-failed).
  • src/budget/ — Phase 6 guardrails: cost.ts (model pricing table + estimateCost, HEADLESSCODE_PRICING_JSON override, conservative fallback for unlisted models), budget.ts (SessionBudget + BudgetTracker: tick() before each LLM call, record() after with usage tokens, check() snapshot, BudgetExceededError), and concurrency.ts (ConcurrencyLimiter — fail-fast in-process semaphore — plus activeSessionCount reading the durable orchestrator/watcher state files for a cross-process view). Wired into HeadlessSession (budget config, budgetUsage on results), the base CLI (--max-cost-usd / --max-duration-ms), orchestrate (aborts at the cap), the watcher (defers cap-exceeding issues to pending), and run-worker.sh/run-qa.sh (env forwarding).
  • src/cloud/ — Phase 6 ephemeral compute abstraction: the CloudProvider lifecycle interface (spawnWorktreeSessionwaitReadyrunHarnesscollectResultsteardown) with LocalProcessProvider as the current local behavior behind it (reuses spawn-parallel-worktrees.sh + run-worker.sh), so a container/VM-per-issue backend slots in without touching the orchestration layer. A cloud-provider sketch is documented (evaluation only — no live setup; see docs/phase6-cloud.md).
  • src/cli.ts — the headlesscode bin entry (+ orchestrate and watch subcommand dispatch).
  • scripts/run-worker.sh — launches one headless harness worker per worktree (pid, log, exit code, .harness.done marker).
  • scripts/run-qa.sh — Phase 4 QA wrapper mirroring run-worker.sh: launches one harness QA session per worktree (.qa-task.md, .qa.pid, qa.log, .qa.exit, .qa.done/).
  • scripts/deploy-gate.sh — Phase 4 gate wrapper: path safety, deployment summary, interactive + token/file approval, then (and only then) invokes the repo's scripts/deploy-production.sh with forwarded deploy args. Exit 3 = human DENIED (hard stop).
  • scripts/spawn-parallel-worktrees.sh — spawns one git worktree + harness worker per group (worktree/.env/branch conventions, run-worker.sh + state-file writes, no GUI involved).

Phase 1 tool filtering decision

The loop exposes to the model exactly the tools the executor can actually run for the selected mode: the intersection of the vendored mode tool groups (getToolsForMode) with the Phase 1 executable set (read_file, write_to_file, execute_command, list_files, attempt_completion, ask_followup_question). Stub-only tools (apply_diff, search_files, …) stay registered in the executor purely as a safety net (clear "not implemented" error) but are NOT advertised to the model, so it doesn't waste turns calling them.

Development

npm run typecheck     # npx tsc --noEmit (whole repo incl. vendored core)
npm run smoke         # vendored prompt builder smoke test (no network)
npm test              # unit tests with fake LLM clients (no network/key)
bash scripts/e2e/run.sh            # Phase 1 integration (mock OpenRouter)
bash scripts/e2e-phase2/run.sh     # Phase 2 integration (spawn + watch + review)
bash scripts/e2e-phase4/run.sh     # Phase 4 integration (QA + deploy gate, fake deploy)
bash scripts/e2e-phase5/run.sh     # Phase 5 integration (watcher vs fake GitHub server,
                                   #   stubbed spawner: state transitions + no double-spawn)
bash scripts/e2e-phase6/run.sh     # Phase 6 integration (budget abort via mock OpenRouter
                                   #   + concurrency-cap sweep via fake GitHub + stubbed spawner)
npm run cli -- --dry-run --workspace .   # build this repo's system prompt

The engine tests (src/engine/__tests__/loop.test.ts) run the full loop with a fake LlmClient injected via the HeadlessSession constructor — no network, no API key required. Phase 2 adds src/orchestrator/__tests__/ (split heuristics, state round-trip, reviewer verdict parsing), and the e2e scripts drive the real CLI through a local mock OpenRouter server, including a 2-worktree parallel spawn, completion-marker polling, and a read-only review invocation. Phase 5 adds src/watcher/__tests__/ (github client with an injected fetch, watcher-state idempotency semantics, and the watch loop with an injected gh client + spawner covering spawn/idempotency/cap/failure/ dry-run/abort) and scripts/e2e-phase5/run.sh (watcher against a fake GitHub server with a stubbed spawner).

Phase status

  • ✅ Phase 1 Subtask 1 — vendored portable Zoo Code core (src/vendor/zoo-code/, read-only dependency).
  • ✅ Phase 1 Subtask 2 — runtime engine (OpenRouter client, tool executor, parser, orchestration loop, CLI, tests).
  • ✅ Phase 2 — headless orchestration layer: drop-in spawn-parallel-worktrees.sh + run-worker.sh (harness subprocess per worktree, .harness.done completion markers), issue-splitting heuristics port, .orchestrator-state.json state management, headless reviewer, and the orchestrate CLI subcommand (see docs/phase2-orchestration.md).
  • ✅ Phase 3 — memory subsystem: per-project knowledge facts + rolling session summaries (src/memory/), local deterministic embedder for semantic recall, opt-in HeadlessSession/CLI wiring (--memory-dir, --no-memory), and a pluggable MemoryStore contract with a remote-backend client stub.
  • ✅ Phase 4 — QA + deploy gate: headless QA runs the target repo's qa-agent mode (--qa / --qa-mode), verdict parsing is fail-closed, results land in the state file's per-group qa field; the human-approval deploy gate (--deploy, scripts/deploy-gate.sh + src/deploy/gate.ts) is a hard stop in front of deploy-production.sh that never auto-approves (see docs/phase4-qa.md and docs/phase4-deploy-gate.md).
  • ✅ Phase 5 — GitHub issue watcher: poll-based intake (watch subcommand) — detect issues by label via the GitHub REST API (GH_TOKEN), fan each out through splitIssues + the existing spawn-parallel-worktrees.sh, track idempotency durably (.worktrees/.watcher-state.json, write-ahead ordering, pending cap deferral, restart-safe), optional --dry-run / --run-once / --retry-failed; webhook upgrade designed but not built as a server (see docs/phase5-issue-watcher.md).
  • ✅ Phase 6 — cloud scaling, guardrails-first: per-session cost/time/iteration budget (src/budget/, --max-cost-usd / --max-duration-ms, budgetUsage on results, worker env forwarding) + a hard concurrent-session cap (HEADLESSCODE_MAX_CONCURRENT_SESSIONS, orchestrate aborts / watcher defers to pending) + the CloudProvider abstraction with LocalProcessProvider and an evaluation-only cloud-provider sketch (see docs/phase6-cloud.md). No live cloud launched; a container/VM-per-issue backend slots in behind the same interface.
  • ⏳ Phase 3 (remaining) — token-based condensation.

Attribution

This project contains Apache-2.0-licensed code derived from Zoo Code (Zoo-Code-Org/Zoo-Code, commit ca9b60f), itself a Roo Code fork. Prompt text, tool schemas, and mode/rules loading logic are reused under the terms of the Apache License 2.0. See LICENSE and ATTRIBUTION.md.