Local coding-agent orchestrator — DAG of auto-approved, git-worktree-isolated sub-sessions across LLM providers (Claude/Kimi/Grok/DeepSeek/local). AGPL-3.0.
sidekick
A local coding-agent orchestrator. Give it a high-level task and it:
- decomposes the task into a DAG of subtasks,
- fans out one auto-approved, headless Claude Code session per subtask, each isolated
- shows live progress — both a terminal
richtable and a liveprogress.md
- runs each subtask's acceptance checks (retrying once on failure),
- merges the green branches and opens the changed files in VSCode,
- reports a table of measurable speed/accuracy objectives.
It is built fully autonomously after a single plan approval, and re-prompts only on significant deviations.
Design lineage
| Source | What sidekick takes from it | |--------|---------------------------| | Nous Hermes-Agent | skills/memory learning loop, pluggable execution backend (git worktrees here), isolated subagent delegation for parallel workstreams | | Raschka, "The Six Components of a Coding Agent" | (1) live repo context, (2) cache-shaped prompts, (3) bounded/structured tool use, (4) context-bloat control, (5) structured session memory, (6) bounded subagent delegation |
Component map
| Module | Role | Lineage | |--------|------|---------| |repo_context.py | workspace summary (branch, tree, docs) | Raschka #1 |
| prompts/ | stable system prefix + dynamic suffix for cache reuse | Raschka #2 |
| agent_session.py + approval.py | headless claude -p wrapper, auto-approval policy | Raschka #3 |
| context_budget.py | output clipping + tiered transcript reduction | Raschka #4 |
| memory.py | transcript + working memory as JSON on disk | Raschka #5 |
| orchestrator.py | DAG waves, bounded parallel agents, merge | Raschka #6 / Hermes |
| worktree.py | git worktree+branch per agent | Hermes backend |
| skills.py | distill + recall reusable skills | Hermes learning loop |
| dashboard.py | live rich table + live progress.md | — |
| vscode.py | open progress doc + changed files in VSCode | — |
| metrics.py | objective computation + gate | OBJECTIVES.md |
How auto-approval works
sidekick drives the Claude Code native binary ($CLAUDECODEEXECPATH) in headless mode:
claude -p "<prompt>" --output-format stream-json --verbose \
--permission-mode acceptEdits \
--allowedTools "Edit Write Read Grep Glob Bash(uv ) Bash(pytest ) …" \
--session-id <uuid> --max-turns N
acceptEdits + an explicit --allowedTools allowlist auto-approves edits and a scoped set of build/test/lint/vcs commands while still refusing unlisted or dangerous operations — zero human prompts (objective S4 = 0), without an open shell grant. Each session runs inside its own worktree, so parallel agents never collide.
Three approval levels (--approval): accepteditsallowlist (default), bypass (--allow-dangerously-skip-permissions), editsnobash.
Showing progress in VSCode
The spawned agents are headless Claude Code subprocesses — that is what makes auto-approval and parallel fan-out possible, and it means they do not appear as interactive sessions in the VSCode sidebar (that sidebar session is the one you use to drive sidekick). Progress is surfaced in the editor instead:
- The dashboard writes a live
progress.md(.sidekick/runs/<id>/progress.md) — a
code -r; VSCode auto-reloads the tab on every
update, so you watch the whole fan-out from one editor pane.
- On completion, the changed files of each accepted subtask are opened for review.
- Detection is automatic (the
codeCLI on PATH); force with--vscode/--no-vscode
SIDEKICK_VSCODE=1|0. The same progress.md works in any editor or tail.
You can run sidekick from VSCode's integrated terminal (or its Claude Code extension terminal) and keep progress.md open beside it.
Make sidekick your default coding workflow in VSCode
First, put sidekick on PATH so VSCode tasks and terminals can call it:
cd /path/to/sidekick && uv tool install --editable . # or: pipx install -e .
The one limitation: the Claude Code **sidebar session cannot be transparently rerouted** through sidekick — the extension runs the agent in-process and exposes no reroute hook, so nothing can sit invisibly underneath it. sidekick drives headless agents; you keep using the sidebar to drive sidekick. With that understood, there are three usage patterns:
Pattern A — auto-launch sidekick repl on folder open (the "default workflow")
Copy examples/vscode/tasks.json → .vscode/tasks.json in
any repo. Opening the folder auto-starts sidekick repl in a dedicated terminal (VSCode
asks once to "Allow Automatic Tasks"). Then, every time:
sidekick> add input validation to the upload handler
→ sidekick plans → fans out auto-approved agents on worktrees → merges green branches, with
progress.md live in an editor tab beside you. This is the closest thing to "VSCode always
runs through sidekick."
Pattern B — drive sidekick from the sidebar session
Use the interactive Claude Code sidebar normally; when a task wants parallel fan-out, tell it to run sidekick, e.g. "runsidekick run "refactor X across these 4 modules" --yes". The
sidebar stays your control surface; sidekick owns the parallel execution and reports back via
progress.md + opened diffs.
Pattern C — terminal one-liners / hotkey
- Integrated-terminal alias (add to
~/.bashrc):
cc() { sidekick run "$@" --yes; } # then: cc "add unit tests for parser.py"
Recursion-safe — sidekick invokes the Claude binary by its absolute $CLAUDECODEEXECPATH,
never the shell claude.
- Hotkey:
examples/vscode/keybindings.jsonbinds
Ctrl+Alt+L to a "run task" prompt (uses the second task in tasks.json).
What you see in the editor
| Surface | When | Where | |---------|------|-------| | Liveprogress.md (per-agent table) | during the run | editor tab, auto-reloads |
| rich dashboard | during the run | the sidekick terminal |
| Changed files of each accepted subtask | on completion | opened for review |
| Objective table (S1–S4 / A1–A4 / E1–E2) | on completion | the sidekick terminal |
Toggle the editor integration with --vscode / --no-vscode or SIDEKICK_VSCODE=1|0 (auto-detected from the code CLI). A per-agent VSCode window on each worktree is not opened by default — set it up with a code <worktree> step if you want one window per agent.
Voice input
Speak a task instead of typing it — works in the VSCode integrated terminal (it uses the OS mic via ffmpeg/arecord, which the terminal process can access).
sidekick voice # press Enter, speak, sidekick plans → fans out → merges
sidekick voice --transcribe-only # just print what it heard
sidekick repl --voice # voice-driven interactive loop (great for the VSCode task)
Speech-to-text goes through an OpenAI-compatible /audio/transcriptions endpoint, so it is provider-independent from the coding model (shared by the claude, kimi, … branches):
| Var | Default | |-----|---------| | SIDEKICKSTTBASEURL | $OPENAIBASE_URL or https://api.openai.com/v1 | | SIDEKICKSTTAPIKEY | $OPENAIAPI_KEY | | SIDEKICKSTTMODEL | whisper-1 | | SIDEKICKAUDIOINPUT | auto (pulse:default / alsa:default) | | SIDEKICKAUDIOSECONDS | 8 |
Requires ffmpeg or arecord plus an STT key; degrades gracefully with a clear message if either is missing.
Usage
just setup # uv venv + editable install
sidekick plan "add input validation" # see the subtask DAG
sidekick run "add input validation" --yes # fan out, auto-approve, merge, report
sidekick repl # interactive task loop (VSCode auto-launch)
sidekick voice # speak a task; sidekick runs it
sidekick repl --voice # voice-driven loop
sidekick metrics # objective table from .sidekick/metrics.jsonl
sidekick status # last run's working memory
sidekick bench # serial baseline vs orchestrated (proves S2)
sidekick run "..." --vscode # force-open progress + diffs in VSCode sidekick run "..." --no-vscode # terminal dashboard only sidekick run "..." --concurrency 5 # wider fan-out
Run sidekick from inside the target git repository (changes are made to that repo's branches and merged into its current branch).
Measurable objectives
See OBJECTIVES.md. sidekick bench and sidekick metrics compute S1–S4 (speed), A1–A4 (accuracy), E1–E2 (efficiency) from metrics.jsonl. Every optimization (prompt shape, context budget, concurrency, approval policy) is judged by its effect on this table.
Requirements
- Claude Code native binary on PATH or
$CLAUDECODEEXECPATH(set inside Claude Code). git, Python ≥ 3.12.rich(declared dep) for the live dashboard.- Auth via the running Claude Code session's credentials (or
ANTHROPICAPIKEY). - Optional: the VSCode
codeCLI for the in-editor progress doc + diffs (auto-detected;
Delegation from another Claude Code session
sidekick can be invoked from inside another Claude Code session so the parent session never spends its own context on the work. Two pieces:
- Install once, globally:
uv tool install /mnt/backup/projects/sidekick
This puts sidekick on PATH for every shell — every Claude Code session (current or future) can shell out to it.
- The user-level skill at
~/.claude/skills/delegate-to-sidekick/SKILL.md
examples/delegate-to-sidekick.SKILL.md for the
canonical copy) tells any Claude Code session how + when to invoke. The
skill is auto-discovered by Claude Code; the session sees
delegate-to-sidekick in its available-skills list and can invoke it via
the Skill tool.
The contract is one command:
sidekick --repo /abs/path/to/repo run "<task>" --json --no-vscode
--json emits a single envelope on stdout (schema documented in the SKILL.md); --no-vscode keeps the live progress doc from popping a window into the parent session's IDE. The envelope carries ok, naccepted/ntotal, n_merged, per-subtask branch, and the last 2 KB of every acceptance check's transcript — enough for the parent session to summarize and decide whether to follow up.
The SKILL.md hard rules cover the gotchas (--repo must be absolute, never shell out to uv run sidekick from inside the source tree, etc).
To upgrade the global install after pulling new changes on this branch:
uv tool install --reinstall /mnt/backup/projects/sidekick