opencodekit 0.17.8 → 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 +24 -24
- package/dist/template/.opencode/opencode.json +229 -98
- package/dist/template/.opencode/package.json +3 -3
- package/dist/template/.opencode/skill/beads/SKILL.md +96 -0
- package/dist/template/.opencode/skill/context-engineering/SKILL.md +104 -0
- package/dist/template/.opencode/skill/executing-plans/SKILL.md +70 -0
- package/dist/template/.opencode/skill/finishing-a-development-branch/SKILL.md +101 -0
- package/dist/template/.opencode/skill/swarm-coordination/SKILL.md +365 -10
- package/dist/template/.opencode/skill/writing-plans/SKILL.md +112 -1
- package/package.json +9 -9
|
@@ -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
|
-
|
|
87
|
-
|
|
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.
|
|
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",
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
"format:check": "oxfmt --check"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ai-sdk/provider": "^3.0.
|
|
39
|
-
"@ai-sdk/provider-utils": "^4.0.
|
|
38
|
+
"@ai-sdk/provider": "^3.0.8",
|
|
39
|
+
"@ai-sdk/provider-utils": "^4.0.15",
|
|
40
40
|
"@clack/prompts": "^0.7.0",
|
|
41
|
-
"@opencode-ai/plugin": "^1.
|
|
42
|
-
"@opentui/core": "^0.1.
|
|
43
|
-
"@opentui/solid": "^0.1.
|
|
41
|
+
"@opencode-ai/plugin": "^1.2.6",
|
|
42
|
+
"@opentui/core": "^0.1.80",
|
|
43
|
+
"@opentui/solid": "^0.1.80",
|
|
44
44
|
"cac": "^6.7.14",
|
|
45
45
|
"cli-table3": "^0.6.5",
|
|
46
46
|
"diff": "^8.0.3",
|
|
47
|
-
"ora": "^9.
|
|
47
|
+
"ora": "^9.3.0",
|
|
48
48
|
"picocolors": "^1.1.1",
|
|
49
49
|
"solid-js": "1.9.9",
|
|
50
50
|
"zod": "^3.25.76"
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"@biomejs/biome": "^1.9.4",
|
|
54
54
|
"@types/bun": "latest",
|
|
55
55
|
"@types/diff": "^8.0.0",
|
|
56
|
-
"@types/node": "^22.19.
|
|
56
|
+
"@types/node": "^22.19.11",
|
|
57
57
|
"oxfmt": "^0.23.0",
|
|
58
|
-
"oxlint": "^1.
|
|
58
|
+
"oxlint": "^1.48.0",
|
|
59
59
|
"typescript": "^5.9.3"
|
|
60
60
|
},
|
|
61
61
|
"engines": {
|