opencodekit 0.17.9 → 0.17.10

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/dist/index.js CHANGED
@@ -759,7 +759,7 @@ var cac = (name = "") => new CAC(name);
759
759
  // package.json
760
760
  var package_default = {
761
761
  name: "opencodekit",
762
- version: "0.17.9",
762
+ version: "0.17.10",
763
763
  description: "CLI tool for bootstrapping and managing OpenCodeKit projects",
764
764
  keywords: ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
765
765
  license: "MIT",
@@ -9244,21 +9244,21 @@ async function copyOpenCodeOnly(templateRoot, targetDir) {
9244
9244
  }
9245
9245
  var MODEL_PRESETS = {
9246
9246
  free: {
9247
- model: "opencode/kimi-k2.5-free",
9247
+ model: "opencode/glm-5-free",
9248
9248
  agents: {
9249
- build: "opencode/kimi-k2.5-free",
9250
- plan: "opencode/kimi-k2.5-free",
9249
+ build: "opencode/minimax-m2.5-free",
9250
+ plan: "opencode/minimax-m2.5-free",
9251
9251
  review: "opencode/minimax-m2.5-free",
9252
- explore: "opencode/minimax-m2.5-free",
9253
- general: "opencode/minimax-m2.5-free",
9254
- looker: "opencode/kimi-k2.5-free",
9255
- vision: "opencode/kimi-k2.5-free",
9256
- scout: "opencode/minimax-m2.5-free",
9257
- painter: "opencode/kimi-k2.5-free"
9252
+ explore: "opencode/glm-5-free",
9253
+ general: "opencode/glm-5-free",
9254
+ looker: "opencode/minimax-m2.5-free",
9255
+ vision: "opencode/minimax-m2.5-free",
9256
+ scout: "opencode/glm-5-free",
9257
+ painter: "opencode/minimax-m2.5-free"
9258
9258
  }
9259
9259
  },
9260
9260
  recommend: {
9261
- model: "opencode/kimi-k2.5-free",
9261
+ model: "opencode/minimax-m2.5-free",
9262
9262
  agents: {
9263
9263
  build: "github-copilot/claude-opus-4.6",
9264
9264
  plan: "openai/gpt-5.3-codex",
@@ -9266,7 +9266,7 @@ var MODEL_PRESETS = {
9266
9266
  explore: "proxypal/gemini-3-flash",
9267
9267
  general: "github-copilot/gpt-5.2-codex",
9268
9268
  looker: "proxypal/gemini-3-flash",
9269
- vision: "proxypal/gemini-3-pro-high",
9269
+ vision: "proxypal/gemini-3.1-pro-high",
9270
9270
  scout: "proxypal/claude-sonnet-4-6",
9271
9271
  painter: "proxypal/gemini-3-pro-image"
9272
9272
  }
@@ -157,6 +157,10 @@
157
157
  "models": {
158
158
  "claude-haiku-4.5": {
159
159
  "attachment": true,
160
+ "limit": {
161
+ "context": 200000,
162
+ "output": 64000
163
+ },
160
164
  "options": {
161
165
  "thinking_budget": 10000,
162
166
  "type": "enabled"
@@ -181,6 +185,10 @@
181
185
  },
182
186
  "claude-opus-4.5": {
183
187
  "attachment": true,
188
+ "limit": {
189
+ "context": 200000,
190
+ "output": 64000
191
+ },
184
192
  "options": {
185
193
  "thinking_budget": 10000
186
194
  },
@@ -203,7 +211,7 @@
203
211
  "claude-opus-4.6": {
204
212
  "attachment": true,
205
213
  "limit": {
206
- "context": 128000,
214
+ "context": 200000,
207
215
  "output": 64000
208
216
  },
209
217
  "options": {
@@ -248,8 +256,8 @@
248
256
  "claude-sonnet-4.6": {
249
257
  "attachment": true,
250
258
  "limit": {
251
- "context": 128000,
252
- "output": 32000
259
+ "context": 200000,
260
+ "output": 64000
253
261
  },
254
262
  "options": {
255
263
  "thinking": {
@@ -292,6 +300,10 @@
292
300
  },
293
301
  "claude-sonnet-4.5": {
294
302
  "attachment": true,
303
+ "limit": {
304
+ "context": 200000,
305
+ "output": 64000
306
+ },
295
307
  "options": {
296
308
  "thinking_budget": 10000
297
309
  },
@@ -313,6 +325,10 @@
313
325
  },
314
326
  "gpt-5.2": {
315
327
  "attachment": true,
328
+ "limit": {
329
+ "context": 400000,
330
+ "output": 128000
331
+ },
316
332
  "options": {
317
333
  "reasoningEffort": "medium",
318
334
  "reasoningSummary": "auto",
@@ -339,6 +355,10 @@
339
355
  },
340
356
  "gpt-5.2-codex": {
341
357
  "attachment": true,
358
+ "limit": {
359
+ "context": 400000,
360
+ "output": 128000
361
+ },
342
362
  "options": {
343
363
  "reasoningEffort": "medium",
344
364
  "reasoningSummary": "auto",
@@ -472,6 +492,37 @@
472
492
  "fast": {
473
493
  "disabled": true
474
494
  },
495
+ "xhigh": {
496
+ "include": ["reasoning.encrypted_content"],
497
+ "reasoningEffort": "xhigh",
498
+ "reasoningSummary": "auto",
499
+ "textVerbosity": "low"
500
+ },
501
+ "high": {
502
+ "include": ["reasoning.encrypted_content"],
503
+ "reasoningEffort": "high",
504
+ "reasoningSummary": "auto",
505
+ "textVerbosity": "low"
506
+ },
507
+ "medium": {
508
+ "include": ["reasoning.encrypted_content"],
509
+ "reasoningEffort": "medium",
510
+ "reasoningSummary": "auto",
511
+ "textVerbosity": "low"
512
+ }
513
+ }
514
+ },
515
+ "gpt-5.3-codex": {
516
+ "variants": {
517
+ "fast": {
518
+ "disabled": true
519
+ },
520
+ "xhigh": {
521
+ "include": ["reasoning.encrypted_content"],
522
+ "reasoningEffort": "xhigh",
523
+ "reasoningSummary": "auto",
524
+ "textVerbosity": "low"
525
+ },
475
526
  "high": {
476
527
  "include": ["reasoning.encrypted_content"],
477
528
  "reasoningEffort": "high",
@@ -498,47 +549,6 @@
498
549
  "top_p": 0.95
499
550
  },
500
551
  "reasoning": true
501
- },
502
- "kimi-k2.5-free": {
503
- "limit": {
504
- "context": 262144,
505
- "output": 32768
506
- },
507
- "options": {
508
- "interleaved": {
509
- "field": "reasoning_content"
510
- },
511
- "thinking": {
512
- "budgetTokens": 8192,
513
- "reasoning_effort": "high",
514
- "type": "enabled"
515
- }
516
- },
517
- "reasoning": true,
518
- "temperature": true,
519
- "tool_call": true,
520
- "variants": {
521
- "high": {
522
- "interleaved": {
523
- "field": "reasoning_content"
524
- },
525
- "options": {
526
- "reasoning_effort": "high",
527
- "thinkingBudget": 16384,
528
- "type": "enabled"
529
- }
530
- },
531
- "max": {
532
- "interleaved": {
533
- "field": "reasoning_content"
534
- },
535
- "options": {
536
- "reasoning_effort": "high",
537
- "thinkingBudget": 32768,
538
- "type": "enabled"
539
- }
540
- }
541
- }
542
552
  }
543
553
  }
544
554
  },
@@ -11,7 +11,7 @@
11
11
  "type-check": "tsc --noEmit"
12
12
  },
13
13
  "dependencies": {
14
- "@opencode-ai/plugin": "1.2.6"
14
+ "@opencode-ai/plugin": "1.2.10"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@types/node": "^25.3.0",
@@ -348,6 +348,102 @@ swarm({ operation: "sync", action: "pull" });
348
348
  3. **One task per session** - Restart after `br close`
349
349
  4. **Always sync and commit** - `br sync --flush-only` then `git add .beads/ && git commit`
350
350
  5. **Write notes for future agents** - Assume zero conversation context
351
+ 6. **Claim file paths before editing** - Use reserve to declare ownership (multi-agent only)
352
+
353
+ ## File Path Claiming (Multi-Agent Safety)
354
+
355
+ At multi-agent scale, agents editing the same files cause merge conflicts. File path claiming prevents this by making ownership explicit before any edit happens.
356
+
357
+ ### When to Use
358
+
359
+ - **Single agent**: Optional — no conflicts possible
360
+ - **2-10 agents**: Recommended for files touched by multiple tasks
361
+ - **10+ agents**: Required — every file must be claimed before editing
362
+
363
+ ### The Claim/Edit/Release Cycle
364
+
365
+ ```bash
366
+ # 1. CLAIM: Declare intent to edit before touching the file
367
+ br reserve <bead-id> --files "src/auth/service.ts,src/auth/types.ts"
368
+ # → Marks files as owned by this bead
369
+ # → Other agents see the reservation and must wait
370
+
371
+ # 2. EDIT: Make your changes
372
+ # (edit files as normal)
373
+
374
+ # 3. VERIFY: Run gates before releasing
375
+ npm run typecheck && npm run lint
376
+
377
+ # 4. CLOSE: Release ownership when done
378
+ br close <bead-id> --reason "Auth service implemented. Gates passed."
379
+ # → Ownership released automatically on close
380
+ ```
381
+
382
+ ### Checking for Conflicts Before Claiming
383
+
384
+ Before claiming, check if another bead already owns the file:
385
+
386
+ ```bash
387
+ # See all reserved files across active beads
388
+ br list --status in_progress --json | jq '.[].reserved_files'
389
+
390
+ # If conflict detected:
391
+ # → Wait for the other bead to close
392
+ # → Or coordinate with the agent owning that bead
393
+ ```
394
+
395
+ ### Claiming in Delegation Packets
396
+
397
+ Workers MUST declare file claims in their delegation packet:
398
+
399
+ ```markdown
400
+ # Delegation Packet
401
+
402
+ - TASK: task-1 - Implement auth service
403
+ - FILES TO CLAIM BEFORE EDITING:
404
+ - src/auth/service.ts
405
+ - src/auth/types.ts
406
+ - src/auth/middleware.ts
407
+ - MUST NOT EDIT (owned by other tasks):
408
+ - src/db/schema.ts (owned by task-0)
409
+ - src/config.ts (owned by task-2)
410
+ ```
411
+
412
+ ### Conflict Resolution Protocol
413
+
414
+ When two agents want the same file:
415
+
416
+ | Scenario | Resolution |
417
+ | ------------------------------------ | ----------------------------------------------- |
418
+ | File not claimed | Claim it and proceed |
419
+ | File claimed by completed bead | Safe to claim (no active owner) |
420
+ | File claimed by in_progress bead | Wait for bead to close, then claim |
421
+ | Urgent: same file, different workers | Escalate to lead agent to split the file change |
422
+
423
+ ### Anti-Pattern: Claiming After Editing
424
+
425
+ ```bash
426
+ # WRONG — edit first, claim after → conflict already happened
427
+ edit src/auth/service.ts
428
+ br reserve bead-1 --files "src/auth/service.ts"
429
+
430
+ # RIGHT — claim first, then edit
431
+ br reserve bead-1 --files "src/auth/service.ts"
432
+ edit src/auth/service.ts
433
+ ```
434
+
435
+ ### Quick Reference: File Claiming
436
+
437
+ ```
438
+ BEFORE EDITING (multi-agent):
439
+ br reserve <id> --files "src/file.ts"
440
+
441
+ CHECK OWNERSHIP:
442
+ br list --status in_progress --json | jq '.[].reserved_files'
443
+
444
+ RELEASE:
445
+ br close <id> --reason "..." ← auto-releases files
446
+ ```
351
447
 
352
448
  ## Best Practices
353
449
 
@@ -59,3 +59,107 @@ Extend it by:
59
59
  ❌ Keeping old file reads after editing complete
60
60
  ❌ Reading entire files when you only need a function
61
61
  ❌ Ignoring AGENTS.md hierarchy
62
+
63
+ ## Static vs Runtime Context (Longshot Pattern)
64
+
65
+ At scale (10+ agents), the difference between **static context** and **runtime context** is the difference between a coherent swarm and chaos.
66
+
67
+ ### Definitions
68
+
69
+ | Type | What It Is | When Loaded | Example |
70
+ | ------------------- | ------------------------------------------------------------ | ---------------------- | --------------------------------------- |
71
+ | **Static Context** | Always-on knowledge — invariants, constraints, project shape | Always (auto-injected) | AGENTS.md, tech-stack.md, user.md |
72
+ | **Runtime Context** | Per-task injections — what THIS task needs right now | Per-task | Delegation packet, task spec, file list |
73
+
74
+ ### Why the Split Matters
75
+
76
+ Without separation, context becomes soup:
77
+
78
+ - Agent loads everything → hits token limit → degrades
79
+ - Agents share stale context → conflicting decisions
80
+ - No clear source of truth for "what is the objective"
81
+
82
+ With separation:
83
+
84
+ - Static = immune to session pollution (always fresh)
85
+ - Runtime = scoped to task (cleaned up when done)
86
+ - Result: agents stay coherent at 200-agent scale
87
+
88
+ ### Task Packet Format
89
+
90
+ Every task dispatched to a worker agent MUST include an explicit context block:
91
+
92
+ ```markdown
93
+ ## Task Packet
94
+
95
+ ### Static Context (always available)
96
+
97
+ - Project rules: AGENTS.md
98
+ - Tech stack: .opencode/memory/project/tech-stack.md
99
+ - Gotchas: .opencode/memory/project/gotchas.md
100
+
101
+ ### Runtime Context (this task only)
102
+
103
+ - Objective: [one sentence]
104
+ - Scope: [files this task may touch]
105
+ - Constraints: [must_do / must_not_do]
106
+ - Dependencies: [what was produced by prior tasks]
107
+ - Verification: [acceptance commands]
108
+ ```
109
+
110
+ ### Injection Pattern
111
+
112
+ When spawning workers, always inject runtime context explicitly:
113
+
114
+ ```typescript
115
+ // WRONG: Vague prompt — agent guesses context
116
+ Task({ prompt: "Implement auth service" });
117
+
118
+ // RIGHT: Explicit static + runtime context split
119
+ Task({
120
+ prompt: `## Static Context
121
+ AGENTS.md governs all decisions. Tech stack: Bun, TypeScript strict mode.
122
+
123
+ ## Runtime Context
124
+ Objective: Implement JWT auth service in src/auth/service.ts.
125
+ Scope: Only modify src/auth/ directory.
126
+ Dependencies: Schema defined in src/db/schema.ts (from task-1).
127
+ Constraints:
128
+ MUST DO: Use zod for input validation
129
+ MUST NOT DO: Add new dependencies without approval
130
+ Verification:
131
+ npm run typecheck && npm run lint && bun test src/auth/`,
132
+ });
133
+ ```
134
+
135
+ ### Context Pollution Anti-Patterns
136
+
137
+ | Anti-Pattern | Problem | Fix |
138
+ | ------------------------------------------- | --------------------------------- | ------------------------------------- |
139
+ | Passing entire AGENTS.md as runtime context | Bloats token budget on every task | Load via static injection only |
140
+ | Runtime state persisting across waves | Stale context poisons next wave | Clear runtime state between waves |
141
+ | No objective in task packet | Agent drifts from goal | Always include one-sentence objective |
142
+ | Injection without scope | Agent modifies wrong files | Always declare file scope |
143
+
144
+ ### Static Context Files (Always Inject)
145
+
146
+ These files are the project's invariant layer. Always available, never stale:
147
+
148
+ ```
149
+ .opencode/memory/project/
150
+ ├── user.md # User preferences, workflow rules
151
+ ├── tech-stack.md # Frameworks, constraints
152
+ ├── gotchas.md # Footguns, warnings
153
+ └── project.md # Vision, success criteria
154
+ ```
155
+
156
+ ### Runtime Context Files (Per-Task)
157
+
158
+ These are created fresh per task and cleaned up after:
159
+
160
+ ```
161
+ .beads/artifacts/<task-id>/
162
+ ├── delegation.md # Task-specific instructions
163
+ ├── spec.md # Technical requirements
164
+ └── progress.txt # Task state (append-only)
165
+ ```
@@ -56,6 +56,13 @@ If concerns: Wait for human to decide and resubmit
56
56
 
57
57
  **Default: First 3 tasks**
58
58
 
59
+ **Before starting a batch**: create a wave-start git tag for safe rollback:
60
+
61
+ ```bash
62
+ # Tag the safe point before this batch/wave
63
+ git tag wave-${BATCH_NUMBER}-start
64
+ ```
65
+
59
66
  For each task:
60
67
 
61
68
  1. Mark as in_progress
@@ -63,12 +70,20 @@ For each task:
63
70
  3. Run verifications as specified
64
71
  4. Mark as completed
65
72
 
73
+ **After batch passes all gates**: create a wave-complete tag:
74
+
75
+ ```bash
76
+ # Seal the completed wave - confirms all gates passed
77
+ git tag wave-${BATCH_NUMBER}-complete
78
+ ```
79
+
66
80
  ### Step 3: Report
67
81
 
68
82
  When batch complete:
69
83
 
70
84
  - Show what was implemented
71
85
  - Show verification output
86
+ - Show wave tag created (e.g., `wave-1-complete`)
72
87
  - Say: "Ready for feedback."
73
88
 
74
89
  ### Step 4: Continue
@@ -87,6 +102,61 @@ After all tasks complete and verified:
87
102
  - **REQUIRED SUB-SKILL:** Use skill({ name: "finishing-a-development-branch" })
88
103
  - Follow that skill to verify tests, present options, execute choice
89
104
 
105
+ ## Wave-Level Rollback with Git Tags
106
+
107
+ Git tags act as checkpoints between waves. If a wave fails irrecoverably, roll back to the last known-good state.
108
+
109
+ ### Tag Protocol
110
+
111
+ | When | Command | Purpose |
112
+ | ---------------------------- | ------------------------------- | ------------------------- |
113
+ | Before starting any batch | `git tag wave-N-start` | Mark rollback point |
114
+ | After batch passes all gates | `git tag wave-N-complete` | Seal confirmed-good state |
115
+ | On irrecoverable failure | `git reset --hard wave-N-start` | Restore to pre-wave state |
116
+ | Listing all wave checkpoints | `git tag --list "wave-*"` | Audit trail of execution |
117
+
118
+ ### When to Rollback
119
+
120
+ Roll back (with user confirmation) when:
121
+
122
+ - Build gates fail twice consecutively in the same wave
123
+ - Unexpected destructive changes were made
124
+ - Drift check detects unrecoverable scope creep
125
+ - Tests were broken and the cause is unclear
126
+
127
+ **Always ask the user before running `git reset --hard`** - it discards uncommitted changes irreversibly.
128
+
129
+ ### Rollback Steps
130
+
131
+ ```bash
132
+ # 1. Identify safe point
133
+ git tag --list "wave-*"
134
+ # e.g.: wave-1-complete wave-2-start wave-2-complete wave-3-start
135
+
136
+ # 2. Confirm with user: rollback to which tag?
137
+ # e.g.: git reset --hard wave-2-complete (last known good)
138
+
139
+ # 3. Execute rollback (ONLY after user confirms)
140
+ git reset --hard wave-2-complete
141
+
142
+ # 4. Verify state is clean
143
+ npm run typecheck && npm run lint
144
+
145
+ # 5. Re-plan the failed batch with new approach
146
+ ```
147
+
148
+ ### Tag Naming Convention
149
+
150
+ ```
151
+ wave-1-start # Before batch 1 starts
152
+ wave-1-complete # After batch 1 passes all gates
153
+ wave-2-start # Before batch 2 starts
154
+ wave-2-complete # After batch 2 passes all gates
155
+ ...
156
+ ```
157
+
158
+ Use numeric batch numbers, not task names, for predictable reference.
159
+
90
160
  ## When to Stop and Ask for Help
91
161
 
92
162
  **STOP executing immediately when:**
@@ -175,6 +175,107 @@ git worktree remove <worktree-path>
175
175
  | 3. Keep as-is | - | - | ✓ | - |
176
176
  | 4. Discard | - | - | - | ✓ (force) |
177
177
 
178
+ ## Mandatory Build Gates (Longshot Pattern)
179
+
180
+ **Build gates are non-optional before any merge/PR/close.** Advisory verification has failed at scale — gates must be enforced as hard blockers.
181
+
182
+ ### Gate Sequence
183
+
184
+ Every bead MUST pass all three gates in order. No exceptions.
185
+
186
+ ```bash
187
+ # Gate 1: Typecheck
188
+ npm run typecheck
189
+ # Must exit 0. If fails → STOP. Fix types first.
190
+
191
+ # Gate 2: Lint
192
+ npm run lint
193
+ # Must exit 0. If fails → STOP. Run npm run lint:fix, then fix remaining.
194
+
195
+ # Gate 3: Tests
196
+ bun test
197
+ # Must exit 0. If fails → STOP. Fix failing tests first.
198
+ ```
199
+
200
+ ### Gate Enforcement Script
201
+
202
+ Run before every merge, PR creation, or bead close:
203
+
204
+ ```bash
205
+ #!/bin/bash
206
+ # Run mandatory gates — all must pass
207
+
208
+ echo "Gate 1/3: Typecheck..."
209
+ npm run typecheck || { echo "FAILED: Fix type errors before proceeding."; exit 1; }
210
+
211
+ echo "Gate 2/3: Lint..."
212
+ npm run lint || {
213
+ echo "Attempting auto-fix..."
214
+ npm run lint:fix
215
+ npm run lint || { echo "FAILED: Fix lint errors before proceeding."; exit 1; }
216
+ }
217
+
218
+ echo "Gate 3/3: Tests..."
219
+ bun test || { echo "FAILED: Fix failing tests before proceeding."; exit 1; }
220
+
221
+ echo "All gates passed. Safe to merge/PR/close."
222
+ ```
223
+
224
+ ### Gate Failure Response
225
+
226
+ | Gate Failure | First Action | If Still Failing |
227
+ | ------------ | -------------------------------- | --------------------------- |
228
+ | Typecheck | Fix type errors at reported line | Use LSP hover for type info |
229
+ | Lint | Run `npm run lint:fix` | Fix remaining manually |
230
+ | Tests | Read failing test output | Fix implementation or test |
231
+
232
+ ### Hard Rules
233
+
234
+ **NEVER:**
235
+
236
+ - Close a bead without passing all 3 gates
237
+ - Create a PR without passing all 3 gates
238
+ - Merge locally without passing all 3 gates on merged result
239
+ - Skip gates "because the change is small"
240
+
241
+ **ALWAYS:**
242
+
243
+ - Run gates after EVERY non-trivial file change
244
+ - Re-run gates after fixing gate failures (to catch regressions)
245
+ - Run gates on the merged result, not just the branch
246
+
247
+ ### Integration with Bead Workflow
248
+
249
+ ```bash
250
+ # Before closing any bead:
251
+ npm run typecheck && npm run lint && bun test
252
+
253
+ # If all pass:
254
+ br close <id> --reason "Implementation complete. All gates passed."
255
+ br sync --flush-only
256
+
257
+ # If any fail:
258
+ # STOP. Fix. Re-run gates. Then close.
259
+ ```
260
+
261
+ ### Gate State in Delegation Packets
262
+
263
+ Workers must include gate results in their completion report:
264
+
265
+ ```markdown
266
+ ## Completion Report
267
+
268
+ ### Gate Results
269
+
270
+ - [ ] typecheck: PASS / FAIL (error: ...)
271
+ - [ ] lint: PASS / FAIL (error: ...)
272
+ - [ ] tests: PASS / FAIL (N failed, N passed)
273
+
274
+ ### Gate Command Used
275
+
276
+ `npm run typecheck && npm run lint && bun test`
277
+ ```
278
+
178
279
  ## Common Mistakes
179
280
 
180
281
  **Skipping test verification**
@@ -15,10 +15,11 @@ Coordinate multiple agents working on independent tasks in parallel using Kimi K
15
15
 
16
16
  ## Overview
17
17
 
18
- **Swarm = Leader + Workers + Progress Tracking + Todo Persistence**
18
+ **Swarm = Leader + Workers + Reconciler + Progress Tracking + Todo Persistence**
19
19
 
20
20
  - **Leader (build agent)**: Orchestrates the swarm - analyzes tasks, spawns workers, monitors progress, synthesizes results
21
21
  - **Workers (general/explore/review/plan agents)**: Execute independent tasks - read delegation, make changes, report progress
22
+ - **Reconciler**: Watches for CI failures, detects broken builds, auto-spawns fix tasks - this is the self-healing mechanism
22
23
  - **Progress Tracker (swarm-progress.jsonl)**: Real-time progress updates with TUI visualization
23
24
  - **Todo Persistence (swarm-todos.json)**: Cross-session recovery for interrupted swarms
24
25
 
@@ -68,8 +69,8 @@ Coordinate multiple agents working on independent tasks in parallel using Kimi K
68
69
  │ - Monitors progress via swarm tool │
69
70
  │ - Synthesizes final results │
70
71
  └─────────────────────────────────────────────────────────────────┘
71
- │ │ │
72
- ▼ ▼ ▼
72
+ │ │ │
73
+ ▼ ▼ ▼
73
74
  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
74
75
  │ WORKER-1 │ │ WORKER-2 │ │ WORKER-3 │
75
76
  │ (general) │ │ (general) │ │ (general) │
@@ -79,15 +80,288 @@ Coordinate multiple agents working on independent tasks in parallel using Kimi K
79
80
  │ - Execute │ │ - Execute │ │ - Execute │
80
81
  │ - Report │ │ - Report │ │ - Report │
81
82
  └─────────────┘ └─────────────┘ └─────────────┘
82
- │ │ │
83
- └────────────────────┼────────────────────┘
84
-
85
- ┌─────────────────┐
86
- PROGRESS +
87
- TODO PERSIST
88
- └─────────────────┘
83
+ │ │ │
84
+ └────────────────────┼────────────────────┘
85
+
86
+ ┌─────────────────┐
87
+ RECONCILER
88
+
89
+ │ - Watch CI │
90
+ │ - Detect broken │
91
+ │ - Spawn fixes │
92
+ └─────────────────┘
93
+
94
+
95
+ ┌─────────────────┐
96
+ │ PROGRESS + │
97
+ │ TODO PERSIST │
98
+ └─────────────────┘
89
99
  ```
90
100
 
101
+ ## Reconciler Agent Pattern (Self-Healing)
102
+
103
+ The reconciler is the key to scaling beyond 50+ agents. Without reconciliation, broken builds cascade and the swarm collapses. The reconciler provides **continuous self-healing** by watching for failures and spawning targeted fix tasks.
104
+
105
+ ### When to Use Reconciler
106
+
107
+ - **50+ agents** running in parallel → **REQUIRED**
108
+ - **10-50 agents** → Recommended
109
+ - **<10 agents** → Optional (leader can handle)
110
+
111
+ ### Reconciler Responsibilities
112
+
113
+ 1. **Watch CI/Build Status**: Monitor build gates continuously
114
+ 2. **Detect Failures**: Identify which worker caused the failure
115
+ 3. **Analyze Root Cause**: Determine if it's a merge conflict, test failure, or type error
116
+ 4. **Spawn Fix Tasks**: Create targeted fix tasks with context about what failed
117
+ 5. **Verify Fix**: Wait for fix to pass gates before continuing
118
+
119
+ ### Reconciler vs Leader
120
+
121
+ | Aspect | Leader | Reconciler |
122
+ | -------------- | ----------------------------- | ----------------------------- |
123
+ | Focus | Orchestration, spawning | Recovery, fixing |
124
+ | Runs | At swarm start, between waves | Continuously during execution |
125
+ | On failure | Spawns workers | Spawns fix tasks |
126
+ | Failure impact | Can't start work | Wave can't complete |
127
+
128
+ ### Implementing Reconciler
129
+
130
+ The reconciler runs in a loop during swarm execution:
131
+
132
+ ```typescript
133
+ // Reconciler runs in background during swarm execution
134
+ async function runReconciler(teamName: string, buildCommand: string) {
135
+ while (swarmActive) {
136
+ // 1. Check build status
137
+ const status = await swarm({
138
+ operation: "monitor",
139
+ operation: "status",
140
+ team_name: teamName,
141
+ });
142
+ const stats = JSON.parse(status).summary;
143
+
144
+ // 2. If there are errors, investigate
145
+ if (stats.errors > 0) {
146
+ // 3. Get error details
147
+ const errors = await getWorkerErrors(teamName);
148
+
149
+ for (const error of errors) {
150
+ // 4. Analyze root cause
151
+ const cause = await analyzeError(error);
152
+
153
+ // 5. Spawn fix task
154
+ const fixBead = await br create({
155
+ title: `Fix: ${cause.summary}`,
156
+ type: "bug",
157
+ description: `Detected by reconciler: ${error.message}. Root cause: ${cause.rootCause}. Suggested fix: ${cause.suggestion}`,
158
+ });
159
+
160
+ // 6. Assign to targeted worker
161
+ await Task({
162
+ subagent_type: "general",
163
+ description: `Fix ${error.worker}`,
164
+ prompt: `Fix the error in ${error.file}.
165
+
166
+ Error: ${error.message}
167
+ Root cause: ${cause.rootCause}
168
+ Suggested fix: ${cause.suggestion}
169
+
170
+ Run: ${buildCommand}
171
+ Verify: npm run typecheck && npm run lint`,
172
+ });
173
+ }
174
+ }
175
+
176
+ // Wait before next check
177
+ await sleep(30000); // Check every 30 seconds
178
+ }
179
+ }
180
+ ```
181
+
182
+ ### Error Analysis Patterns
183
+
184
+ The reconciler categorizes errors:
185
+
186
+ | Error Type | Detection | Fix Strategy |
187
+ | -------------- | -------------------------------- | ---------------------------- |
188
+ | Merge conflict | "CONFLICT" in output, git status | Re-base, resolve, force push |
189
+ | Type error | "typecheck failed" | Fix types, run typecheck |
190
+ | Test failure | "test failed", "expect" mismatch | Fix test or implementation |
191
+ | Lint error | "lint failed", formatting issues | Run lint:fix |
192
+ | Build error | "build failed", bundler errors | Fix imports, dependencies |
193
+
194
+ ### Spawning Fix Tasks
195
+
196
+ When the reconciler spawns a fix task, it includes:
197
+
198
+ ```typescript
199
+ // Create fix task with full context
200
+ await br create({
201
+ title: `Fix: ${error.type} in ${error.file}`,
202
+ type: "bug",
203
+ description: `## Error Detected
204
+ - Worker: ${error.worker}
205
+ - File: ${error.file}
206
+ - Error: ${error.message}
207
+ - Timestamp: ${error.timestamp}
208
+
209
+ ## Root Cause Analysis
210
+ ${cause.explanation}
211
+
212
+ ## Suggested Fix
213
+ ${cause.suggestion}
214
+
215
+ ## Verification
216
+ Run: ${buildCommand}
217
+ Must pass before wave can complete.`,
218
+ });
219
+ ```
220
+
221
+ ### Reconciler in Wave Execution
222
+
223
+ Add reconciler monitoring to each wave:
224
+
225
+ ```typescript
226
+ // Execute wave with reconciler
227
+ async function executeWaveWithReconciler(wave, teamName) {
228
+ // Start reconciler in background
229
+ const reconciler = runReconciler(teamName, "npm run typecheck && npm run lint");
230
+
231
+ // Execute workers in this wave
232
+ await Promise.all(wave.tasks.map(spawnWorker));
233
+
234
+ // Wait for all workers + reconciler to complete
235
+ await reconciler;
236
+
237
+ // Verify wave output before proceeding
238
+ await bash("npm run typecheck && npm run lint");
239
+ }
240
+ ```
241
+
242
+ ### Example: Full Swarm with Reconciler
243
+
244
+ ```typescript
245
+ // Full swarm execution with reconciler
246
+ async function runSwarmWithReconciler(tasks, teamName) {
247
+ // 1. Analyze and create waves
248
+ const waves = createWaves(tasks);
249
+
250
+ // 2. Execute each wave with reconciler
251
+ for (const wave of waves) {
252
+ console.log(`Executing wave ${wave.number} with ${wave.tasks.length} tasks`);
253
+
254
+ // Start reconciler for this wave
255
+ const reconcilerPromise = runReconciler(teamName, "npm run typecheck && npm run lint");
256
+
257
+ // Spawn workers
258
+ await Promise.all(wave.tasks.map((task) => spawnWorker(task, teamName)));
259
+
260
+ // Wait for reconciler to finish fixing any errors
261
+ await reconcilerPromise;
262
+
263
+ // Verify wave output
264
+ const result = await bash("npm run typecheck && npm run lint");
265
+ if (!result.success) {
266
+ throw new Error(`Wave ${wave.number} failed gates`);
267
+ }
268
+
269
+ console.log(`Wave ${wave.number} complete`);
270
+ }
271
+ }
272
+ ```
273
+
274
+ ## Drift Check After Each Wave
275
+
276
+ After every wave completes and before starting the next, run a **drift check** to verify the codebase has not deviated from the intended state. Accumulated drift between waves is the primary cause of cascading failures in large swarms.
277
+
278
+ **Drift** = any difference between actual codebase state and the plan's expected state at a wave boundary.
279
+
280
+ ### What to Check
281
+
282
+ | Check | Command | Passing Condition |
283
+ | ----------------- | -------------------------------------------------- | ------------------------------ |
284
+ | Build gates | `npm run typecheck && npm run lint` | Zero errors |
285
+ | Unexpected files | `git diff --name-only HEAD` | Only planned files modified |
286
+ | Missing artifacts | Verify expected files exist | All declared outputs present |
287
+ | Scope adherence | Compare `git status` vs wave's declared file scope | No out-of-scope files modified |
288
+
289
+ ### Drift Check Protocol
290
+
291
+ Run after every wave, before spawning the next:
292
+
293
+ ```typescript
294
+ async function driftCheckAfterWave(wave: Wave, expectedFiles: string[]) {
295
+ console.log(`\n=== DRIFT CHECK: Wave ${wave.number} ===`);
296
+
297
+ // 1. Build gates must pass
298
+ const gates = await bash("npm run typecheck && npm run lint");
299
+ if (!gates.success) {
300
+ throw new Error(`Wave ${wave.number} drift: build gates failed\n${gates.output}`);
301
+ }
302
+
303
+ // 2. Detect unexpected file modifications
304
+ const changedFiles = await bash("git diff --name-only HEAD");
305
+ const actualFiles = changedFiles.output.trim().split("\n").filter(Boolean);
306
+ const unexpected = actualFiles.filter((f) => !expectedFiles.includes(f));
307
+
308
+ if (unexpected.length > 0) {
309
+ console.warn(`⚠️ Unexpected files modified in wave ${wave.number}:`);
310
+ unexpected.forEach((f) => console.warn(` - ${f}`));
311
+ }
312
+
313
+ // 3. Verify declared artifacts exist
314
+ for (const artifact of wave.expectedArtifacts ?? []) {
315
+ const exists = await bash(`test -f ${artifact} && echo "ok" || echo "missing"`);
316
+ if (exists.output.trim() === "missing") {
317
+ throw new Error(`Wave ${wave.number} drift: expected artifact missing: ${artifact}`);
318
+ }
319
+ }
320
+
321
+ console.log(`✓ Drift check passed: Wave ${wave.number}`);
322
+ }
323
+ ```
324
+
325
+ ### Integration in Wave Execution
326
+
327
+ Call drift check between every wave:
328
+
329
+ ```typescript
330
+ for (let i = 0; i < waves.length; i++) {
331
+ const wave = waves[i];
332
+ const reconciler = runReconciler(teamName, "npm run typecheck && npm run lint");
333
+
334
+ await Promise.all(wave.tasks.map((task) => spawnWorker(task, teamName)));
335
+ await reconciler;
336
+
337
+ // MANDATORY: Drift check before next wave
338
+ await driftCheckAfterWave(
339
+ wave,
340
+ wave.tasks.flatMap((t) => t.assignedFiles),
341
+ );
342
+
343
+ console.log(`✓ Wave ${i + 1}/${waves.length} complete and verified`);
344
+ }
345
+ ```
346
+
347
+ ### Drift Response Protocol
348
+
349
+ | Drift Type | Severity | Action |
350
+ | ------------------------ | -------- | ------------------------------------------------ |
351
+ | Build gate failure | Critical | Stop swarm, run reconciler, fix before next wave |
352
+ | Unexpected file modified | Warning | Review change, revert if out of scope |
353
+ | Missing artifact | Critical | Re-run failed worker task, verify output |
354
+ | Scope creep | Warning | Escalate to user if >3 unexpected files changed |
355
+
356
+ ### When Drift Is Unrecoverable
357
+
358
+ If drift check fails twice in a row on the same wave:
359
+
360
+ 1. **Stop the swarm** - don't start next wave
361
+ 2. **Report to user**: exact drift details, failing gate output, list of unexpected files
362
+ 3. **Rollback option**: use `git reset --hard <wave-N-start-tag>` (see `executing-plans` skill)
363
+ 4. **Never paper over drift** - proceeding with known drift compounds into cascading failure
364
+
91
365
  ## Swarm Launch Flow - PARL Pattern (7 Steps)
92
366
 
93
367
  ### Step 0: Task Analysis (Anti-Serial-Collapse + Dependency Graph)
@@ -706,3 +980,84 @@ This renders the beautiful TUI block and shows:
706
980
  7. **Use dependency graph** - Spawn workers in parallelizable_groups order
707
981
  8. **Graceful shutdown** - Leader waits for all workers, syncs back to Beads
708
982
  9. **Use tmux for visibility** - Enable visual monitoring when available
983
+ 10. **Use reconciler at scale** - Required for 50+ agents, recommended for 10+
984
+ 11. **Reconciler watches continuously** - Spawns fix tasks on detected failures
985
+
986
+ ## Tier Enforcement (Longshot Pattern)
987
+
988
+ For multi-agent execution at scale (10+ agents), enforce explicit tier hierarchy. This is the Longshot pattern that enabled 200 agents to build Minecraft.
989
+
990
+ ### Tier System
991
+
992
+ | Tier | Role | Swarm Equivalent | Responsibility |
993
+ | --------------- | --------------------- | ---------------- | -------------------------------------------------------------- |
994
+ | **planner** | Lead orchestrator | Build agent | Analyzes scope, decomposes into sub-tasks, coordinates workers |
995
+ | **sub-planner** | Mid-level coordinator | N/A | Takes planner output, further decomposes, assigns to workers |
996
+ | **worker** | Execution agent | Worker agents | Executes assigned work, reports progress |
997
+
998
+ ### When Tiers Are Required
999
+
1000
+ - **<10 agents**: Optional - flat decomposition works
1001
+ - **10-50 agents**: Recommended - planner + workers
1002
+ - **50+ agents**: Required - planner + sub-planners + workers
1003
+
1004
+ ### Enforcing Tier Boundaries
1005
+
1006
+ The swarm leader enforces tier boundaries:
1007
+
1008
+ ```typescript
1009
+ // Tier enforcement in swarm execution
1010
+ async function enforceTiers(waves, tierConfig) {
1011
+ // Wave 1: Planner tasks only
1012
+ const planners = waves.filter((w) => w.tier === "planner");
1013
+ await executeWave(planners);
1014
+
1015
+ // Wave 2: Sub-planner tasks (if any)
1016
+ const subPlanners = waves.filter((w) => w.tier === "sub-planner");
1017
+ await executeWave(subPlanners);
1018
+
1019
+ // Wave 3+: Worker tasks
1020
+ const workers = waves.filter((w) => w.tier === "worker");
1021
+ await executeWave(workers);
1022
+ }
1023
+ ```
1024
+
1025
+ ### Handoff Contracts Between Tiers
1026
+
1027
+ Each tier must declare handoff contracts:
1028
+
1029
+ ```typescript
1030
+ // Planner declares what it produces for sub-planners
1031
+ const plannerHandoff = {
1032
+ produces: [
1033
+ { artifact: "docs/auth-design.md", format: "markdown" },
1034
+ { artifact: "tasks/auth-tasks.json", format: "json" },
1035
+ ],
1036
+ consumedBy: ["sub-planner-auth"],
1037
+ };
1038
+
1039
+ // Worker declares what it consumes from sub-planners
1040
+ const workerHandoff = {
1041
+ consumes: [{ artifact: "tasks/auth-tasks.json", format: "json" }],
1042
+ produces: [{ artifact: "src/auth/service.ts", format: "typescript" }],
1043
+ };
1044
+ ```
1045
+
1046
+ ### Anti-Pattern: Flat Decomposition at Scale
1047
+
1048
+ Without tiers, 20 agents get 20 flat tasks → chaos:
1049
+
1050
+ - Workers step on each other
1051
+ - No coordination between related work
1052
+ - Merge conflicts everywhere
1053
+ - No clear ownership
1054
+
1055
+ With tiers (Longshot pattern):
1056
+
1057
+ ```
1058
+ Lead Planner → Sub-planner A → Worker 1, 2, 3
1059
+ → Sub-planner B → Worker 4, 5, 6
1060
+ Sub-planner C → Worker 7, 8, 9
1061
+ ```
1062
+
1063
+ This mirrors real engineering orgs: lead → tech lead → IC. The architecture is the differentiator.
@@ -90,10 +90,119 @@ Task C (User API): needs Task A, creates src/api/users.ts
90
90
  Wave 1: A, B (parallel)
91
91
  Wave 2: C (after Wave 1)
92
92
 
93
+ ````
94
+
95
+ ## Tiered Task Hierarchy
96
+
97
+ For multi-agent execution at scale (10+ agents), use explicit tier declarations. This prevents flat decomposition that fails when many agents work in parallel.
98
+
99
+ ### Tier Definitions
100
+
101
+ | Tier | Role | Description | Example |
102
+ |------|------|-------------|---------|
103
+ | **planner** | Lead orchestrator | Analyzes scope, decomposes into sub-tasks, coordinates workers | "Design auth system" |
104
+ | **sub-planner** | Mid-level coordinator | Takes planner output, further decomposes, assigns to workers | "Break auth into API, model, middleware" |
105
+ | **worker** | Execution agent | Executes assigned work, reports progress | "Implement auth service" |
106
+
107
+ ### When to Use Tiers
108
+
109
+ - **<10 agents**: Optional - flat decomposition works
110
+ - **10-50 agents**: Recommended - planner + workers
111
+ - **50+ agents**: Required - planner + sub-planners + workers
112
+
113
+ ### Tier Declaration Format
114
+
115
+ Add tier metadata to each task:
116
+
117
+ ```markdown
118
+ ### Task 1: Design Auth System
119
+
120
+ **Tier:** planner
121
+
122
+ **Files:**
123
+ - Create: `docs/auth-design.md`
124
+
125
+ This task decomposes the auth feature into sub-tasks for implementation.
126
+ ````
127
+
128
+ ### Handoff Contracts
129
+
130
+ Tasks must declare what they produce for downstream tasks:
131
+
132
+ ```markdown
133
+ ### Handoff Contract
134
+
135
+ **Produces:**
136
+
137
+ - `docs/auth-design.md` - Architecture decision document
138
+
139
+ **Consumed By:**
140
+
141
+ - Task 2: Implement Auth Service
142
+ - Task 3: Add Auth Tests
143
+ ```
144
+
145
+ ### Tier Enforcement in Plans
146
+
147
+ ```markdown
148
+ # [Feature Name] Implementation Plan
149
+
150
+ > **Tier Structure:**
151
+ >
152
+ > - **Planners (2):** Task 1, Task 5
153
+ > - **Workers (6):** Tasks 2,3,4,6,7,8
154
+
155
+ ## Task Hierarchy
156
+
157
+ ### Tier 1: Planner Tasks (Orchestration)
158
+
159
+ ### Task 1: [Planner] Design Auth System
160
+
161
+ ### Task 5: [Planner] Design API Layer
162
+
163
+ ### Tier 2: Worker Tasks (Execution)
164
+
165
+ ### Task 2: [Worker] Implement Auth Service
166
+
167
+ ### Task 3: [Worker] Add Auth Middleware
168
+
169
+ ### Task 4: [Worker] Write Auth Tests
93
170
  ```
94
171
 
172
+ ### Wave Execution with Tiers
173
+
174
+ When executing with tiers:
175
+
176
+ 1. **Planner waves** execute first (scope definition)
177
+ 2. **Worker waves** execute after planner output is ready
178
+ 3. **Sub-planners** sit between, bridging planner → worker
179
+
180
+ ```markdown
181
+ Wave 1 (Planners): Task 1, Task 5
182
+ Wave 2 (Workers): Tasks 2, 3, 4 (after Task 1)
183
+ Wave 3 (Workers): Tasks 6, 7, 8 (after Task 5)
95
184
  ```
96
185
 
186
+ ### Anti-Pattern: Flat Decomposition at Scale
187
+
188
+ Without tiers, 20 agents get 20 flat tasks → chaos:
189
+
190
+ - Workers step on each other
191
+ - No coordination between related work
192
+ - Merge conflicts everywhere
193
+
194
+ With tiers, the structure emerges:
195
+
196
+ ```
197
+ Planner → Sub-planner A → Worker 1, 2, 3
198
+ → Worker 4, 5
199
+ Sub-planner B → Worker 6, 7
200
+ ```
201
+
202
+ This mirrors real engineering orgs: lead → tech lead → IC.
203
+
204
+ `````
205
+
97
206
  ## Context Budget
98
207
 
99
208
  Target: ~50% context per plan execution
@@ -130,7 +239,8 @@ Maximum: 2-3 tasks per plan
130
239
  def test_specific_behavior():
131
240
  result = function(input)
132
241
  assert result == expected
133
- ```
242
+ `````
243
+
134
244
  ````
135
245
 
136
246
  **Step 2: Run test to verify it fails**
@@ -187,3 +297,4 @@ After saving the plan, offer execution choice:
187
297
  - Guide them to open new session in worktree
188
298
  - **REQUIRED SUB-SKILL:** New session uses skill({ name: "executing-plans" })
189
299
  ```
300
+ ````
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencodekit",
3
- "version": "0.17.9",
3
+ "version": "0.17.10",
4
4
  "description": "CLI tool for bootstrapping and managing OpenCodeKit projects",
5
5
  "keywords": ["agents", "cli", "mcp", "opencode", "opencodekit", "template"],
6
6
  "license": "MIT",