Simple multi-agent coordination for Claude Code
Orchestra Lite lets you run multiple Claude Code instances in parallel, coordinating through simple markdown files and git branches. No databases, no daemons, no complexity.
- Files ARE the database — Markdown and YAML, human-readable and git-trackable
- Humans trigger agents — You control when work happens, no runaway costs
- Git IS the coordination — Branches prevent conflicts naturally
- Claude does the thinking — You just organize and orchestrate
curl -sL https://raw.githubusercontent.com/sgharlow/orchestra-lite/master/init-orchestra.sh | bash
# Or download and run: bash init-orchestra.shWindows (Git Bash/MSYS2): Use source init-orchestra.sh instead of bash init-orchestra.sh.
nano .orchestra/GOAL.mdWrite what you're building, acceptance criteria, and scope.
claude
> /orchestra planClaude will break down your goal into tasks with dependencies.
claude
> /orchestra workClaude claims the next available task, does the work, and marks it complete.
claude
> /orchestra workAnother worker claims a different task. Git branches prevent conflicts.
> /orchestra status
Your identity is determined by your current git branch.
| Current Branch | Your Status |
|---|---|
main |
Not assigned to any task |
task/XXX |
You own task XXX |
Check your identity: git branch --show-current
This means:
- No need for worker IDs or registration
/orchestra continueknows which task is yours by checking your branch- If a branch exists, that task is claimed
| Command | Description |
|---|---|
/orchestra plan |
Create tasks from GOAL.md (safe to re-run) |
/orchestra status |
Show progress, ready tasks, blockers |
/orchestra work |
Claim and complete next ready task |
/orchestra work ID |
Claim specific task |
/orchestra done ID |
Mark task complete, unblock dependents |
/orchestra stuck ID |
Mark blocked, preserve branch for later |
/orchestra drop ID |
Unclaim task, discard code changes |
/orchestra continue |
Resume your in-progress task |
/orchestra replan |
Re-evaluate remaining work |
/orchestra split ID |
Break task into subtasks (003 → 003a, 003b) |
/orchestra context |
Show recent decisions and patterns |
/orchestra decide |
Log an architectural decision |
Shortcut: /o works the same as /orchestra
project/
├── .orchestra/
│ ├── GOAL.md # What you're building
│ ├── PLAN.md # High-level phases
│ ├── TASKS.md # Task board (the "kanban")
│ ├── DECISIONS.md # Architectural decisions log
│ ├── config.yaml # Settings (test command, etc.)
│ ├── tasks/ # Active task files
│ │ ├── 001-design-schema.md
│ │ └── 002-implement-auth.md
│ └── done/ # Completed and split task files
│ └── 000-setup.md
│
├── .claude/commands/
│ ├── orchestra.md # Main command definition
│ └── o.md # Shortcut
│
└── CLAUDE.md # Project context (includes Orchestra docs)
# Tasks
> Last updated: 2025-01-16 14:30
> Progress: 2/8 complete (25%)
## Ready
- [ ] `003` Create login endpoint
- [ ] `004` Create registration endpoint
## In Progress
- [ ] `005` Implement token refresh (task/005)
## Done
- [x] `001` Design user database schema ✓
- [x] `002` Implement password hashing utilities ✓
## Blocked
- [ ] `006` Create password reset flow (waiting: 003, 004)
- [ ] `009` External API integration (blocked: waiting for API keys)Format notes:
- Ready:
- [ ] \ID` Task name` - In Progress:
- [ ] \ID` Task name (task/ID)` - Done:
- [x] \ID` Task name ✓` - Blocked by dependencies:
(waiting: 001, 002) - Blocked by external issue:
(blocked: reason)
┌─────────────────────────────────────┐
│ │
▼ │
┌─────────┐ ┌─────────────┐ ┌──────┐ │
│ ready │ ───► │ in_progress │ ───► │ done │ │
└─────────┘ └─────────────┘ └──────┘ │
▲ │ │
│ ▼ │
│ ┌─────────┐ │
└────────── │ blocked │ ──────────────────────┘
└─────────┘
(when unblocked)
Additional states:
split— Task was broken into subtasks (moved to done/)
┌─────────────────────────────────────────────────────────────────┐
│ Your Project │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Terminal 1 (Planning) Terminal 2 (Worker) Terminal 3 │
│ ┌──────────────────┐ ┌──────────────────┐ ┌────────────┐ │
│ │ > /orchestra plan│ │ > /orchestra work│ │ > /o work │ │
│ │ │ │ │ │ │ │
│ │ Created 8 tasks │ │ Claimed task 001 │ │ Claimed 002│ │
│ │ 5 ready, 3 block │ │ Working... │ │ Working... │ │
│ │ │ │ │ │ │ │
│ │ > /o status │ │ > /o done 001 │ │ > /o done │ │
│ │ │ │ ✓ Complete │ │ ✓ Complete │ │
│ │ 2/8 complete │ │ Unblocked: 003 │ │ │ │
│ └──────────────────┘ └──────────────────┘ └────────────┘ │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ .orchestra/TASKS.md │ │
│ │ (shared state, updated by all agents) │ │
│ └──────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
-
Each task = own git branch
git checkout -b task/001 # Worker 1 git checkout -b task/002 # Worker 2 (different branch)
-
Branch existence = claim check
- Before claiming, check if
task/XXXbranch exists - If it exists, task is already claimed — pick another
- Before claiming, check if
-
Tasks are scoped to specific files
- Task 001 works on
src/db/schema.ts - Task 002 works on
src/services/auth.ts - No overlap
- Task 001 works on
-
Dependencies enforce ordering
- Task 003 depends on 001 → Can't start until 001 merges
- Merge conflicts resolved before dependent work begins
-
Human resolves edge cases
- If conflict occurs, human resolves during merge
- Clear ownership via branch names
# Task 001: Design User Schema
## Metadata
| Field | Value |
|-------|-------|
| **ID** | 001 |
| **Status** | ready |
| **Branch** | task/001 |
| **Assigned** | task/001 |
| **Depends** | none |
| **Blocked-By** | |
| **Estimated** | 45 min |
## Inputs
- [Files from dependencies]
## Description
[What needs to be done]
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
## Context Files
- [Files to read before starting]
## Outputs
[Filled when complete]
---
## Work Log
[Appended during work]Marks a task as blocked by an external issue.
- Branch is preserved (not deleted)
- Partial work is committed before returning to main
- To resume later:
git checkout task/[ID] /orchestra continue
Unclaims a task without completing it.
- Code changes are discarded (or stashed)
- Task returns to Ready state
- Branch is deleted
- State change committed on main
Breaks a large task into smaller subtasks.
- Creates new IDs:
003a,003b,003c - Subtasks inherit original's dependencies
- Tasks that depended on original now depend on ALL subtasks
- Original marked as "split" and moved to done/
Every significant decision gets logged in DECISIONS.md:
### DEC-001: Password Hashing Algorithm
**Date:** 2025-01-16
**Task:** 001
**Status:** Decided
**Context:**
Need to select a password hashing algorithm.
**Decision:** Use bcrypt with cost factor 12
**Rationale:** Industry standard, good security/performance balance
**Alternatives Considered:**
- Argon2: Less library support
- PBKDF2: Older, less GPU-resistantThis ensures all agents share context about why things are built the way they are.
.orchestra/config.yaml:
project: "My Project"
test_command: "npm test" # Run during /orchestra done (optional)
git:
main_branch: "main"
auto_push: true
default_estimate: 60 # minutesNote: If test_command is not defined, tests are skipped with a warning.
- Keep tasks small (30-60 minutes)
- Make acceptance criteria specific and verifiable
- Identify dependencies explicitly
- Re-run
/orchestra planas you learn more
- Always load context first (DECISIONS.md, dependency outputs)
- Update work log as you go
- Commit incrementally
- Run tests before marking done
- Check
/orchestra statusfrequently - Use
/orchestra stuckearly if blocked (branch preserved!) - Document decisions immediately
| Feature | Status | Reason |
|---|---|---|
| Autonomous loops | No | Human control, no runaway costs |
| Database | No | Files are simpler, git-trackable |
| Web dashboard | No | TASKS.md is the dashboard |
| Cost tracking | No | Use Anthropic dashboard |
| Auto-retry | No | Human decides on failures |
| Real-time sync | No | Pull-based via git |
- Check if all tasks are blocked or done
- Run
/orchestra statusto see the full state - Run
/orchestra planif more work is needed
Run /orchestra done [dep-id] again — it auto-unblocks dependents by reading all task files.
git checkout main
git pull
git merge task/XXX
# Resolve conflicts manually
git add . && git commit
git push # if auto_push enabled> /orchestra continue
Detects your task from current branch, or shows in-progress tasks if on main.
> /orchestra split [task-id]
Breaks it into subtasks (003 → 003a, 003b, 003c).
> /orchestra drop [task-id]
Returns task to Ready, discards your code changes.
> /orchestra stuck [task-id] "waiting for API keys"
Preserves your branch so you can resume later with /orchestra continue.
See mdlink-check — A complete CLI tool built using Orchestra Lite, showing the full workflow from planning through 5 completed tasks.
See the examples/ directory:
GOAL-auth-example.md— A filled-out goal for user authenticationTASKS-example.md— Task board with various statestask-001-example.md— Completed task showing proper formatDECISIONS-example.md— Several architectural decisions
MIT — Use freely in your projects.