@adamancyzhang/claude-orchestrator 0.2.8 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +179 -186
- package/dist/cli/commands.d.ts +13 -20
- package/dist/cli/commands.js +171 -288
- package/dist/cli/commands.js.map +1 -1
- package/dist/config.d.ts +25 -11
- package/dist/config.js +49 -13
- package/dist/config.js.map +1 -1
- package/dist/index.js +122 -215
- package/dist/index.js.map +1 -1
- package/dist/leader/decision-engine.d.ts +35 -0
- package/dist/leader/decision-engine.js +102 -0
- package/dist/leader/decision-engine.js.map +1 -0
- package/dist/leader/event-bus.d.ts +11 -0
- package/dist/leader/event-bus.js +21 -0
- package/dist/leader/event-bus.js.map +1 -0
- package/dist/leader/index.d.ts +7 -0
- package/dist/leader/index.js +96 -0
- package/dist/leader/index.js.map +1 -0
- package/dist/leader/monitor.d.ts +14 -0
- package/dist/leader/monitor.js +55 -0
- package/dist/leader/monitor.js.map +1 -0
- package/dist/leader/orchestrator.d.ts +14 -0
- package/dist/leader/orchestrator.js +83 -0
- package/dist/leader/orchestrator.js.map +1 -0
- package/dist/leader/recovery.d.ts +11 -0
- package/dist/leader/recovery.js +61 -0
- package/dist/leader/recovery.js.map +1 -0
- package/dist/leader/state.d.ts +24 -0
- package/dist/leader/state.js +122 -0
- package/dist/leader/state.js.map +1 -0
- package/dist/leader/task-generator.d.ts +34 -0
- package/dist/leader/task-generator.js +93 -0
- package/dist/leader/task-generator.js.map +1 -0
- package/dist/leader/tui.d.ts +5 -0
- package/dist/leader/tui.js +136 -0
- package/dist/leader/tui.js.map +1 -0
- package/dist/leader/watcher.d.ts +18 -0
- package/dist/leader/watcher.js +89 -0
- package/dist/leader/watcher.js.map +1 -0
- package/dist/models/schemas.d.ts +111 -100
- package/dist/models/schemas.js +54 -45
- package/dist/models/schemas.js.map +1 -1
- package/dist/modules/message-router.d.ts +2 -2
- package/dist/modules/message-router.js +10 -16
- package/dist/modules/message-router.js.map +1 -1
- package/dist/modules/registry.js +3 -3
- package/dist/modules/registry.js.map +1 -1
- package/dist/modules/task-queue.d.ts +4 -1
- package/dist/modules/task-queue.js +114 -10
- package/dist/modules/task-queue.js.map +1 -1
- package/dist/skills/CLAUDE.md +155 -0
- package/dist/skills/claude-code-developer/SKILL.md +325 -0
- package/dist/skills/claude-orchestrator/SKILL.md +180 -0
- package/dist/skills/task-acceptance/SKILL.md +201 -0
- package/dist/skills/task-execution/SKILL.md +142 -0
- package/dist/skills/task-planning/SKILL.md +188 -0
- package/dist/skills/task-review/SKILL.md +220 -0
- package/dist/skills/task-traceability/SKILL.md +154 -0
- package/dist/skills/task-verification/SKILL.md +194 -0
- package/dist/templates/leader-decide.md +59 -0
- package/dist/templates/leader-decompose.md +69 -0
- package/dist/templates/worker-accept.md +46 -0
- package/dist/templates/worker-build.md +45 -0
- package/dist/templates/worker-plan.md +43 -0
- package/dist/templates/worker-review.md +46 -0
- package/dist/templates/worker-verify.md +47 -0
- package/dist/utils/exec.d.ts +8 -0
- package/dist/utils/exec.js +45 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/worker/watcher.d.ts +19 -0
- package/dist/worker/watcher.js +152 -0
- package/dist/worker/watcher.js.map +1 -0
- package/dist/zk/client.d.ts +5 -5
- package/dist/zk/client.js +16 -26
- package/dist/zk/client.js.map +1 -1
- package/dist/zk/paths.d.ts +9 -9
- package/dist/zk/paths.js +4 -5
- package/dist/zk/paths.js.map +1 -1
- package/dist/zk/watcher.d.ts +0 -2
- package/dist/zk/watcher.js +0 -3
- package/dist/zk/watcher.js.map +1 -1
- package/package.json +3 -6
- package/dist/modules/context-store.d.ts +0 -10
- package/dist/modules/context-store.js +0 -25
- package/dist/modules/context-store.js.map +0 -1
- package/dist/modules/message-watcher.d.ts +0 -12
- package/dist/modules/message-watcher.js +0 -133
- package/dist/modules/message-watcher.js.map +0 -1
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -490
- package/dist/server.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,30 +22,25 @@
|
|
|
22
22
|
|
|
23
23
|
Behind the scenes, ZooKeeper acts as the coordination backbone: ephemeral nodes for instance heartbeat, sequential nodes for FIFO task ordering, and watches for real-time change notification.
|
|
24
24
|
|
|
25
|
+
v0.3.0 introduces a **Leader-Worker CLI-native architecture**: no MCP server, no HTTP. The Leader runs a read-only TUI monitoring the team, while Workers connect directly to ZooKeeper and process messages via `claude -p`. All messaging happens through the CLI.
|
|
26
|
+
|
|
25
27
|
```
|
|
26
|
-
|
|
27
|
-
│
|
|
28
|
-
│
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
│
|
|
34
|
-
│
|
|
35
|
-
│
|
|
36
|
-
|
|
37
|
-
│
|
|
38
|
-
|
|
39
|
-
│
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
└──────────────────────────────────────────────────────────┘
|
|
43
|
-
▲ ▲ ▲
|
|
44
|
-
│ │ │
|
|
45
|
-
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
|
|
46
|
-
│ Tom │ │ Jerry │ │ Bob │
|
|
47
|
-
│Architect│ │Developer│ │ Tester │
|
|
48
|
-
└─────────┘ └─────────┘ └─────────┘
|
|
28
|
+
┌─────────────────────────────────────────────────┐
|
|
29
|
+
│ ZooKeeper │
|
|
30
|
+
│ /leader /instances /tasks /messages /context│
|
|
31
|
+
└──────┬──────────────┬──────────────┬────────────┘
|
|
32
|
+
│ │ │
|
|
33
|
+
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
|
|
34
|
+
│ Leader │ │ Worker │ │ Worker │
|
|
35
|
+
│ (TUI) │ │ (CLI) │ │ (CLI) │
|
|
36
|
+
│ Tom │ │ Jerry │ │ Bob │
|
|
37
|
+
│architect│ │developer│ │ tester │
|
|
38
|
+
└─────────┘ └─────────┘ └─────────┘
|
|
39
|
+
│ │ │
|
|
40
|
+
└──────────────┼──────────────┘
|
|
41
|
+
│
|
|
42
|
+
claude-orchestrator CLI
|
|
43
|
+
(send-message, push-task, …)
|
|
49
44
|
```
|
|
50
45
|
|
|
51
46
|
---
|
|
@@ -64,129 +59,95 @@ npm install -g @adamancyzhang/claude-orchestrator
|
|
|
64
59
|
docker-compose up -d
|
|
65
60
|
```
|
|
66
61
|
|
|
67
|
-
### 3.
|
|
62
|
+
### 3. Initialize your environment
|
|
68
63
|
|
|
69
64
|
```bash
|
|
70
|
-
|
|
71
|
-
|
|
65
|
+
# For the Leader (the team coordinator):
|
|
66
|
+
claude-orchestrator setup --leader --name Tom
|
|
67
|
+
|
|
68
|
+
# For each Worker (the doers):
|
|
69
|
+
claude-orchestrator setup --name Jerry --role developer
|
|
72
70
|
```
|
|
73
71
|
|
|
74
|
-
|
|
72
|
+
This creates `.claude-orchestrator/agents/` with message templates and writes project + global config.
|
|
75
73
|
|
|
76
|
-
|
|
74
|
+
### 4. Start the Leader
|
|
77
75
|
|
|
78
76
|
```bash
|
|
79
|
-
claude-orchestrator
|
|
77
|
+
claude-orchestrator leader --name Tom
|
|
78
|
+
# → TUI launches: team panel, task board, event log, footer
|
|
80
79
|
```
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
Options:
|
|
85
|
-
- `--global` — write to `~/.claude/mcp.json` instead of local `.claude/mcp.json`
|
|
86
|
-
- `--port`, `--host` — if your server runs on a different address
|
|
87
|
-
- `--name`, `--role` — set instance identity headers
|
|
88
|
-
- `--with-hook` — add SessionStart + SessionEnd hooks for automatic lifecycle
|
|
89
|
-
|
|
90
|
-
### 5. Go
|
|
91
|
-
|
|
92
|
-
Restart Claude Code in this project — the `SessionStart` hook auto-registers your instance. Or register manually with `/orchestrator-register`.
|
|
93
|
-
|
|
94
|
-
Now open another terminal, start a second Claude Code instance, run `claude-orchestrator setup` with a different name/role, and they'll discover each other, pass tasks, and collaborate.
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## How It Works
|
|
81
|
+
The Leader TUI is read-only — it shows who's online, what tasks are pending/in-progress, and a scrolling event log. All actions are triggered by CLI commands or Worker registrations.
|
|
99
82
|
|
|
100
|
-
###
|
|
101
|
-
|
|
102
|
-
| Module | What it does | ZK magic |
|
|
103
|
-
|--------|-------------|----------|
|
|
104
|
-
| **Instance Registry** | Register, heartbeat, discover, unregister | Ephemeral nodes → auto-cleanup on disconnect |
|
|
105
|
-
| **Task Queue** | Push → Claim → Complete | Sequential nodes for FIFO, ephemeral claims for atomic locks |
|
|
106
|
-
| **Message Router** | P2P messages, broadcast, help requests, long-poll | Persistent-sequential nodes, ZK watches for push |
|
|
107
|
-
| **Context Store** | Shared key-value storage, watch for changes | Persistent nodes, cross-instance visibility |
|
|
108
|
-
|
|
109
|
-
### The MCP Tools (18)
|
|
110
|
-
|
|
111
|
-
Each Claude Code instance calls these tools to participate in the swarm:
|
|
112
|
-
|
|
113
|
-
| # | Tool | What it does |
|
|
114
|
-
|---|------|-------------|
|
|
115
|
-
| 1 | `register_instance` | Join the swarm with a name and role |
|
|
116
|
-
| 2 | `heartbeat` | Stay alive, optionally report what you're working on |
|
|
117
|
-
| 3 | `list_instances` | See who's online right now |
|
|
118
|
-
| 4 | `push_task` | Create a task (optionally assign to someone specific) |
|
|
119
|
-
| 5 | `claim_task` | Grab the next task — atomic, no two instances can claim the same one |
|
|
120
|
-
| 6 | `complete_task` | Mark a task done with results |
|
|
121
|
-
| 7 | `list_tasks` | View tasks by status (pending / claimed / completed) |
|
|
122
|
-
| 8 | `send_message` | DM another instance or broadcast to everyone |
|
|
123
|
-
| 9 | `poll_messages` | Check your inbox |
|
|
124
|
-
| 10 | `wait_for_message` | Long-poll — block until a message arrives |
|
|
125
|
-
| 11 | `dismiss_message` | Delete a message from your inbox |
|
|
126
|
-
| 12 | `request_help` | Broadcast a question to the whole team |
|
|
127
|
-
| 13 | `set_context` | Write a shared key-value entry |
|
|
128
|
-
| 14 | `get_context` | Read a shared key-value entry |
|
|
129
|
-
| 15 | `delete_context` | Remove a shared context key |
|
|
130
|
-
| 16 | `list_context_keys` | List all context keys |
|
|
131
|
-
| 17 | `mark_read` | Mark a specific message as read |
|
|
132
|
-
| 18 | `server_status` | Health check |
|
|
133
|
-
|
|
134
|
-
### Or Use the CLI Directly
|
|
135
|
-
|
|
136
|
-
If you prefer the terminal over Claude Code:
|
|
83
|
+
### 5. Register a Worker
|
|
137
84
|
|
|
138
85
|
```bash
|
|
139
|
-
#
|
|
140
|
-
claude-orchestrator register --name
|
|
141
|
-
|
|
142
|
-
# See who's around
|
|
143
|
-
claude-orchestrator list-instances
|
|
86
|
+
# Persistent mode — stays connected and processes messages automatically:
|
|
87
|
+
claude-orchestrator register --name Jerry --role developer --work-dir /path/to/project
|
|
144
88
|
|
|
145
|
-
#
|
|
146
|
-
claude-orchestrator
|
|
147
|
-
|
|
148
|
-
# Claim the next task
|
|
149
|
-
claude-orchestrator claim-task
|
|
150
|
-
|
|
151
|
-
# Send a message
|
|
152
|
-
claude-orchestrator send-message --to <instance-id> --content "How's PR #42 going?"
|
|
153
|
-
|
|
154
|
-
# Check inbox
|
|
155
|
-
claude-orchestrator poll-messages
|
|
156
|
-
|
|
157
|
-
# Wait for messages (blocks until received or timeout)
|
|
158
|
-
claude-orchestrator wait-for-message --timeout 60
|
|
159
|
-
|
|
160
|
-
# Dismiss a message
|
|
161
|
-
claude-orchestrator dismiss-message --message-id msg-0000000000
|
|
89
|
+
# One-shot mode — just register, no persistent watcher:
|
|
90
|
+
claude-orchestrator register --name Jerry --role developer
|
|
91
|
+
```
|
|
162
92
|
|
|
163
|
-
|
|
164
|
-
claude-orchestrator set-context --key "api_version" --value "v2.1"
|
|
93
|
+
### 6. Go
|
|
165
94
|
|
|
166
|
-
|
|
167
|
-
claude-orchestrator get-context --key "api_version"
|
|
95
|
+
Now the Leader TUI shows Jerry online. You can push tasks, send messages, and manage the full lifecycle — all from any terminal.
|
|
168
96
|
|
|
169
|
-
|
|
170
|
-
claude-orchestrator
|
|
97
|
+
```bash
|
|
98
|
+
claude-orchestrator push-task --title "Implement login endpoint" --priority 0
|
|
99
|
+
claude-orchestrator send-message --to-name Jerry --content "Starting on the auth module?"
|
|
100
|
+
claude-orchestrator list-tasks --status pending
|
|
101
|
+
```
|
|
171
102
|
|
|
172
|
-
|
|
173
|
-
claude-orchestrator delete-context --key "api_version"
|
|
103
|
+
---
|
|
174
104
|
|
|
175
|
-
|
|
176
|
-
claude-orchestrator watch-context --key "jwt_strategy"
|
|
105
|
+
## How It Works
|
|
177
106
|
|
|
178
|
-
|
|
179
|
-
claude-orchestrator watch-tasks
|
|
107
|
+
### Leader-Worker Model
|
|
180
108
|
|
|
181
|
-
|
|
182
|
-
|
|
109
|
+
| Component | What it does | ZK magic |
|
|
110
|
+
|-----------|-------------|----------|
|
|
111
|
+
| **Leader** | Read-only TUI, monitors team, recovers orphaned tasks | `/leader` EPHEMERAL — only one Leader at a time |
|
|
112
|
+
| **Worker** | Persistent ZK connection, auto-processes messages via `claude -p` | Ephemeral nodes → auto-cleanup on disconnect |
|
|
113
|
+
| **Task Queue** | Push → Claim → In Progress → Complete (or Block/Fail/Retry) | Sequential nodes for FIFO, ephemeral claims for atomic locks |
|
|
114
|
+
| **Message Router** | P2P messages, broadcast, help requests, templates | Persistent-sequential nodes, ZK watches for push |
|
|
115
|
+
| **Context Store** | Shared key-value storage, watch for changes | Persistent nodes, cross-instance visibility |
|
|
183
116
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
117
|
+
### CLI-Native — No MCP Server
|
|
118
|
+
|
|
119
|
+
v0.3.0 removes the centralized MCP Server entirely. Leader and Workers each connect directly to ZooKeeper. Messages are delivered via ZK watches that trigger `$COMMAND -p "$MSG" | tee $CACHE_DIR/{key}.log` on the recipient. This eliminates 3 layers of indirection (MCP protocol, SSE, HTTP) and makes every node self-contained.
|
|
120
|
+
|
|
121
|
+
### CLI Commands (25)
|
|
122
|
+
|
|
123
|
+
| Command | What it does |
|
|
124
|
+
|---------|-------------|
|
|
125
|
+
| `leader` | Start Leader node with read-only TUI |
|
|
126
|
+
| `setup` | Initialize environment: templates, config, agent directory |
|
|
127
|
+
| `register` | Join the swarm. With `--work-dir`: persistent message watcher |
|
|
128
|
+
| `heartbeat` | Stay alive, optionally report current task |
|
|
129
|
+
| `status` | Health check (ZK connection) |
|
|
130
|
+
| `list-instances` | See who's online |
|
|
131
|
+
| `push-task` | Create a task (optionally assign to someone) |
|
|
132
|
+
| `claim-task` | Grab the next task — atomic, no two instances can claim the same one |
|
|
133
|
+
| `complete-task` | Mark a task done with results |
|
|
134
|
+
| `task-block` | Mark a claimed task as blocked (with reason) |
|
|
135
|
+
| `task-fail` | Mark a claimed task as failed (with reason) |
|
|
136
|
+
| `task-retry` | Re-queue a failed task for retry (retry_count + 1, max 3) |
|
|
137
|
+
| `list-tasks` | View tasks by status (pending/claimed/in_progress/completed/blocked/failed) |
|
|
138
|
+
| `send-message` | DM another instance by name or broadcast to all |
|
|
139
|
+
| `poll-messages` | Check your inbox |
|
|
140
|
+
| `wait-for-message` | Long-poll — block until a message arrives |
|
|
141
|
+
| `dismiss-message` | Delete a message from your inbox |
|
|
142
|
+
| `request-help` | Broadcast a question to the whole team |
|
|
143
|
+
| `set-context` | Write a shared key-value entry |
|
|
144
|
+
| `get-context` | Read a shared key-value entry |
|
|
145
|
+
| `delete-context` | Remove a shared context key |
|
|
146
|
+
| `list-context-keys` | List all context keys |
|
|
147
|
+
| `watch-context` | Watch a context key for changes (blocks until change) |
|
|
148
|
+
| `watch-tasks` | Watch for new tasks (blocks until new task) |
|
|
149
|
+
| `unregister` | Explicitly unregister an instance |
|
|
150
|
+
| `config` | Show current configuration |
|
|
190
151
|
|
|
191
152
|
All CLI commands return JSON. Every command supports `--zookeeper` / `-z` (or `ZK_HOSTS` env var) for pointing at a remote ZooKeeper.
|
|
192
153
|
|
|
@@ -194,74 +155,69 @@ All CLI commands return JSON. Every command supports `--zookeeper` / `-z` (or `Z
|
|
|
194
155
|
|
|
195
156
|
## Example Session
|
|
196
157
|
|
|
197
|
-
Here's a real flow with
|
|
158
|
+
Here's a real flow with a Leader (Tom) and two Workers (Jerry, Bob):
|
|
198
159
|
|
|
199
|
-
**Tom
|
|
200
|
-
```json
|
|
201
|
-
{ "id": "a1b2c3d4...", "name": "Tom", "role": "architect", "status": "idle" }
|
|
160
|
+
**Tom starts the Leader:**
|
|
202
161
|
```
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
```json
|
|
206
|
-
{ "id": "f6e5d4c3...", "name": "Jerry", "role": "developer", "status": "idle" }
|
|
162
|
+
claude-orchestrator leader --name Tom
|
|
163
|
+
→ TUI shows: [TEAM] Tom (leader), [PENDING] empty, [EVENT LOG] Leader started
|
|
207
164
|
```
|
|
208
165
|
|
|
209
|
-
**
|
|
166
|
+
**Jerry registers as a Worker:**
|
|
167
|
+
```bash
|
|
168
|
+
claude-orchestrator register --name Jerry --role developer --work-dir ~/project
|
|
210
169
|
```
|
|
211
|
-
2 active instances:
|
|
212
|
-
[architect] Tom (a1b2c3d4...) status=idle
|
|
213
|
-
[developer] Jerry (f6e5d4c3...) status=idle
|
|
214
170
|
```
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
push_task:
|
|
219
|
-
title: "Implement POST /api/auth/login"
|
|
220
|
-
description: "Email+password login, return JWT. Handle validation and errors."
|
|
221
|
-
priority: HIGH (0)
|
|
222
|
-
assignee: f6e5d4c3... (Jerry)
|
|
171
|
+
TUI updates:
|
|
172
|
+
[TEAM] Jerry joined (developer)
|
|
173
|
+
[EVENT] 9:15:03 PM Jerry joined (developer)
|
|
223
174
|
```
|
|
224
175
|
|
|
225
|
-
**
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
|
|
176
|
+
**Tom assigns work (from another terminal):**
|
|
177
|
+
```bash
|
|
178
|
+
claude-orchestrator push-task --title "Implement POST /api/auth/login" \
|
|
179
|
+
--description "Email+password login, return JWT." --priority 0
|
|
229
180
|
```
|
|
230
181
|
|
|
231
|
-
**Jerry
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
context: "Express + jsonwebtoken, ~100K DAU"
|
|
182
|
+
**Jerry claims it:**
|
|
183
|
+
```bash
|
|
184
|
+
claude-orchestrator claim-task
|
|
185
|
+
# → { "id": "task-0000000000", "status": "claimed", ... }
|
|
236
186
|
```
|
|
237
187
|
|
|
238
|
-
**
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
send_message to=Jerry: "15min access, 7d refresh. Use Redis blacklist for logout."
|
|
188
|
+
**Jerry gets blocked:**
|
|
189
|
+
```bash
|
|
190
|
+
claude-orchestrator task-block --task-id task-0000000000 --reason "Waiting for API key"
|
|
242
191
|
```
|
|
243
192
|
|
|
244
|
-
**Tom
|
|
245
|
-
```
|
|
246
|
-
|
|
193
|
+
**Tom sees the block in the TUI and sends the key:**
|
|
194
|
+
```bash
|
|
195
|
+
claude-orchestrator send-message --to-name Jerry --content "API key is in 1Password: auth/third-party/google-oauth"
|
|
247
196
|
```
|
|
248
197
|
|
|
249
198
|
**Jerry finishes:**
|
|
250
|
-
```
|
|
251
|
-
|
|
199
|
+
```bash
|
|
200
|
+
claude-orchestrator complete-task --task-id task-0000000000 --result "PR #42 — login endpoint with tests"
|
|
252
201
|
```
|
|
253
202
|
|
|
254
|
-
|
|
203
|
+
**Bob fails a task (test env down):**
|
|
204
|
+
```bash
|
|
205
|
+
claude-orchestrator task-fail --task-id task-0000000001 --reason "Test environment unavailable"
|
|
206
|
+
claude-orchestrator task-retry --task-id task-0000000001
|
|
207
|
+
# → Re-queued as task-0000000002 with retry_count: 1
|
|
208
|
+
```
|
|
255
209
|
|
|
256
210
|
---
|
|
257
211
|
|
|
258
|
-
## ZooKeeper Schema
|
|
212
|
+
## ZooKeeper Schema (v0.3.0)
|
|
259
213
|
|
|
260
214
|
```
|
|
261
215
|
/claude-orchestrator
|
|
216
|
+
├── leader [EPHEMERAL] Leader metadata
|
|
262
217
|
├── instances/
|
|
263
|
-
│ ├── a1b2c3d4...
|
|
264
|
-
│
|
|
218
|
+
│ ├── a1b2c3d4... [EPHEMERAL] Tom (leader)
|
|
219
|
+
│ ├── f6e5d4c3... [EPHEMERAL] Jerry (developer)
|
|
220
|
+
│ └── e7f8a9b0... [EPHEMERAL] Bob (tester)
|
|
265
221
|
├── tasks/
|
|
266
222
|
│ ├── pending/
|
|
267
223
|
│ │ ├── task-0000000000 [PERSISTENT_SEQUENTIAL]
|
|
@@ -279,7 +235,27 @@ No polling required for task claiming — the atomic claim mechanism means Jerry
|
|
|
279
235
|
└── jwt_strategy [PERSISTENT]
|
|
280
236
|
```
|
|
281
237
|
|
|
282
|
-
**Key insight:** Ephemeral nodes mean crashed instances auto-unregister. Ephemeral claim nodes mean abandoned tasks auto-release.
|
|
238
|
+
**Key insight:** Ephemeral nodes mean crashed instances auto-unregister. Ephemeral claim nodes mean abandoned tasks auto-release. The Leader monitors `/instances` and recovers orphaned tasks when a Worker disconnects (max 3 retries, then archived as failed).
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Task State Machine (v0.3.0)
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
pending → claimed → in_progress → completed
|
|
246
|
+
→ blocked → pending (retry)
|
|
247
|
+
→ failed → pending (retry, max 3)
|
|
248
|
+
claimed → pending (Worker disconnect, Leader recovers orphan)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
| State | Meaning | Trigger |
|
|
252
|
+
|-------|---------|---------|
|
|
253
|
+
| `pending` | Waiting for claim | `push_task` |
|
|
254
|
+
| `claimed` | Claimed, not started | `claim_task` |
|
|
255
|
+
| `in_progress` | Working | `heartbeat(current_task=...)` |
|
|
256
|
+
| `completed` | Done | `complete_task` |
|
|
257
|
+
| `blocked` | Blocked, waiting unblock | `task-block` |
|
|
258
|
+
| `failed` | Failed, can retry | `task-fail` |
|
|
283
259
|
|
|
284
260
|
---
|
|
285
261
|
|
|
@@ -289,7 +265,7 @@ No polling required for task claiming — the atomic claim mechanism means Jerry
|
|
|
289
265
|
|
|
290
266
|
- Node.js 18+
|
|
291
267
|
- Docker (for ZooKeeper)
|
|
292
|
-
- Claude Code (for
|
|
268
|
+
- Claude Code CLI (for `register --work-dir` message processing)
|
|
293
269
|
|
|
294
270
|
### From Source
|
|
295
271
|
|
|
@@ -306,8 +282,8 @@ docker-compose up -d
|
|
|
306
282
|
# Build TypeScript
|
|
307
283
|
npm run build
|
|
308
284
|
|
|
309
|
-
# Start the
|
|
310
|
-
claude-orchestrator
|
|
285
|
+
# Start the Leader
|
|
286
|
+
claude-orchestrator leader
|
|
311
287
|
|
|
312
288
|
# Or use the CLI directly
|
|
313
289
|
claude-orchestrator status
|
|
@@ -327,9 +303,8 @@ The repo includes Claude Code skills that make the orchestrator even easier to u
|
|
|
327
303
|
|
|
328
304
|
| Skill | What it does |
|
|
329
305
|
|-------|-------------|
|
|
330
|
-
| `claude-
|
|
331
|
-
| `
|
|
332
|
-
| `orchestrator-setup` | Auto-configure MCP connection and auto-registration hook |
|
|
306
|
+
| `claude-orchestrator` | Full CLI reference — all 25 commands with examples |
|
|
307
|
+
| `orchestrator-setup` | Auto-configure environment and agent templates |
|
|
333
308
|
| `orchestrator-register` | Guided registration flow |
|
|
334
309
|
| `orchestrator-status` | Dashboard: health, instances, tasks |
|
|
335
310
|
| `orchestrator-communicate` | Message patterns: poll, DM, broadcast |
|
|
@@ -345,8 +320,9 @@ The repo includes Claude Code skills that make the orchestrator even easier to u
|
|
|
345
320
|
| Instance lifecycle | Ephemeral nodes → auto-cleanup. No heartbeat polling needed. |
|
|
346
321
|
| Task ordering | Sequential nodes → guaranteed FIFO. No race conditions. |
|
|
347
322
|
| Claim atomicity | `create(path, ephemeral=true)` is atomic at the ZK level. Only one winner. |
|
|
323
|
+
| Leader election | `/leader` EPHEMERAL → exactly one Leader. Auto-released on crash. |
|
|
348
324
|
| Change notification | Built-in watches → push, not poll. |
|
|
349
|
-
| Dependencies | One dependency (ZK). No external database
|
|
325
|
+
| Dependencies | One dependency (ZK). No external database, no HTTP server. |
|
|
350
326
|
|
|
351
327
|
Zero external database. All state lives in ZooKeeper.
|
|
352
328
|
|
|
@@ -356,6 +332,7 @@ Zero external database. All state lives in ZooKeeper.
|
|
|
356
332
|
|
|
357
333
|
| Role | Value | Typical behavior |
|
|
358
334
|
|------|-------|-----------------|
|
|
335
|
+
| Leader | `leader` | Runs TUI, monitors team, recovers orphaned tasks |
|
|
359
336
|
| Architect | `architect` | Sets standards, designs tasks, reviews results |
|
|
360
337
|
| Developer | `developer` | Claims tasks, writes code, submits PRs |
|
|
361
338
|
| Tester | `tester` | Claims test tasks, E2E verification |
|
|
@@ -369,8 +346,8 @@ Zero external database. All state lives in ZooKeeper.
|
|
|
369
346
|
|--------|-------|---------|
|
|
370
347
|
| ZK hosts | `-z, --zookeeper` flag or `ZK_HOSTS` env | `127.0.0.1:2181` |
|
|
371
348
|
| Instance ID | `-i, --instance-id` flag or `.claude-orchestrator/config.json` (project) / `~/.claude-orchestrator/config.json` (global) | auto-saved after `register` |
|
|
372
|
-
|
|
|
373
|
-
|
|
|
349
|
+
| Claude command | `--command` flag or `config.json` → `command` | `claude --dangerously-skip-permissions -v` |
|
|
350
|
+
| Cache directory | `--cache-dir` flag or `config.json` → `cache_dir` | `~/.claude-orchestrator/sessions` |
|
|
374
351
|
|
|
375
352
|
---
|
|
376
353
|
|
|
@@ -378,37 +355,53 @@ Zero external database. All state lives in ZooKeeper.
|
|
|
378
355
|
|
|
379
356
|
```
|
|
380
357
|
├── src/
|
|
381
|
-
│ ├── index.ts # CLI entry point (commander)
|
|
382
|
-
│ ├── server.ts # MCP server — 18 tools, 5 resources, 2 prompts
|
|
358
|
+
│ ├── index.ts # CLI entry point (commander, 25 commands)
|
|
383
359
|
│ ├── config.ts # Configuration handling
|
|
384
360
|
│ ├── cli/
|
|
385
361
|
│ │ └── commands.ts # CLI subcommand implementations
|
|
362
|
+
│ ├── leader/ # Leader node (v0.3.0)
|
|
363
|
+
│ │ ├── index.ts # startup / shutdown orchestration
|
|
364
|
+
│ │ ├── tui.ts # ANSI-based read-only TUI
|
|
365
|
+
│ │ ├── event-bus.ts # typed EventEmitter
|
|
366
|
+
│ │ ├── state.ts # centralized LeaderState
|
|
367
|
+
│ │ ├── monitor.ts # WorkerMonitor — join/leave detection
|
|
368
|
+
│ │ ├── orchestrator.ts # TaskOrchestrator — lifecycle tracking
|
|
369
|
+
│ │ ├── recovery.ts # TaskRecovery — orphan recovery (max 3 retries)
|
|
370
|
+
│ │ └── watcher.ts # LeaderWatcher — message processing
|
|
371
|
+
│ ├── worker/ # Worker node (v0.3.0)
|
|
372
|
+
│ │ └── watcher.ts # WorkerWatcher — persistent message loop
|
|
373
|
+
│ ├── templates/ # Built-in agent templates
|
|
374
|
+
│ │ ├── leader.md # Leader message template
|
|
375
|
+
│ │ └── worker.md # Worker completion report template
|
|
386
376
|
│ ├── zk/
|
|
387
377
|
│ │ ├── client.ts # ZooKeeper connection management
|
|
388
378
|
│ │ ├── paths.ts # ZK path constants
|
|
389
379
|
│ │ └── watcher.ts # ZK watch manager
|
|
390
380
|
│ ├── modules/
|
|
391
381
|
│ │ ├── registry.ts # Instance registry
|
|
392
|
-
│ │ ├── task-queue.ts # Task queue
|
|
393
|
-
│ │ ├── message-router.ts # Message routing + long-poll
|
|
382
|
+
│ │ ├── task-queue.ts # Task queue (6-state: push/claim/block/fail/retry)
|
|
383
|
+
│ │ ├── message-router.ts # Message routing + template rendering + long-poll
|
|
394
384
|
│ │ └── context-store.ts # Shared key-value store
|
|
395
385
|
│ ├── models/
|
|
396
386
|
│ │ └── schemas.ts # Zod schemas and inferred types
|
|
397
387
|
│ └── utils/
|
|
388
|
+
│ ├── exec.ts # Shell execution (execWithTee)
|
|
398
389
|
│ └── output.ts # CLI output formatting
|
|
399
390
|
├── bin/
|
|
400
391
|
│ └── claude-orchestrator # npm CLI entry (Node.js)
|
|
401
392
|
├── scripts/
|
|
402
393
|
│ ├── start-zk.sh # Docker ZK launcher
|
|
403
|
-
│ ├── start-
|
|
394
|
+
│ ├── start-leader.sh # Leader launcher
|
|
395
|
+
│ ├── start-worker.sh # Worker launcher
|
|
404
396
|
│ ├── stop-all.sh # Tear down
|
|
405
397
|
│ └── publish.sh # npm publish pipeline
|
|
406
398
|
├── skills/ # Claude Code skills
|
|
407
399
|
├── docs/
|
|
408
400
|
│ ├── v0.1.0/ # Archived Python v0.1.0 docs
|
|
409
|
-
│
|
|
410
|
-
│
|
|
411
|
-
│
|
|
401
|
+
│ ├── v0.2.0/ # Archived MCP-based v0.2.x docs
|
|
402
|
+
│ └── v0.3.0/ # Current v0.3.0 docs
|
|
403
|
+
│ ├── prd/ # Full spec + architecture + ZK schema
|
|
404
|
+
│ └── migration-guide.md # v0.2.0 → v0.3.0 migration
|
|
412
405
|
├── tests/
|
|
413
406
|
│ ├── unit/
|
|
414
407
|
│ └── integration/
|
|
@@ -426,5 +419,5 @@ MIT — use it, fork it, ship it.
|
|
|
426
419
|
---
|
|
427
420
|
|
|
428
421
|
<p align="center">
|
|
429
|
-
<sub>Built with TypeScript
|
|
422
|
+
<sub>Built with TypeScript and ZooKeeper. Orchestrate responsibly.</sub>
|
|
430
423
|
</p>
|
package/dist/cli/commands.d.ts
CHANGED
|
@@ -1,28 +1,21 @@
|
|
|
1
|
-
export declare function
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function cmdHeartbeat(zkHosts: string, cliInstanceId: string | undefined, currentTask?: string): Promise<void>;
|
|
4
|
-
export declare function cmdListInstances(zkHosts: string): Promise<void>;
|
|
5
|
-
export declare function cmdPushTask(zkHosts: string, cliInstanceId: string | undefined, title: string, description: string, priority: number, assignee?: string): Promise<void>;
|
|
1
|
+
export declare function cmdRegister(zkHosts: string): Promise<void>;
|
|
2
|
+
export declare function cmdPushTask(zkHosts: string, cliInstanceId: string | undefined, title: string, description: string, priority: number, assignee?: string, link?: string, chainId?: string, dependsOn?: string[], blockedBy?: string[]): Promise<void>;
|
|
6
3
|
export declare function cmdClaimTask(zkHosts: string, cliInstanceId: string | undefined): Promise<void>;
|
|
7
4
|
export declare function cmdCompleteTask(zkHosts: string, cliInstanceId: string | undefined, taskId: string, result: string): Promise<void>;
|
|
8
|
-
export declare function
|
|
9
|
-
export declare function cmdSendMessage(zkHosts: string, cliInstanceId: string | undefined, content: string, toInstance?: string, broadcast?: boolean, toName?: string): Promise<void>;
|
|
10
|
-
export declare function
|
|
11
|
-
export declare function
|
|
12
|
-
export declare function cmdDismissMessage(zkHosts: string, cliInstanceId: string | undefined, messageId: string): Promise<void>;
|
|
13
|
-
export declare function cmdRequestHelp(zkHosts: string, cliInstanceId: string | undefined, question: string, ctx?: string): Promise<void>;
|
|
14
|
-
export declare function cmdSetContext(zkHosts: string, cliInstanceId: string | undefined, key: string, value: string): Promise<void>;
|
|
15
|
-
export declare function cmdGetContext(zkHosts: string, key: string): Promise<void>;
|
|
16
|
-
export declare function cmdDeleteContext(zkHosts: string, key: string): Promise<void>;
|
|
17
|
-
export declare function cmdListContextKeys(zkHosts: string): Promise<void>;
|
|
18
|
-
export declare function cmdWatchContext(zkHosts: string, key: string): Promise<void>;
|
|
19
|
-
export declare function cmdWatchTasks(zkHosts: string): Promise<void>;
|
|
5
|
+
export declare function cmdPollTask(zkHosts: string, statusFilter?: string): Promise<void>;
|
|
6
|
+
export declare function cmdSendMessage(zkHosts: string, cliInstanceId: string | undefined, content: string, toInstance?: string, broadcast?: boolean, toName?: string, help?: boolean): Promise<void>;
|
|
7
|
+
export declare function cmdPollMessage(zkHosts: string, cliInstanceId: string | undefined): Promise<void>;
|
|
8
|
+
export declare function cmdDeleteMessage(zkHosts: string, cliInstanceId: string | undefined, messageId: string): Promise<void>;
|
|
20
9
|
export declare function cmdUnregister(zkHosts: string, cliInstanceId: string | undefined): Promise<void>;
|
|
21
10
|
export declare function cmdSetup(options: {
|
|
22
|
-
|
|
23
|
-
host: string;
|
|
11
|
+
leader: boolean;
|
|
24
12
|
name?: string;
|
|
25
13
|
role?: string;
|
|
14
|
+
cacheDir?: string;
|
|
15
|
+
command?: string;
|
|
26
16
|
global: boolean;
|
|
27
|
-
|
|
17
|
+
instanceId?: string;
|
|
28
18
|
}): Promise<void>;
|
|
19
|
+
export declare function cmdTaskBlock(zkHosts: string, cliInstanceId: string | undefined, taskId: string, reason: string): Promise<void>;
|
|
20
|
+
export declare function cmdTaskFail(zkHosts: string, cliInstanceId: string | undefined, taskId: string, reason: string): Promise<void>;
|
|
21
|
+
export declare function cmdTaskRetry(zkHosts: string, _cliInstanceId: string | undefined, taskId: string): Promise<void>;
|