@adamancyzhang/claude-orchestrator 0.3.0 → 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.
Files changed (76) hide show
  1. package/README.md +179 -186
  2. package/dist/cli/commands.d.ts +6 -17
  3. package/dist/cli/commands.js +106 -172
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/config.d.ts +22 -14
  6. package/dist/config.js +47 -20
  7. package/dist/config.js.map +1 -1
  8. package/dist/index.js +110 -246
  9. package/dist/index.js.map +1 -1
  10. package/dist/leader/decision-engine.d.ts +35 -0
  11. package/dist/leader/decision-engine.js +102 -0
  12. package/dist/leader/decision-engine.js.map +1 -0
  13. package/dist/leader/index.js +12 -2
  14. package/dist/leader/index.js.map +1 -1
  15. package/dist/leader/recovery.d.ts +2 -0
  16. package/dist/leader/recovery.js +37 -22
  17. package/dist/leader/recovery.js.map +1 -1
  18. package/dist/leader/state.d.ts +2 -1
  19. package/dist/leader/state.js +39 -2
  20. package/dist/leader/state.js.map +1 -1
  21. package/dist/leader/task-generator.d.ts +34 -0
  22. package/dist/leader/task-generator.js +93 -0
  23. package/dist/leader/task-generator.js.map +1 -0
  24. package/dist/leader/tui.js +8 -5
  25. package/dist/leader/tui.js.map +1 -1
  26. package/dist/leader/watcher.d.ts +3 -1
  27. package/dist/leader/watcher.js +14 -2
  28. package/dist/leader/watcher.js.map +1 -1
  29. package/dist/models/schemas.d.ts +60 -96
  30. package/dist/models/schemas.js +27 -44
  31. package/dist/models/schemas.js.map +1 -1
  32. package/dist/modules/message-router.d.ts +1 -3
  33. package/dist/modules/message-router.js +3 -26
  34. package/dist/modules/message-router.js.map +1 -1
  35. package/dist/modules/registry.js +3 -3
  36. package/dist/modules/registry.js.map +1 -1
  37. package/dist/modules/task-queue.d.ts +1 -1
  38. package/dist/modules/task-queue.js +28 -2
  39. package/dist/modules/task-queue.js.map +1 -1
  40. package/dist/skills/CLAUDE.md +155 -0
  41. package/dist/skills/claude-code-developer/SKILL.md +325 -0
  42. package/dist/skills/claude-orchestrator/SKILL.md +180 -0
  43. package/dist/skills/task-acceptance/SKILL.md +201 -0
  44. package/dist/skills/task-execution/SKILL.md +142 -0
  45. package/dist/skills/task-planning/SKILL.md +188 -0
  46. package/dist/skills/task-review/SKILL.md +220 -0
  47. package/dist/skills/task-traceability/SKILL.md +154 -0
  48. package/dist/skills/task-verification/SKILL.md +194 -0
  49. package/dist/templates/leader-decide.md +59 -0
  50. package/dist/templates/leader-decompose.md +69 -0
  51. package/dist/templates/worker-accept.md +46 -0
  52. package/dist/templates/worker-build.md +45 -0
  53. package/dist/templates/worker-plan.md +43 -0
  54. package/dist/templates/worker-review.md +46 -0
  55. package/dist/templates/worker-verify.md +47 -0
  56. package/dist/utils/exec.d.ts +5 -0
  57. package/dist/utils/exec.js +25 -0
  58. package/dist/utils/exec.js.map +1 -1
  59. package/dist/worker/watcher.d.ts +3 -0
  60. package/dist/worker/watcher.js +72 -2
  61. package/dist/worker/watcher.js.map +1 -1
  62. package/dist/zk/client.d.ts +0 -5
  63. package/dist/zk/client.js +0 -27
  64. package/dist/zk/client.js.map +1 -1
  65. package/dist/zk/paths.d.ts +8 -10
  66. package/dist/zk/paths.js +1 -6
  67. package/dist/zk/paths.js.map +1 -1
  68. package/dist/zk/watcher.d.ts +0 -2
  69. package/dist/zk/watcher.js +0 -3
  70. package/dist/zk/watcher.js.map +1 -1
  71. package/package.json +2 -2
  72. package/dist/modules/context-store.d.ts +0 -10
  73. package/dist/modules/context-store.js +0 -25
  74. package/dist/modules/context-store.js.map +0 -1
  75. package/dist/templates/leader.md +0 -10
  76. package/dist/templates/worker.md +0 -8
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
- Claude Orchestrator
28
- (MCP Server :3100)
29
- │ │
30
- │ ┌──────────────┐ ┌──────────┐ ┌──────────────┐
31
- │ Registry │ │ Tasks │ │ Messages │ │
32
- who's here? │ FIFO Q │ P2P + cast
33
- └──────┬───────┘ └────┬─────┘ └──────┬───────┘
34
- └────────────────┼──────────────┘
35
- ┌──────┴──────┐
36
- │ │ ZooKeeper │ │
37
- └──────┬──────┘
38
- │ ┌──────┴──────┐ │
39
- │ Context │ │
40
- │ │ KV Store │ │
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. Start the MCP Server
62
+ ### 3. Initialize your environment
68
63
 
69
64
  ```bash
70
- claude-orchestrator server
71
- # MCP server listening on http://127.0.0.1:3100
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
- ### 4. Configure Claude Code
72
+ This creates `.claude-orchestrator/agents/` with message templates and writes project + global config.
75
73
 
76
- Use the built-in setup command to auto-configure your project:
74
+ ### 4. Start the Leader
77
75
 
78
76
  ```bash
79
- claude-orchestrator setup --name Tom-Architect --role architect --with-hook
77
+ claude-orchestrator leader --name Tom
78
+ # → TUI launches: team panel, task board, event log, footer
80
79
  ```
81
80
 
82
- This writes the MCP connection to `.claude/mcp.json` and adds lifecycle hooks: `SessionStart` (auto-register) and `SessionEnd` (auto-unregister).
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
- ### Four Modules, One ZooKeeper
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
- # Register
140
- claude-orchestrator register --name Alice --role developer
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
- # Push a task
146
- claude-orchestrator push-task --title "Add rate limiting" --priority 0
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
- # Share context
164
- claude-orchestrator set-context --key "api_version" --value "v2.1"
93
+ ### 6. Go
165
94
 
166
- # Read shared context
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
- # List context keys
170
- claude-orchestrator list-context-keys
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
- # Delete context
173
- claude-orchestrator delete-context --key "api_version"
103
+ ---
174
104
 
175
- # Watch context for changes
176
- claude-orchestrator watch-context --key "jwt_strategy"
105
+ ## How It Works
177
106
 
178
- # Watch for new tasks
179
- claude-orchestrator watch-tasks
107
+ ### Leader-Worker Model
180
108
 
181
- # Unregister
182
- claude-orchestrator unregister
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
- # Show config
185
- claude-orchestrator config
186
-
187
- # Health check
188
- claude-orchestrator status
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 two instances Tom (Architect) and Jerry (Developer):
158
+ Here's a real flow with a Leader (Tom) and two Workers (Jerry, Bob):
198
159
 
199
- **Tom registers:**
200
- ```json
201
- { "id": "a1b2c3d4...", "name": "Tom", "role": "architect", "status": "idle" }
160
+ **Tom starts the Leader:**
202
161
  ```
203
-
204
- **Jerry registers:**
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
- **Tom lists instances:**
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
- **Tom assigns work:**
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
- **Jerry claims it:**
226
- ```
227
- claim_task Got it! task-0000000000
228
- heartbeat current_task="task-0000000000"
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 gets stuck and asks for help:**
232
- ```
233
- request_help:
234
- question: "What should the JWT expiry be? Access vs refresh token?"
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
- **Tom checks messages and replies:**
239
- ```
240
- poll_messages 1 new message from Jerry
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 records the decision:**
245
- ```
246
- set_context key="jwt_strategy" value="access:15min, refresh:7d, blacklist:redis"
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
- complete_task task_id="task-0000000000" result="PR #42 — implemented login endpoint with tests"
199
+ ```bash
200
+ claude-orchestrator complete-task --task-id task-0000000000 --result "PR #42 — login endpoint with tests"
252
201
  ```
253
202
 
254
- No polling required for task claiming the atomic claim mechanism means Jerry always gets the right task. Messages are delivered instantly via ZooKeeper's persistent-sequential nodes.
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... [EPHEMERAL] Tom's registration
264
- └── f6e5d4c3... [EPHEMERAL] Jerry's registration
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. No deadlocks, no orphans. ZooKeeper handles the lifecycle.
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 the MCP integration)
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 server
310
- claude-orchestrator server
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-code-developer` | Reference for developing Claude Code extensions hooks, settings, MCP, CLI |
331
- | `claude-orchestrator` | Full CLI reference all 21 commands with examples |
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 needed. |
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
- | MCP server host | `--host` flag or `ORCHESTRATOR_HOST` env | `127.0.0.1` |
373
- | MCP server port | `--port` flag or `ORCHESTRATOR_PORT` env | `3100` |
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 with atomic claim
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-server.sh # Server launcher
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
- └── v0.2.0/ # Current TypeScript docs
410
- ├── prd/ # Full spec + architecture
411
- └── operations-guide.md # Step-by-step walkthrough
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, ZooKeeper, and the MCP protocol. Orchestrate responsibly.</sub>
422
+ <sub>Built with TypeScript and ZooKeeper. Orchestrate responsibly.</sub>
430
423
  </p>
@@ -1,22 +1,11 @@
1
- export declare function cmdStatus(zkHosts: string): Promise<void>;
2
- export declare function cmdRegister(zkHosts: string, instanceId: string | undefined, name?: string, role?: string, workDir?: string): Promise<void>;
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 cmdListTasks(zkHosts: string, statusFilter?: string): Promise<void>;
9
- export declare function cmdSendMessage(zkHosts: string, cliInstanceId: string | undefined, content: string, toInstance?: string, broadcast?: boolean, toName?: string): Promise<void>;
10
- export declare function cmdPollMessages(zkHosts: string, cliInstanceId: string | undefined): Promise<void>;
11
- export declare function cmdWaitForMessage(zkHosts: string, cliInstanceId: string | undefined, timeout: number): Promise<void>;
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
11
  leader: boolean;