A Go CLI tool that orchestrates Claude Code to process issues, creating PRs for each.
The following CLI tools must be installed and available in your PATH:
| Tool | Purpose | Installation |
|---|---|---|
bd |
Beads issue tracking | curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash |
claude |
Claude Code CLI | docs.anthropic.com/claude-code |
gh |
GitHub CLI | cli.github.com |
git |
Version control | Usually pre-installed |
zellij |
Terminal multiplexer | zellij.dev |
go install github.com/newhook/co@latestgit clone https://github.com/newhook/co.git
cd co
go build -o co .
mv co /usr/local/bin/co --helpClaude Orchestrator uses a project-based model with a 3-tier hierarchy: Work → Tasks → Beads
<project-dir>/
├── .co/
│ ├── config.toml # Project configuration
│ └── tracking.db # SQLite coordination database
├── main/ # Symlink to local repo OR clone from GitHub
│ └── .beads/ # Beads issue tracker (in repo)
├── w-8xa/ # Work unit directory
│ └── tree/ # Git worktree for feature branch
├── w-3kp/ # Another work unit
│ └── tree/ # Git worktree for its feature branch
└── ...
- Work: A feature branch with its own worktree, groups related tasks (ID:
w-8xa) - Tasks: Units of Claude execution within a work (ID:
w-8xa.1,w-8xa.2) - Beads: Individual issues from the beads tracker (ID:
ac-pjw)
From a local repository:
co proj create ~/myproject ~/path/to/repoFrom a GitHub repository:
co proj create ~/myproject https://github.com/user/repoThis creates the project structure with main/ pointing to your repository.
Project creation also:
- Initializes beads:
bd initandbd hooks install - If mise enabled (
.mise.tomlor.tool-versions): runsmise trust,mise install - If mise
setuptask defined: runsmise run setup(use for npm/pnpm install)
| Command | Description |
|---|---|
co proj create <dir> <repo> |
Create a new project (local path or GitHub URL) |
co proj destroy [--force] |
Remove project and all worktrees |
co proj status |
Show project info, worktrees, and task status |
The .co/config.toml file stores project settings:
[project]
name = "my-project"
created_at = 2024-01-15T10:00:00-05:00
[repo]
type = "github" # or "local"
source = "https://github.com/user/repo"
path = "main"
[hooks]
# Environment variables set when spawning Claude
# Supports variable expansion (e.g., $PATH)
env = [
"CLAUDE_CODE_USE_VERTEX=1",
"CLOUD_ML_REGION=us-east5",
"MY_VAR=value"
]
[linear]
# Linear API key for importing issues
# Can also be set via LINEAR_API_KEY environment variable
api_key = "lin_api_..."
[claude]
# Whether to run Claude with --dangerously-skip-permissions flag.
# Defaults to true when not specified.
skip_permissions = true
# Maximum minutes for a Claude session (0 = no limit).
# When set, tasks that exceed this limit will be marked as failed.
time_limit = 30
# Maximum execution time for a task in minutes.
# Defaults to 60 minutes when not specified.
# If time_limit is set and is less than task_timeout_minutes, time_limit takes precedence.
task_timeout_minutes = 60
[workflow]
# Maximum number of review/fix cycles before proceeding to PR.
# Defaults to 2 when not specified.
max_review_iterations = 2
[scheduler]
# Interval between PR feedback checks in minutes.
# Can also be set via CO_PR_FEEDBACK_INTERVAL_MINUTES environment variable.
# Defaults to 5 minutes when not specified.
pr_feedback_interval_minutes = 5
# Interval between comment resolution checks in minutes.
# Can also be set via CO_COMMENT_RESOLUTION_INTERVAL_MINUTES environment variable.
# Defaults to 5 minutes when not specified.
comment_resolution_interval_minutes = 5
# Scheduler polling interval in seconds.
# Can also be set via CO_SCHEDULER_POLL_SECONDS environment variable.
# Defaults to 1 second when not specified.
scheduler_poll_seconds = 1
# Interval for updating task activity timestamps in seconds.
# Can also be set via CO_ACTIVITY_UPDATE_SECONDS environment variable.
# Defaults to 30 seconds when not specified.
activity_update_seconds = 30[hooks]
The hooks.env setting is useful for:
- Configuring Claude Code to use Vertex AI
- Setting custom PATH for tools
- Any environment variables Claude needs
[linear]
The linear.api_key setting provides authentication for Linear integration. This is used by co linear import to fetch issues from Linear. The API key can alternatively be set via the LINEAR_API_KEY environment variable.
[claude]
-
skip_permissions: Controls whether Claude runs with--dangerously-skip-permissions. This flag allows Claude to execute commands without prompting for confirmation. Set tofalseif you want Claude to prompt for permission before running commands. Defaults totrue. -
time_limit: The maximum duration in minutes for a Claude session. When a task exceeds this limit, it is automatically terminated and marked as failed with a timeout error. This is useful for preventing runaway sessions. Set to0or omit to disable the time limit. -
task_timeout_minutes: The maximum execution time for a task in minutes. Defaults to 60 minutes. Iftime_limitis set and is less thantask_timeout_minutes,time_limittakes precedence.
[workflow]
The max_review_iterations setting limits the number of review/fix cycles in automated workflows. The default is 2 iterations. Increase this value if you want Claude to perform more review passes, or decrease it to limit iteration time.
[scheduler]
The scheduler section controls timing for background operations during orchestration:
pr_feedback_interval_minutes: How often to check for new PR feedback (CI failures, review comments). Defaults to 5 minutes.comment_resolution_interval_minutes: How often to check for resolved feedback that needs GitHub comment updates. Defaults to 5 minutes.scheduler_poll_seconds: Internal scheduler polling frequency. Defaults to 1 second.activity_update_seconds: How often to update task activity timestamps. Defaults to 30 seconds.
All scheduler settings can be overridden via environment variables (e.g., CO_PR_FEEDBACK_INTERVAL_MINUTES).
All commands must be run from within a project directory (or subdirectory).
# Create a project
co proj create ~/myproject https://github.com/user/repo
cd ~/myproject
# Create a work unit from a bead (generates branch from bead title)
co work create bead-1
# → Creates w-8xa/tree/ worktree with the bead
# Execute work
cd w-8xa
co run # Execute tasks sequentially
co run --plan # Use LLM to group beads intelligentlyClaude Orchestrator uses a two-phase workflow: work → run.
co work create bead-1 # Create work with a single bead (or epic)This creates:
- A work directory (
w-abc/) - A git worktree with a generated branch (
w-abc/tree/) - A unique work ID using content-based hashing
If the bead is an epic, all child beads are automatically included. Transitive dependencies are also included.
The branch name is generated from bead titles and you're prompted for confirmation.
co run # Execute all pending tasks in current work
co run --work w-abc # Execute all tasks in work w-abcTasks within a work are executed sequentially in the work's worktree.
Run command options:
--plan: Use LLM complexity estimation to auto-group beads into tasks--auto: Full automated workflow (implement, review/fix loop, PR creation)
| Command | Description |
|---|---|
co work create <bead-args...> |
Create a new work unit with beads (generates branch from titles) |
co work add <bead-args...> |
Add beads to existing work |
co work remove <bead-ids...> |
Remove beads from existing work |
co work list |
List all work units with their status |
co work show [<id>] |
Show detailed work information (current directory or specified) |
co work pr [<id>] |
Create a PR task for Claude to generate pull request |
co work review [<id>] |
Create a review task to examine code changes |
co work feedback [<id>] |
Process PR feedback and create beads from actionable items |
co work destroy <id> |
Delete work unit and all associated data |
| Flag | Description |
|---|---|
--base |
Specify base branch (default: main) |
--auto |
Full automated workflow (implement, review/fix loop, PR) |
| Flag | Short | Description |
|---|---|---|
--limit |
-n |
Maximum number of tasks to process (0 = unlimited) |
--dry-run |
Show execution plan without running | |
--plan |
Use LLM complexity estimation to auto-group beads | |
--auto |
Full automated workflow (implement, review/fix loop, PR) | |
--project |
Specify project directory (default: auto-detect from cwd) | |
--work |
Specify work ID (default: auto-detect from current directory) |
# 1. Create a work unit from a bead
co work create bead-1
# Output: Generated work ID: w-8xa (from branch: feat/implement-feature-x)
# 2. Navigate to the work directory
cd w-8xa
# 3. Execute tasks
co run # Each bead becomes its own task
co run --plan # Or use LLM to group beads intelligently
# 4. Create PR (Claude generates comprehensive description)
co work pr
co run # Execute the PR task
# 5. Review and merge PR manually
gh pr merge --squash
# 6. Clean up
co work destroy w-8xaEach work has its own feature branch, and all tasks within the work are executed sequentially in the work's worktree.
Use --auto for a fully automated workflow:
co work create bead-1 bead-2 --autoThis mode:
- Creates work unit and tasks from beads
- Executes all implementation tasks
- Runs review/fix loop until code is clean (default max 2 iterations, configurable)
- Creates PR automatically
- Returns PR URL when complete
Claude Orchestrator automatically monitors and integrates feedback from GitHub Pull Requests:
During orchestration, the system automatically:
- Polls PR feedback every 5 minutes when a work has an associated PR
- Creates beads from actionable feedback items (failed checks, test failures, review comments)
- Adds new beads to the work for immediate execution
- Resolves GitHub comments when feedback beads are closed
You can manually trigger PR feedback polling:
# From work directory (auto-detects work)
co work feedback
# With explicit work ID
co work feedback w-8xa
# Options
co work feedback --dry-run # Preview what beads would be created
co work feedback --auto-add # Automatically add beads to work
co work feedback --min-priority 2 # Set minimum priority (0-4)The feedback system processes:
- CI/Build Failures: Failed status checks and workflow runs
- Test Failures: Extracts specific test failures from logs
- Lint Errors: Code style and quality issues
- Review Comments: Actionable feedback from code reviews
- Security Issues: Vulnerabilities and security concerns
Each feedback item creates a bead under the work's root issue, allowing Claude to address the feedback in subsequent tasks.
The TUI (co tui) provides a manual trigger button (F5) to poll PR feedback on-demand, with visual feedback showing the polling status.
Task dependencies are derived automatically from bead dependencies:
- If bead A depends on bead B, and they're in different tasks, task(A) depends on task(B)
co runexecutes tasks in the correct dependency order- Cycles are detected and reported as errors
Manage tasks with the co task command:
co task list # List all tasks
co task list --status pending # List pending tasks
co task list --type estimate # List estimation tasks
co task show <task-id> # Show detailed task information
co task delete <task-id> # Delete a task from database
co task reset <task-id> # Reset failed/stuck task to pending
co task set-review-epic <epic> # Associate review epic with review taskWhen a task fails:
- The task is automatically marked as failed in the database
- Claude can signal failure using
co complete <task-id> --error "message" - To retry a failed task:
co task reset <task-id> # Reset task status to pending co run # Retry the task
- On retry, Claude only processes incomplete beads (already completed beads are skipped)
CO uses a hierarchical ID system:
-
Work IDs: Content-based hash (e.g.,
w-8xa)- Generated from branch name + project + timestamp
- 3-8 character base36 hash
- Collision-resistant with automatic lengthening
-
Task IDs: Hierarchical format (e.g.,
w-8xa.1,w-8xa.2)- Format:
<work-id>.<sequence> - Sequential numbering within each work
- Shows clear task ownership
- Format:
-
Bead IDs: Managed by beads system (e.g.,
ac-pjw)- Project-specific prefixes
- Content-based hashing similar to works
| Command | Description |
|---|---|
co tui |
Interactive TUI for managing works and beads (lazygit-style) |
co poll [work-id|task-id] |
Monitor work/task progress with text output |
The TUI (co tui) provides a full management interface with:
- Three-panel drill-down: Beads → Works → Tasks
- Create/destroy works, run tasks
- Bead filtering (ready/open/closed), search, multi-select. "Open" includes all non-closed statuses.
- Keyboard shortcuts for all operations (press
?for help)
The poll command (co poll) provides simple text-based monitoring:
- Use
--intervalto set polling interval (default: 2s) - Useful for scripting or when you don't need interactive features
| Command | Description |
|---|---|
co status [bead-id] |
Show tracking status for beads |
co list [-s status] |
List tracked beads with optional status filter |
co sync |
Pull from upstream in all repositories |
co complete <bead-id> [--pr URL] [--error "message"] |
Mark a bead/task as completed or failed (called by Claude) |
co estimate <bead-id> --score N --tokens N |
Report complexity estimate for a bead (called by Claude during estimation) |
Import issues from Linear into the beads issue tracker:
# Import single issue by ID or URL
co linear import ENG-123
co linear import https://linear.app/company/issue/ENG-123/title
# Import multiple issues
co linear import ENG-123 ENG-124 ENG-125
# Import with dependencies (blocking issues)
co linear import ENG-123 --create-deps --max-dep-depth=2
# Update existing bead from Linear
co linear import ENG-123 --update
# Preview without creating
co linear import ENG-123 --dry-run| Flag | Description |
|---|---|
--api-key |
Linear API key (or use LINEAR_API_KEY env var or config.toml) |
--create-deps |
Import blocking issues as dependencies |
--max-dep-depth |
Maximum depth for dependency import (default: 1) |
--update |
Update existing beads if already imported |
--dry-run |
Preview import without creating beads |
--status-filter |
Only import issues matching status |
--priority-filter |
Only import issues matching priority |
--assignee-filter |
Only import issues matching assignee |
Linear metadata (ID, URL, assignee, labels) is preserved in the imported bead.
Claude Orchestrator uses a two-phase workflow with the Work → Tasks → Beads hierarchy:
┌─────────────────────────────────────────────────────────────────┐
│ co work create │
├─────────────────────────────────────────────────────────────────┤
│ 1. Parse bead argument │
│ 2. Expand epics to include all child beads │
│ 3. Include transitive dependencies │
│ 4. Generate branch name from bead titles (prompt for confirm) │
│ 5. Generate unique work ID using content-based hashing │
│ 6. Create work directory: <project>/<work-id>/ │
│ 7. Create git worktree: <work-id>/tree/ │
│ └─ git worktree add tree -b <branch-name> │
│ 8. Create zellij tab for the work │
│ 9. Push branch and set upstream │
│ 10. Store work in tracking database │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ co run │
├─────────────────────────────────────────────────────────────────┤
│ 1. Load work and its pending tasks from database │
│ 2. (Optional with --plan) Estimate complexity and regroup │
│ 3. Execute tasks sequentially in the work's worktree: │
│ │ │
│ ├─ For each task: │
│ │ ├─ Check for uncommitted changes: │
│ │ │ • If related to task beads: complete implementation │
│ │ │ • If unrelated: stash with descriptive message │
│ │ │ • Fail-fast if can't handle cleanly │
│ │ │ │
│ │ ├─ Run Claude Code in work's zellij tab │
│ │ │ └─ zellij run -- claude --dangerously-skip-permissions│
│ │ │ Claude receives prompt and autonomously: │
│ │ │ • Implements all beads in the task │
│ │ │ • Commits after each bead completion │
│ │ │ • Pushes commits to remote immediately │
│ │ │ • Closes beads (bd close <id> --reason "...") │
│ │ │ • Signals completion (co complete <id>) │
│ │ │ • Or signals failure (co complete <id> --error) │
│ │ │ │
│ │ └─ Manager polls database for completion │
│ │ │
│ 4. After all tasks complete: │
│ ├─ Mark work as completed │
│ └─ (With --auto) Run review/fix loop, then create PR │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ co work pr │
├─────────────────────────────────────────────────────────────────┤
│ 1. Check work is completed and no PR exists │
│ 2. Create special PR task (w-abc.pr) │
│ 3. User runs: co run │
│ 4. Claude analyzes all changes and completed work: │
│ ├─ Reviews git log and diff │
│ ├─ Summarizes completed tasks and beads │
│ ├─ Generates comprehensive PR description │
│ ├─ Creates PR using gh pr create │
│ └─ Returns PR URL (does NOT auto-merge) │
│ 5. User reviews and merges PR manually │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ co work review │
├─────────────────────────────────────────────────────────────────┤
│ 1. Create review task (w-abc.review-1, w-abc.review-2, etc.) │
│ 2. Claude examines the work's branch for: │
│ ├─ Code quality issues │
│ ├─ Security vulnerabilities │
│ └─ Potential bugs │
│ 3. Creates beads for issues found (attached to review epic) │
│ 4. (With --auto) Loops: review → fix → review until clean │
└─────────────────────────────────────────────────────────────────┘
- Three-tier hierarchy: Work → Tasks → Beads provides clear organization
- Work-based isolation: Each work has its own worktree and feature branch
- Content-based IDs: Works use hash-based IDs (w-abc), tasks use hierarchical IDs (w-abc.1)
- Two-phase workflow: Work creation and execution are separate phases
- Sequential task execution: Tasks within a work run sequentially in the same worktree
- Project isolation: Each project has its own tracking database in
.co/ - Claude handles implementation: Claude autonomously implements, commits, and closes beads
- Zellij for terminal management: Each work gets its own tab in the project's zellij session
- Database polling: Manager polls SQLite database for completion signals from Claude
- Fail-fast for uncommitted changes: Tasks verify clean working tree and handle partial work appropriately
- Continuous integration: Each bead completion is committed and pushed immediately to prevent work loss
- Intelligent retries: Failed tasks can be reset and retried, with Claude skipping already-completed beads
- Error signaling: Claude can explicitly mark tasks as failed with error messages for better debugging
- Automated reviews: Review tasks can find issues and create fix beads automatically
co/
├── main.go # CLI entry point
├── cmd/
│ ├── root.go # Root command
│ ├── complete.go # Complete command (mark beads/tasks as done)
│ ├── estimate.go # Estimate command (report complexity)
│ ├── list.go # List command (list tracked beads)
│ ├── migrate.go # Database migration command
│ ├── orchestrate.go # Orchestrate command (internal, execute tasks)
│ ├── poll.go # Text-based progress monitoring
│ ├── proj.go # Project management commands
│ ├── run.go # Run command (execute pending tasks)
│ ├── status.go # Status command
│ ├── sync.go # Sync command (pull from upstream)
│ ├── task.go # Task management commands
│ ├── task_processing.go # Task processing helpers
│ ├── tui.go # Interactive TUI (lazygit-style)
│ ├── work.go # Work management commands
│ └── work_automated.go # Automated bead-to-PR workflow
└── internal/
├── beads/ # Beads client (bd CLI wrapper)
├── claude/ # Claude Code invocation
├── db/ # SQLite tracking database
│ ├── migrations/ # Schema migrations
│ ├── queries/ # SQL query definitions
│ └── sqlc/ # Generated SQL queries
├── git/ # Git operations
├── mise/ # Mise tool management
├── project/ # Project discovery and config
├── signal/ # Signal handling
├── task/ # Task planning and complexity estimation
├── worktree/ # Git worktree operations
└── zellij/ # Zellij terminal multiplexer integration
go test ./...go build -o co .After modifying SQL files in internal/db/queries/:
mise run sqlc-generateAll commands must be run from within a project. Create one first:
co proj create ~/myproject ~/path/to/repo
cd ~/myprojectInstall beads:
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bashInstall GitHub CLI:
- macOS:
brew install gh - Linux: See cli.github.com/manual/installation
Authenticate with GitHub:
gh auth loginEnsure you have ready beads in your project's main repo:
cd ~/myproject/main
bd readyIf empty, create work items:
bd create --title "Your task" --type taskYou need to be in a work directory or specify the work ID:
co work create bead-1 bead-2
cd w-abc # Use the generated work ID
co runMIT