opencodekit 0.18.1 → 0.18.3
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 +161 -38
- package/dist/template/.opencode/.version +1 -1
- package/dist/template/.opencode/AGENTS.md +39 -9
- package/dist/template/.opencode/AGENT_ALIGNMENT.md +6 -6
- package/dist/template/.opencode/agent/build.md +7 -103
- package/dist/template/.opencode/agent/general.md +0 -52
- package/dist/template/.opencode/agent/plan.md +10 -0
- package/dist/template/.opencode/agent/runner.md +79 -0
- package/dist/template/.opencode/command/create.md +13 -1
- package/dist/template/.opencode/command/init-context.md +20 -6
- package/dist/template/.opencode/command/init-user.md +18 -16
- package/dist/template/.opencode/command/lfg.md +3 -4
- package/dist/template/.opencode/command/ship.md +6 -48
- package/dist/template/.opencode/command/start.md +20 -3
- package/dist/template/.opencode/command/verify.md +12 -17
- package/dist/template/.opencode/context/README.md +29 -0
- package/dist/template/.opencode/memory/_templates/{STATE.md → state.md} +1 -1
- package/dist/template/.opencode/memory.db +0 -0
- package/dist/template/.opencode/memory.db-shm +0 -0
- package/dist/template/.opencode/memory.db-wal +0 -0
- package/dist/template/.opencode/opencode.json +131 -7
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/plugin/lib/memory-helpers.ts +51 -16
- package/dist/template/.opencode/plugin/lib/memory-hooks.ts +1 -1
- package/dist/template/.opencode/skill/accessibility-audit/SKILL.md +11 -5
- package/dist/template/.opencode/skill/agent-browser/SKILL.md +55 -18
- package/dist/template/.opencode/skill/agent-teams/SKILL.md +12 -1
- package/dist/template/.opencode/skill/augment-context-engine/SKILL.md +11 -1
- package/dist/template/.opencode/skill/beads/SKILL.md +57 -390
- package/dist/template/.opencode/skill/beads/references/BEST_PRACTICES.md +27 -0
- package/dist/template/.opencode/skill/beads/references/EXAMPLES.md +45 -0
- package/dist/template/.opencode/skill/beads/references/FILE_CLAIMING.md +101 -0
- package/dist/template/.opencode/skill/beads/references/GIT_SYNC.md +25 -0
- package/dist/template/.opencode/skill/beads/references/HIERARCHY.md +71 -0
- package/dist/template/.opencode/skill/beads/references/MULTI_AGENT.md +40 -0
- package/dist/template/.opencode/skill/beads/references/SESSION_PROTOCOL.md +61 -0
- package/dist/template/.opencode/skill/beads/references/TASK_CREATION.md +38 -0
- package/dist/template/.opencode/skill/beads/references/TROUBLESHOOTING.md +38 -0
- package/dist/template/.opencode/skill/beads-bridge/SKILL.md +10 -10
- package/dist/template/.opencode/skill/brainstorming/SKILL.md +13 -0
- package/dist/template/.opencode/skill/chrome-devtools/SKILL.md +11 -1
- package/dist/template/.opencode/skill/cloudflare/SKILL.md +87 -67
- package/dist/template/.opencode/skill/compaction/SKILL.md +11 -3
- package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +11 -25
- package/dist/template/.opencode/skill/context-engineering/SKILL.md +13 -2
- package/dist/template/.opencode/skill/context-initialization/SKILL.md +11 -1
- package/dist/template/.opencode/skill/context-management/SKILL.md +13 -1
- package/dist/template/.opencode/skill/core-data-expert/SKILL.md +13 -2
- package/dist/template/.opencode/skill/deep-research/SKILL.md +5 -8
- package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +13 -0
- package/dist/template/.opencode/skill/design-system-audit/SKILL.md +9 -3
- package/dist/template/.opencode/skill/development-lifecycle/SKILL.md +51 -0
- package/dist/template/.opencode/skill/dispatching-parallel-agents/SKILL.md +19 -30
- package/dist/template/.opencode/skill/executing-plans/SKILL.md +36 -0
- package/dist/template/.opencode/skill/figma/SKILL.md +11 -1
- package/dist/template/.opencode/skill/finishing-a-development-branch/SKILL.md +31 -0
- package/dist/template/.opencode/skill/frontend-design/SKILL.md +13 -3
- package/dist/template/.opencode/skill/gemini-large-context/SKILL.md +11 -0
- package/dist/template/.opencode/skill/index-knowledge/SKILL.md +11 -1
- package/dist/template/.opencode/skill/jira/SKILL.md +11 -1
- package/dist/template/.opencode/skill/memory-system/SKILL.md +13 -1
- package/dist/template/.opencode/skill/mockup-to-code/SKILL.md +9 -3
- package/dist/template/.opencode/skill/mqdh/SKILL.md +11 -1
- package/dist/template/.opencode/skill/obsidian/SKILL.md +11 -1
- package/dist/template/.opencode/skill/opensrc/SKILL.md +18 -6
- package/dist/template/.opencode/skill/pdf-extract/SKILL.md +11 -1
- package/dist/template/.opencode/skill/playwright/SKILL.md +11 -1
- package/dist/template/.opencode/skill/playwriter/SKILL.md +11 -1
- package/dist/template/.opencode/skill/polar/SKILL.md +11 -1
- package/dist/template/.opencode/skill/prd/SKILL.md +13 -4
- package/dist/template/.opencode/skill/prd-task/SKILL.md +13 -3
- package/dist/template/.opencode/skill/ralph/SKILL.md +4 -8
- package/dist/template/.opencode/skill/react-best-practices/SKILL.md +24 -16
- package/dist/template/.opencode/skill/receiving-code-review/SKILL.md +22 -0
- package/dist/template/.opencode/skill/requesting-code-review/SKILL.md +30 -2
- package/dist/template/.opencode/skill/resend/SKILL.md +11 -1
- package/dist/template/.opencode/skill/root-cause-tracing/SKILL.md +12 -23
- package/dist/template/.opencode/skill/session-management/SKILL.md +11 -1
- package/dist/template/.opencode/skill/sharing-skills/SKILL.md +11 -0
- package/dist/template/.opencode/skill/skill-creator/SKILL.md +12 -11
- package/dist/template/.opencode/skill/source-code-research/SKILL.md +20 -266
- package/dist/template/.opencode/skill/source-code-research/references/analysis-tips.md +43 -0
- package/dist/template/.opencode/skill/source-code-research/references/anti-patterns.md +36 -0
- package/dist/template/.opencode/skill/source-code-research/references/common-patterns.md +57 -0
- package/dist/template/.opencode/skill/source-code-research/references/example-workflow.md +60 -0
- package/dist/template/.opencode/skill/source-code-research/references/further-reading.md +5 -0
- package/dist/template/.opencode/skill/source-code-research/references/source-structure.md +45 -0
- package/dist/template/.opencode/skill/stitch/SKILL.md +11 -1
- package/dist/template/.opencode/skill/structured-edit/SKILL.md +13 -0
- package/dist/template/.opencode/skill/subagent-driven-development/SKILL.md +13 -14
- package/dist/template/.opencode/skill/supabase/SKILL.md +11 -1
- package/dist/template/.opencode/skill/supabase-postgres-best-practices/SKILL.md +23 -15
- package/dist/template/.opencode/skill/swarm-coordination/SKILL.md +23 -923
- package/dist/template/.opencode/skill/swarm-coordination/references/architecture.md +39 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/delegation-worker-protocol.md +145 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/dependency-graph.md +50 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/drift-check.md +90 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/integration-beads.md +20 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/launch-flow.md +186 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/reconciler.md +172 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/tier-enforcement.md +78 -0
- package/dist/template/.opencode/skill/swarm-coordination/references/tmux-integration.md +134 -0
- package/dist/template/.opencode/skill/swift-concurrency/SKILL.md +22 -2
- package/dist/template/.opencode/skill/swiftui-expert-skill/SKILL.md +58 -19
- package/dist/template/.opencode/skill/systematic-debugging/SKILL.md +25 -25
- package/dist/template/.opencode/skill/test-driven-development/SKILL.md +19 -15
- package/dist/template/.opencode/skill/testing-anti-patterns/SKILL.md +13 -0
- package/dist/template/.opencode/skill/testing-skills-with-subagents/SKILL.md +13 -15
- package/dist/template/.opencode/skill/tool-priority/SKILL.md +13 -0
- package/dist/template/.opencode/skill/ui-ux-research/SKILL.md +9 -3
- package/dist/template/.opencode/skill/using-git-worktrees/SKILL.md +37 -0
- package/dist/template/.opencode/skill/using-skills/SKILL.md +13 -0
- package/dist/template/.opencode/skill/v0/SKILL.md +11 -1
- package/dist/template/.opencode/skill/v1-run/SKILL.md +11 -1
- package/dist/template/.opencode/skill/vercel-deploy-claimable/SKILL.md +14 -2
- package/dist/template/.opencode/skill/verification-before-completion/SKILL.md +22 -0
- package/dist/template/.opencode/skill/verification-before-completion/references/VERIFICATION_PROTOCOL.md +67 -0
- package/dist/template/.opencode/skill/visual-analysis/SKILL.md +9 -3
- package/dist/template/.opencode/skill/web-design-guidelines/SKILL.md +12 -5
- package/dist/template/.opencode/skill/writing-plans/SKILL.md +13 -0
- package/dist/template/.opencode/skill/writing-skills/SKILL.md +26 -421
- package/dist/template/.opencode/skill/writing-skills/references/anti-patterns.md +25 -0
- package/dist/template/.opencode/skill/writing-skills/references/claude-search-optimization.md +140 -0
- package/dist/template/.opencode/skill/writing-skills/references/discovery-workflow.md +11 -0
- package/dist/template/.opencode/skill/writing-skills/references/file-organization.md +32 -0
- package/dist/template/.opencode/skill/writing-skills/references/flowcharts-and-examples.md +57 -0
- package/dist/template/.opencode/skill/writing-skills/references/rationalization-hardening.md +75 -0
- package/dist/template/.opencode/skill/writing-skills/references/testing-skill-types.md +52 -0
- package/package.json +15 -4
- /package/dist/template/.opencode/memory/_templates/{PROJECT.md → project.md} +0 -0
- /package/dist/template/.opencode/memory/_templates/{ROADMAP.md → roadmap.md} +0 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Reconciler Agent Pattern (Self-Healing)
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
## When to Use Reconciler
|
|
6
|
+
|
|
7
|
+
- **50+ agents** running in parallel → **REQUIRED**
|
|
8
|
+
- **10-50 agents** → Recommended
|
|
9
|
+
- **<10 agents** → Optional (leader can handle)
|
|
10
|
+
|
|
11
|
+
## Reconciler Responsibilities
|
|
12
|
+
|
|
13
|
+
1. **Watch CI/Build Status**: Monitor build gates continuously
|
|
14
|
+
2. **Detect Failures**: Identify which worker caused the failure
|
|
15
|
+
3. **Analyze Root Cause**: Determine if it's a merge conflict, test failure, or type error
|
|
16
|
+
4. **Spawn Fix Tasks**: Create targeted fix tasks with context about what failed
|
|
17
|
+
5. **Verify Fix**: Wait for fix to pass gates before continuing
|
|
18
|
+
|
|
19
|
+
## Reconciler vs Leader
|
|
20
|
+
|
|
21
|
+
| Aspect | Leader | Reconciler |
|
|
22
|
+
| -------------- | ----------------------------- | ----------------------------- |
|
|
23
|
+
| Focus | Orchestration, spawning | Recovery, fixing |
|
|
24
|
+
| Runs | At swarm start, between waves | Continuously during execution |
|
|
25
|
+
| On failure | Spawns workers | Spawns fix tasks |
|
|
26
|
+
| Failure impact | Can't start work | Wave can't complete |
|
|
27
|
+
|
|
28
|
+
## Implementing Reconciler
|
|
29
|
+
|
|
30
|
+
The reconciler runs in a loop during swarm execution:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
// Reconciler runs in background during swarm execution
|
|
34
|
+
async function runReconciler(teamName: string, buildCommand: string) {
|
|
35
|
+
while (swarmActive) {
|
|
36
|
+
// 1. Check build status
|
|
37
|
+
const status = await swarm({
|
|
38
|
+
operation: "monitor",
|
|
39
|
+
operation: "status",
|
|
40
|
+
team_name: teamName,
|
|
41
|
+
});
|
|
42
|
+
const stats = JSON.parse(status).summary;
|
|
43
|
+
|
|
44
|
+
// 2. If there are errors, investigate
|
|
45
|
+
if (stats.errors > 0) {
|
|
46
|
+
// 3. Get error details
|
|
47
|
+
const errors = await getWorkerErrors(teamName);
|
|
48
|
+
|
|
49
|
+
for (const error of errors) {
|
|
50
|
+
// 4. Analyze root cause
|
|
51
|
+
const cause = await analyzeError(error);
|
|
52
|
+
|
|
53
|
+
// 5. Spawn fix task
|
|
54
|
+
const fixBead = await br create({
|
|
55
|
+
title: `Fix: ${cause.summary}`,
|
|
56
|
+
type: "bug",
|
|
57
|
+
description: `Detected by reconciler: ${error.message}. Root cause: ${cause.rootCause}. Suggested fix: ${cause.suggestion}`,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// 6. Assign to targeted worker
|
|
61
|
+
await Task({
|
|
62
|
+
subagent_type: "general",
|
|
63
|
+
description: `Fix ${error.worker}`,
|
|
64
|
+
prompt: `Fix the error in ${error.file}.
|
|
65
|
+
|
|
66
|
+
Error: ${error.message}
|
|
67
|
+
Root cause: ${cause.rootCause}
|
|
68
|
+
Suggested fix: ${cause.suggestion}
|
|
69
|
+
|
|
70
|
+
Run: ${buildCommand}
|
|
71
|
+
Verify: npm run typecheck && npm run lint`,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Wait before next check
|
|
77
|
+
await sleep(30000); // Check every 30 seconds
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Error Analysis Patterns
|
|
83
|
+
|
|
84
|
+
The reconciler categorizes errors:
|
|
85
|
+
|
|
86
|
+
| Error Type | Detection | Fix Strategy |
|
|
87
|
+
| -------------- | -------------------------------- | ---------------------------- |
|
|
88
|
+
| Merge conflict | "CONFLICT" in output, git status | Re-base, resolve, force push |
|
|
89
|
+
| Type error | "typecheck failed" | Fix types, run typecheck |
|
|
90
|
+
| Test failure | "test failed", "expect" mismatch | Fix test or implementation |
|
|
91
|
+
| Lint error | "lint failed", formatting issues | Run lint:fix |
|
|
92
|
+
| Build error | "build failed", bundler errors | Fix imports, dependencies |
|
|
93
|
+
|
|
94
|
+
## Spawning Fix Tasks
|
|
95
|
+
|
|
96
|
+
When the reconciler spawns a fix task, it includes:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// Create fix task with full context
|
|
100
|
+
await br create({
|
|
101
|
+
title: `Fix: ${error.type} in ${error.file}`,
|
|
102
|
+
type: "bug",
|
|
103
|
+
description: `## Error Detected
|
|
104
|
+
- Worker: ${error.worker}
|
|
105
|
+
- File: ${error.file}
|
|
106
|
+
- Error: ${error.message}
|
|
107
|
+
- Timestamp: ${error.timestamp}
|
|
108
|
+
|
|
109
|
+
## Root Cause Analysis
|
|
110
|
+
${cause.explanation}
|
|
111
|
+
|
|
112
|
+
## Suggested Fix
|
|
113
|
+
${cause.suggestion}
|
|
114
|
+
|
|
115
|
+
## Verification
|
|
116
|
+
Run: ${buildCommand}
|
|
117
|
+
Must pass before wave can complete.`,
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Reconciler in Wave Execution
|
|
122
|
+
|
|
123
|
+
Add reconciler monitoring to each wave:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Execute wave with reconciler
|
|
127
|
+
async function executeWaveWithReconciler(wave, teamName) {
|
|
128
|
+
// Start reconciler in background
|
|
129
|
+
const reconciler = runReconciler(teamName, "npm run typecheck && npm run lint");
|
|
130
|
+
|
|
131
|
+
// Execute workers in this wave
|
|
132
|
+
await Promise.all(wave.tasks.map(spawnWorker));
|
|
133
|
+
|
|
134
|
+
// Wait for all workers + reconciler to complete
|
|
135
|
+
await reconciler;
|
|
136
|
+
|
|
137
|
+
// Verify wave output before proceeding
|
|
138
|
+
await bash("npm run typecheck && npm run lint");
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Example: Full Swarm with Reconciler
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Full swarm execution with reconciler
|
|
146
|
+
async function runSwarmWithReconciler(tasks, teamName) {
|
|
147
|
+
// 1. Analyze and create waves
|
|
148
|
+
const waves = createWaves(tasks);
|
|
149
|
+
|
|
150
|
+
// 2. Execute each wave with reconciler
|
|
151
|
+
for (const wave of waves) {
|
|
152
|
+
console.log(`Executing wave ${wave.number} with ${wave.tasks.length} tasks`);
|
|
153
|
+
|
|
154
|
+
// Start reconciler for this wave
|
|
155
|
+
const reconcilerPromise = runReconciler(teamName, "npm run typecheck && npm run lint");
|
|
156
|
+
|
|
157
|
+
// Spawn workers
|
|
158
|
+
await Promise.all(wave.tasks.map((task) => spawnWorker(task, teamName)));
|
|
159
|
+
|
|
160
|
+
// Wait for reconciler to finish fixing any errors
|
|
161
|
+
await reconcilerPromise;
|
|
162
|
+
|
|
163
|
+
// Verify wave output
|
|
164
|
+
const result = await bash("npm run typecheck && npm run lint");
|
|
165
|
+
if (!result.success) {
|
|
166
|
+
throw new Error(`Wave ${wave.number} failed gates`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.log(`Wave ${wave.number} complete`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Tier Enforcement (Longshot Pattern)
|
|
2
|
+
|
|
3
|
+
For multi-agent execution at scale (10+ agents), enforce explicit tier hierarchy. This is the Longshot pattern that enabled 200 agents to build Minecraft.
|
|
4
|
+
|
|
5
|
+
## Tier System
|
|
6
|
+
|
|
7
|
+
| Tier | Role | Swarm Equivalent | Responsibility |
|
|
8
|
+
| --------------- | --------------------- | ---------------- | -------------------------------------------------------------- |
|
|
9
|
+
| **planner** | Lead orchestrator | Build agent | Analyzes scope, decomposes into sub-tasks, coordinates workers |
|
|
10
|
+
| **sub-planner** | Mid-level coordinator | N/A | Takes planner output, further decomposes, assigns to workers |
|
|
11
|
+
| **worker** | Execution agent | Worker agents | Executes assigned work, reports progress |
|
|
12
|
+
|
|
13
|
+
## When Tiers Are Required
|
|
14
|
+
|
|
15
|
+
- **<10 agents**: Optional - flat decomposition works
|
|
16
|
+
- **10-50 agents**: Recommended - planner + workers
|
|
17
|
+
- **50+ agents**: Required - planner + sub-planners + workers
|
|
18
|
+
|
|
19
|
+
## Enforcing Tier Boundaries
|
|
20
|
+
|
|
21
|
+
The swarm leader enforces tier boundaries:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// Tier enforcement in swarm execution
|
|
25
|
+
async function enforceTiers(waves, tierConfig) {
|
|
26
|
+
// Wave 1: Planner tasks only
|
|
27
|
+
const planners = waves.filter((w) => w.tier === "planner");
|
|
28
|
+
await executeWave(planners);
|
|
29
|
+
|
|
30
|
+
// Wave 2: Sub-planner tasks (if any)
|
|
31
|
+
const subPlanners = waves.filter((w) => w.tier === "sub-planner");
|
|
32
|
+
await executeWave(subPlanners);
|
|
33
|
+
|
|
34
|
+
// Wave 3+: Worker tasks
|
|
35
|
+
const workers = waves.filter((w) => w.tier === "worker");
|
|
36
|
+
await executeWave(workers);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Handoff Contracts Between Tiers
|
|
41
|
+
|
|
42
|
+
Each tier must declare handoff contracts:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// Planner declares what it produces for sub-planners
|
|
46
|
+
const plannerHandoff = {
|
|
47
|
+
produces: [
|
|
48
|
+
{ artifact: "docs/auth-design.md", format: "markdown" },
|
|
49
|
+
{ artifact: "tasks/auth-tasks.json", format: "json" },
|
|
50
|
+
],
|
|
51
|
+
consumedBy: ["sub-planner-auth"],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Worker declares what it consumes from sub-planners
|
|
55
|
+
const workerHandoff = {
|
|
56
|
+
consumes: [{ artifact: "tasks/auth-tasks.json", format: "json" }],
|
|
57
|
+
produces: [{ artifact: "src/auth/service.ts", format: "typescript" }],
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Anti-Pattern: Flat Decomposition at Scale
|
|
62
|
+
|
|
63
|
+
Without tiers, 20 agents get 20 flat tasks → chaos:
|
|
64
|
+
|
|
65
|
+
- Workers step on each other
|
|
66
|
+
- No coordination between related work
|
|
67
|
+
- Merge conflicts everywhere
|
|
68
|
+
- No clear ownership
|
|
69
|
+
|
|
70
|
+
With tiers (Longshot pattern):
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Lead Planner → Sub-planner A → Worker 1, 2, 3
|
|
74
|
+
→ Sub-planner B → Worker 4, 5, 6
|
|
75
|
+
Sub-planner C → Worker 7, 8, 9
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
This mirrors real engineering orgs: lead → tech lead → IC. The architecture is the differentiator.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Tmux Integration (Visual Swarm Monitoring)
|
|
2
|
+
|
|
3
|
+
Enable real-time visualization of swarm workers in separate tmux panes.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. Start OpenCode inside tmux:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
tmux new -s opencode
|
|
11
|
+
opencode
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. The tmux tool auto-detects when running inside tmux and uses these defaults:
|
|
15
|
+
- Layout: `main-vertical` (leader left, workers right)
|
|
16
|
+
- Main pane size: 60%
|
|
17
|
+
- Auto-cleanup: enabled
|
|
18
|
+
|
|
19
|
+
## Detecting Tmux
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// Check if running inside tmux
|
|
23
|
+
const status = await tmux({ operation: "detect" });
|
|
24
|
+
const { available, inside_session } = JSON.parse(status);
|
|
25
|
+
|
|
26
|
+
if (!inside_session) {
|
|
27
|
+
console.log("Tip: Run inside tmux for visual swarm monitoring");
|
|
28
|
+
console.log("Start with: tmux new -s opencode");
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Spawning Worker Panes
|
|
33
|
+
|
|
34
|
+
When spawning workers, create visual panes:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// Before spawning worker via Task tool
|
|
38
|
+
if (inside_session) {
|
|
39
|
+
// Create pane for this worker
|
|
40
|
+
const pane = await tmux({
|
|
41
|
+
operation: "spawn",
|
|
42
|
+
worker_id: "worker-1",
|
|
43
|
+
title: "Explorer: auth.ts",
|
|
44
|
+
size: 40, // 40% width
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const { pane_id } = JSON.parse(pane);
|
|
48
|
+
|
|
49
|
+
// Send command to pane (optional - for visual feedback)
|
|
50
|
+
await tmux({
|
|
51
|
+
operation: "send",
|
|
52
|
+
pane_id,
|
|
53
|
+
command: `echo "🔍 Worker-1: Exploring auth.ts..."`,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Spawn the actual worker
|
|
58
|
+
await Task({
|
|
59
|
+
subagent_type: "general",
|
|
60
|
+
description: "Execute worker-1",
|
|
61
|
+
prompt: `...`,
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Layout Options
|
|
66
|
+
|
|
67
|
+
| Layout | Description | Best For |
|
|
68
|
+
| ----------------- | ------------------------------------- | ----------------------------- |
|
|
69
|
+
| `main-vertical` | Main pane left, workers stacked right | Default, good for 2-4 workers |
|
|
70
|
+
| `main-horizontal` | Main pane top, workers below | Wide monitors |
|
|
71
|
+
| `tiled` | Equal grid for all panes | Many workers (5+) |
|
|
72
|
+
| `even-horizontal` | Equal width columns | 2-3 workers |
|
|
73
|
+
| `even-vertical` | Equal height rows | 2-3 workers |
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// Change layout dynamically
|
|
77
|
+
await tmux({
|
|
78
|
+
operation: "layout",
|
|
79
|
+
layout: "tiled", // When many workers spawn
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Monitoring Worker Output
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// Capture output from a worker's pane
|
|
87
|
+
const output = await tmux({
|
|
88
|
+
operation: "capture",
|
|
89
|
+
pane_id: "%5",
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Check what the worker is doing
|
|
93
|
+
console.log(JSON.parse(output).output);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Cleanup
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// Kill specific pane when worker completes
|
|
100
|
+
await tmux({
|
|
101
|
+
operation: "kill",
|
|
102
|
+
pane_id: "%5",
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Or cleanup all spawned panes at end of swarm
|
|
106
|
+
await tmux({
|
|
107
|
+
operation: "cleanup",
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## User Commands
|
|
112
|
+
|
|
113
|
+
| Action | Keys |
|
|
114
|
+
| ----------------------- | ------------- |
|
|
115
|
+
| Switch to next pane | `Ctrl+B →` |
|
|
116
|
+
| Switch to previous pane | `Ctrl+B ←` |
|
|
117
|
+
| Zoom current pane | `Ctrl+B z` |
|
|
118
|
+
| Detach (keep running) | `Ctrl+B d` |
|
|
119
|
+
| Reattach | `tmux attach` |
|
|
120
|
+
| List all panes | `Ctrl+B w` |
|
|
121
|
+
|
|
122
|
+
## Watch Command
|
|
123
|
+
|
|
124
|
+
Use `/swarm-watch` for real-time progress monitoring:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
/swarm-watch my-swarm-team
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This renders the beautiful TUI block and shows:
|
|
131
|
+
|
|
132
|
+
- Worker progress percentages
|
|
133
|
+
- Current files being worked on
|
|
134
|
+
- Completion status
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: swift-concurrency
|
|
3
3
|
description: 'Expert guidance on Swift Concurrency best practices, patterns, and implementation. Use when developers mention: (1) Swift Concurrency, async/await, actors, or tasks, (2) "use Swift Concurrency" or "modern concurrency patterns", (3) migrating to Swift 6, (4) data races or thread safety issues, (5) refactoring closures to async/await, (6) @MainActor, Sendable, or actor isolation, (7) concurrent code architecture or performance optimization, (8) concurrency-related linter warnings (SwiftLint or similar; e.g. async_without_await, Sendable/actor isolation/MainActor lint).'
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [apple, code-quality]
|
|
6
|
+
dependencies: []
|
|
4
7
|
---
|
|
8
|
+
|
|
5
9
|
# Swift Concurrency
|
|
6
10
|
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- When working on Swift concurrency features, async/await, actors, or Swift 6 migration issues.
|
|
14
|
+
|
|
15
|
+
## When NOT to Use
|
|
16
|
+
|
|
17
|
+
- When concurrency is not involved or the codebase is not Swift.
|
|
18
|
+
|
|
7
19
|
## Overview
|
|
8
20
|
|
|
9
21
|
This skill provides expert guidance on Swift Concurrency, covering modern async/await patterns, actors, tasks, Sendable conformance, and migration to Swift 6. Use this skill to help developers write safe, performant concurrent code and navigate the complexities of Swift's structured concurrency model.
|
|
@@ -29,8 +41,6 @@ When analyzing Swift projects for concurrency issues:
|
|
|
29
41
|
- Use `Grep` for `SWIFT_STRICT_CONCURRENCY` or `SWIFT_DEFAULT_ACTOR_ISOLATION` in `.pbxproj` files
|
|
30
42
|
- Use `Grep` for `SWIFT_UPCOMING_FEATURE_` to find enabled upcoming features
|
|
31
43
|
|
|
32
|
-
|
|
33
|
-
|
|
34
44
|
## Project Settings Intake (Evaluate Before Advising)
|
|
35
45
|
|
|
36
46
|
Concurrency behavior depends on build settings. Always try to determine:
|
|
@@ -109,6 +119,7 @@ When a developer needs concurrency guidance, follow this decision tree:
|
|
|
109
119
|
### When to Use Each Concurrency Tool
|
|
110
120
|
|
|
111
121
|
**async/await** - Making existing synchronous code asynchronous
|
|
122
|
+
|
|
112
123
|
```swift
|
|
113
124
|
// Use for: Single asynchronous operations
|
|
114
125
|
func fetchUser() async throws -> User {
|
|
@@ -117,6 +128,7 @@ func fetchUser() async throws -> User {
|
|
|
117
128
|
```
|
|
118
129
|
|
|
119
130
|
**async let** - Running multiple independent async operations in parallel
|
|
131
|
+
|
|
120
132
|
```swift
|
|
121
133
|
// Use for: Fixed number of parallel operations known at compile time
|
|
122
134
|
async let user = fetchUser()
|
|
@@ -125,6 +137,7 @@ let profile = try await (user, posts)
|
|
|
125
137
|
```
|
|
126
138
|
|
|
127
139
|
**Task** - Starting unstructured asynchronous work
|
|
140
|
+
|
|
128
141
|
```swift
|
|
129
142
|
// Use for: Fire-and-forget operations, bridging sync to async contexts
|
|
130
143
|
Task {
|
|
@@ -133,6 +146,7 @@ Task {
|
|
|
133
146
|
```
|
|
134
147
|
|
|
135
148
|
**Task Group** - Dynamic parallel operations with structured concurrency
|
|
149
|
+
|
|
136
150
|
```swift
|
|
137
151
|
// Use for: Unknown number of parallel operations at compile time
|
|
138
152
|
await withTaskGroup(of: Result.self) { group in
|
|
@@ -143,6 +157,7 @@ await withTaskGroup(of: Result.self) { group in
|
|
|
143
157
|
```
|
|
144
158
|
|
|
145
159
|
**Actor** - Protecting mutable state from data races
|
|
160
|
+
|
|
146
161
|
```swift
|
|
147
162
|
// Use for: Shared mutable state accessed from multiple contexts
|
|
148
163
|
actor DataCache {
|
|
@@ -152,6 +167,7 @@ actor DataCache {
|
|
|
152
167
|
```
|
|
153
168
|
|
|
154
169
|
**@MainActor** - Ensuring UI updates on main thread
|
|
170
|
+
|
|
155
171
|
```swift
|
|
156
172
|
// Use for: View models, UI-related classes
|
|
157
173
|
@MainActor
|
|
@@ -163,6 +179,7 @@ class ViewModel: ObservableObject {
|
|
|
163
179
|
### Common Scenarios
|
|
164
180
|
|
|
165
181
|
**Scenario: Network request with UI update**
|
|
182
|
+
|
|
166
183
|
```swift
|
|
167
184
|
Task { @concurrent in
|
|
168
185
|
let data = try await fetchData() // Background
|
|
@@ -173,6 +190,7 @@ Task { @concurrent in
|
|
|
173
190
|
```
|
|
174
191
|
|
|
175
192
|
**Scenario: Multiple parallel network requests**
|
|
193
|
+
|
|
176
194
|
```swift
|
|
177
195
|
async let users = fetchUsers()
|
|
178
196
|
async let posts = fetchPosts()
|
|
@@ -181,6 +199,7 @@ let (u, p, c) = try await (users, posts, comments)
|
|
|
181
199
|
```
|
|
182
200
|
|
|
183
201
|
**Scenario: Processing array items in parallel**
|
|
202
|
+
|
|
184
203
|
```swift
|
|
185
204
|
await withTaskGroup(of: ProcessedItem.self) { group in
|
|
186
205
|
for item in items {
|
|
@@ -195,6 +214,7 @@ await withTaskGroup(of: ProcessedItem.self) { group in
|
|
|
195
214
|
## Swift 6 Migration Quick Guide
|
|
196
215
|
|
|
197
216
|
Key changes in Swift 6:
|
|
217
|
+
|
|
198
218
|
- **Strict concurrency checking** enabled by default
|
|
199
219
|
- **Complete data-race safety** at compile time
|
|
200
220
|
- **Sendable requirements** enforced on boundaries
|