oh-my-codex-cli 0.1.0
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/.agent/skills/agent-kb/HOW_TO_USE.md +428 -0
- package/.agent/skills/agent-kb/README.md +46 -0
- package/.agent/skills/agent-kb/SKILL.md +128 -0
- package/.agent/skills/agent-kb/references/intelligent-analysis-explained.md +333 -0
- package/.agent/skills/agent-kb/references/query-optimization.md +225 -0
- package/.agent/skills/aireview/SKILL.md +704 -0
- package/.agent/skills/analyze/SKILL.md +81 -0
- package/.agent/skills/architect-planner/HOW_TO_USE.md +238 -0
- package/.agent/skills/architect-planner/README.md +41 -0
- package/.agent/skills/architect-planner/SKILL.md +539 -0
- package/.agent/skills/auto-mbti/SKILL.md +291 -0
- package/.agent/skills/autopilot/SKILL.md +222 -0
- package/.agent/skills/backend-patterns/SKILL.md +602 -0
- package/.agent/skills/bdd-generator/README.md +78 -0
- package/.agent/skills/bdd-generator/SKILL.md +436 -0
- package/.agent/skills/brainstorming/HOW_TO_USE.md +289 -0
- package/.agent/skills/brainstorming/README.md +41 -0
- package/.agent/skills/brainstorming/SKILL.md +165 -0
- package/.agent/skills/build-fix/SKILL.md +190 -0
- package/.agent/skills/cancel/SKILL.md +658 -0
- package/.agent/skills/checkpoint/SKILL.md +94 -0
- package/.agent/skills/code-review/SKILL.md +273 -0
- package/.agent/skills/coding-standards/SKILL.md +535 -0
- package/.agent/skills/conductor/SKILL.md +128 -0
- package/.agent/skills/conductor/commands/conductor/implement.toml +358 -0
- package/.agent/skills/conductor/commands/conductor/newTrack.toml +142 -0
- package/.agent/skills/conductor/commands/conductor/revert.toml +123 -0
- package/.agent/skills/conductor/commands/conductor/setup.toml +429 -0
- package/.agent/skills/conductor/commands/conductor/status.toml +57 -0
- package/.agent/skills/conductor/scripts/install.sh +89 -0
- package/.agent/skills/conductor/templates/code_styleguides/csharp.md +115 -0
- package/.agent/skills/conductor/templates/code_styleguides/dart.md +238 -0
- package/.agent/skills/conductor/templates/code_styleguides/general.md +23 -0
- package/.agent/skills/conductor/templates/code_styleguides/go.md +48 -0
- package/.agent/skills/conductor/templates/code_styleguides/html-css.md +49 -0
- package/.agent/skills/conductor/templates/code_styleguides/javascript.md +51 -0
- package/.agent/skills/conductor/templates/code_styleguides/python.md +37 -0
- package/.agent/skills/conductor/templates/code_styleguides/typescript.md +43 -0
- package/.agent/skills/conductor/templates/rules/README.md +23 -0
- package/.agent/skills/conductor/templates/rules/agents.md +49 -0
- package/.agent/skills/conductor/templates/rules/coding-style.md +70 -0
- package/.agent/skills/conductor/templates/rules/dev.md +20 -0
- package/.agent/skills/conductor/templates/rules/git-workflow.md +45 -0
- package/.agent/skills/conductor/templates/rules/hooks.md +6 -0
- package/.agent/skills/conductor/templates/rules/patterns.md +55 -0
- package/.agent/skills/conductor/templates/rules/performance.md +47 -0
- package/.agent/skills/conductor/templates/rules/research.md +26 -0
- package/.agent/skills/conductor/templates/rules/review.md +22 -0
- package/.agent/skills/conductor/templates/rules/security.md +36 -0
- package/.agent/skills/conductor/templates/rules/testing.md +30 -0
- package/.agent/skills/conductor/templates/workflow.md +333 -0
- package/.agent/skills/consensus/HOW_TO_USE.md +191 -0
- package/.agent/skills/consensus/README.md +41 -0
- package/.agent/skills/consensus/SKILL.md +317 -0
- package/.agent/skills/content-research-writer/SKILL.md +537 -0
- package/.agent/skills/debug-analysis/SKILL.md +331 -0
- package/.agent/skills/deepinit/SKILL.md +347 -0
- package/.agent/skills/deepsearch/SKILL.md +56 -0
- package/.agent/skills/doctor/SKILL.md +158 -0
- package/.agent/skills/drawio/EXAMPLES.md +382 -0
- package/.agent/skills/drawio/QUICK_START.md +237 -0
- package/.agent/skills/drawio/README.md +315 -0
- package/.agent/skills/drawio/SETUP_GUIDE.md +254 -0
- package/.agent/skills/drawio/SKILL.md +1176 -0
- package/.agent/skills/e2e/SKILL.md +396 -0
- package/.agent/skills/ecomode/SKILL.md +160 -0
- package/.agent/skills/electron-driver/SKILL.md +144 -0
- package/.agent/skills/electron-driver/scripts/driver-template.js +71 -0
- package/.agent/skills/eval/SKILL.md +140 -0
- package/.agent/skills/eval-harness/SKILL.md +242 -0
- package/.agent/skills/evolve/SKILL.md +213 -0
- package/.agent/skills/frontend-design/SKILL.md +42 -0
- package/.agent/skills/frontend-patterns/SKILL.md +646 -0
- package/.agent/skills/frontend-ui-ux/SKILL.md +70 -0
- package/.agent/skills/git-master/SKILL.md +75 -0
- package/.agent/skills/help/SKILL.md +89 -0
- package/.agent/skills/iterative-retrieval/SKILL.md +217 -0
- package/.agent/skills/local-skills-setup/SKILL.md +483 -0
- package/.agent/skills/log-analyzer/SKILL.md +187 -0
- package/.agent/skills/mcp-setup/SKILL.md +226 -0
- package/.agent/skills/multi-model-research/HOW_TO_USE.md +614 -0
- package/.agent/skills/multi-model-research/README.md +233 -0
- package/.agent/skills/multi-model-research/SKILL.md +541 -0
- package/.agent/skills/multi-model-research/references/troubleshooting.md +415 -0
- package/.agent/skills/note/SKILL.md +80 -0
- package/.agent/skills/omc-setup/SKILL.md +219 -0
- package/.agent/skills/orchestrate/SKILL.md +620 -0
- package/.agent/skills/patent-workflow/IMPLEMENTATION_SUMMARY.md +500 -0
- package/.agent/skills/patent-workflow/README.md +455 -0
- package/.agent/skills/patent-workflow/SKILL.md +1036 -0
- package/.agent/skills/patent-workflow/tools/irr_checker.py +260 -0
- package/.agent/skills/patent-workflow/tools/sample_terminology.json +49 -0
- package/.agent/skills/patent-workflow/tools/term_checker.py +355 -0
- package/.agent/skills/pattern-recognition/SKILL.md +792 -0
- package/.agent/skills/pipeline/SKILL.md +448 -0
- package/.agent/skills/plan/SKILL.md +309 -0
- package/.agent/skills/planning-methodology/SKILL.md +370 -0
- package/.agent/skills/planning-with-files/SKILL.md +210 -0
- package/.agent/skills/planning-with-files/examples.md +202 -0
- package/.agent/skills/planning-with-files/reference.md +218 -0
- package/.agent/skills/planning-with-files/scripts/check-complete.ps1 +42 -0
- package/.agent/skills/planning-with-files/scripts/check-complete.sh +44 -0
- package/.agent/skills/planning-with-files/scripts/init-session.ps1 +120 -0
- package/.agent/skills/planning-with-files/scripts/init-session.sh +120 -0
- package/.agent/skills/planning-with-files/scripts/session-catchup.py +208 -0
- package/.agent/skills/planning-with-files/templates/findings.md +95 -0
- package/.agent/skills/planning-with-files/templates/progress.md +114 -0
- package/.agent/skills/planning-with-files/templates/task_plan.md +132 -0
- package/.agent/skills/project-analyze/CLAUDE.md +18 -0
- package/.agent/skills/project-analyze/HOW_TO_USE.md +145 -0
- package/.agent/skills/project-analyze/README.md +42 -0
- package/.agent/skills/project-analyze/SKILL.md +289 -0
- package/.agent/skills/project-analyze/SKILL.md.backup +287 -0
- package/.agent/skills/project-analyze/SKILL.md.backup_20260105_093646 +287 -0
- package/.agent/skills/project-analyze/assets/analysis-report-template.md +433 -0
- package/.agent/skills/project-analyze/references/analysis-patterns.md +422 -0
- package/.agent/skills/project-analyze/references/projectmind-explained.md +535 -0
- package/.agent/skills/project-session-manager/SKILL.md +428 -0
- package/.agent/skills/project-session-manager/lib/config.sh +86 -0
- package/.agent/skills/project-session-manager/lib/parse.sh +121 -0
- package/.agent/skills/project-session-manager/lib/session.sh +132 -0
- package/.agent/skills/project-session-manager/lib/tmux.sh +103 -0
- package/.agent/skills/project-session-manager/lib/worktree.sh +171 -0
- package/.agent/skills/project-session-manager/psm.sh +629 -0
- package/.agent/skills/project-session-manager/templates/feature.md +56 -0
- package/.agent/skills/project-session-manager/templates/issue-fix.md +57 -0
- package/.agent/skills/project-session-manager/templates/pr-review.md +65 -0
- package/.agent/skills/project-session-manager/templates/projects.json +19 -0
- package/.agent/skills/quality-check/HOW_TO_USE.md +171 -0
- package/.agent/skills/quality-check/README.md +50 -0
- package/.agent/skills/quality-check/SKILL.md +240 -0
- package/.agent/skills/quality-check/SKILL.md.backup +238 -0
- package/.agent/skills/quality-check/SKILL.md.backup_20260105_093646 +238 -0
- package/.agent/skills/quality-check/assets/quality-report-template.md +437 -0
- package/.agent/skills/quality-check/references/refactoring-patterns.md +550 -0
- package/.agent/skills/quality-check/references/scoring-criteria.md +454 -0
- package/.agent/skills/quality-validation/SKILL.md +519 -0
- package/.agent/skills/quality-validation/SKILL.md.backup +573 -0
- package/.agent/skills/quality-validation/SKILL.md.backup_20260105_093646 +573 -0
- package/.agent/skills/ralph/SKILL.md +236 -0
- package/.agent/skills/ralph-init/SKILL.md +78 -0
- package/.agent/skills/ralplan/SKILL.md +58 -0
- package/.agent/skills/refactor-clean/SKILL.md +49 -0
- package/.agent/skills/release/SKILL.md +84 -0
- package/.agent/skills/research/SKILL.md +526 -0
- package/.agent/skills/research-methodology/SKILL.md +268 -0
- package/.agent/skills/review/SKILL.md +53 -0
- package/.agent/skills/security-review/SKILL.md +509 -0
- package/.agent/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/.agent/skills/setup-pm/SKILL.md +102 -0
- package/.agent/skills/skill/SKILL.md +424 -0
- package/.agent/skills/skill-create/SKILL.md +209 -0
- package/.agent/skills/skill-debugger/HOW_TO_USE.md +244 -0
- package/.agent/skills/skill-debugger/README.md +44 -0
- package/.agent/skills/skill-debugger/SKILL.md +326 -0
- package/.agent/skills/skill-debugger/diagnostic_checklist.md +115 -0
- package/.agent/skills/skill-development/SKILL.md +661 -0
- package/.agent/skills/skill-development/references/skill-creator-original.md +209 -0
- package/.agent/skills/skill-doc-generator/README.md +37 -0
- package/.agent/skills/skill-doc-generator/SKILL.md +331 -0
- package/.agent/skills/skill-quality-analyzer/HOW_TO_USE.md +243 -0
- package/.agent/skills/skill-quality-analyzer/README.md +61 -0
- package/.agent/skills/skill-quality-analyzer/SKILL.md +247 -0
- package/.agent/skills/skill-quality-analyzer/analyzer.py +209 -0
- package/.agent/skills/skill-quality-analyzer/expected_output.json +81 -0
- package/.agent/skills/skill-quality-analyzer/sample_input.json +9 -0
- package/.agent/skills/skill-tester/README.md +46 -0
- package/.agent/skills/skill-tester/SKILL.md +345 -0
- package/.agent/skills/start-dev/SKILL.md +701 -0
- package/.agent/skills/swarm/SKILL.md +691 -0
- package/.agent/skills/task-kb-lookup/SKILL.md +211 -0
- package/.agent/skills/task-kb-record/SKILL.md +417 -0
- package/.agent/skills/tdd/SKILL.md +446 -0
- package/.agent/skills/tdd-generator/DEMO.md +516 -0
- package/.agent/skills/tdd-generator/README.md +89 -0
- package/.agent/skills/tdd-generator/SKILL.md +278 -0
- package/.agent/skills/tdd-workflow/SKILL.md +424 -0
- package/.agent/skills/test-coverage/SKILL.md +48 -0
- package/.agent/skills/thinkdeep/HOW_TO_USE.md +183 -0
- package/.agent/skills/thinkdeep/README.md +41 -0
- package/.agent/skills/thinkdeep/SKILL.md +343 -0
- package/.agent/skills/ui-ux-pro-max/SKILL.md +228 -0
- package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/skills/ui-ux-pro-max/scripts/core.py +236 -0
- package/.agent/skills/ui-ux-pro-max/scripts/search.py +61 -0
- package/.agent/skills/ultrapilot/SKILL.md +647 -0
- package/.agent/skills/ultraqa/SKILL.md +152 -0
- package/.agent/skills/ultrawork/SKILL.md +123 -0
- package/.agent/skills/update-codemaps/SKILL.md +38 -0
- package/.agent/skills/update-docs/SKILL.md +52 -0
- package/.agent/skills/verification-loop/SKILL.md +140 -0
- package/.agent/skills/verify/SKILL.md +80 -0
- package/.agent/skills/writer-memory/SKILL.md +459 -0
- package/.agent/skills/writer-memory/lib/character-tracker.ts +338 -0
- package/.agent/skills/writer-memory/lib/memory-manager.ts +804 -0
- package/.agent/skills/writer-memory/lib/relationship-graph.ts +400 -0
- package/.agent/skills/writer-memory/lib/scene-organizer.ts +544 -0
- package/.agent/skills/writer-memory/lib/synopsis-builder.ts +339 -0
- package/.agent/skills/writer-memory/templates/synopsis-template.md +46 -0
- package/.governance/skill-lint.allowlist +4 -0
- package/.governance/skill-llm.allowlist +4 -0
- package/AGENTS.md +59 -0
- package/LICENSE +21 -0
- package/README.md +169 -0
- package/README.zh.md +145 -0
- package/bin/omcodex.js +8 -0
- package/commands/conductor/implement.toml +358 -0
- package/commands/conductor/newTrack.toml +142 -0
- package/commands/conductor/revert.toml +123 -0
- package/commands/conductor/setup.toml +429 -0
- package/commands/conductor/status.toml +57 -0
- package/docs/ALIGNMENT.md +40 -0
- package/docs/CODEX.md +133 -0
- package/docs/NOTIFY.md +81 -0
- package/docs/SKILL_GOVERNANCE.md +72 -0
- package/docs/SKILL_GOVERNANCE_FRAMEWORK.md +182 -0
- package/docs/SKILL_GOVERNANCE_FRAMEWORK.zh.md +170 -0
- package/package.json +50 -0
- package/prompts/architect.md +105 -0
- package/prompts/executor.md +134 -0
- package/prompts/planner.md +113 -0
- package/scripts/check-skill-governance.sh +84 -0
- package/scripts/check-skill-llm-governance.js +302 -0
- package/scripts/eval-skills.js +217 -0
- package/scripts/generate-catalog-docs.js +95 -0
- package/scripts/generate-codex-mcp-config.sh +22 -0
- package/scripts/install-codex-force.sh +5 -0
- package/scripts/install-codex-incremental.sh +5 -0
- package/scripts/install-codex.sh +79 -0
- package/scripts/notify-dispatch.js +15 -0
- package/scripts/setup-package-manager.js +137 -0
- package/src/catalog/generated/public-catalog.json +547 -0
- package/src/catalog/manifest.json +542 -0
- package/src/catalog/reader.js +43 -0
- package/src/catalog/schema.js +79 -0
- package/src/cli/doctor.js +62 -0
- package/src/cli/index.js +85 -0
- package/src/cli/notify.js +127 -0
- package/src/cli/route.js +43 -0
- package/src/cli/setup.js +155 -0
- package/src/cli/team.js +125 -0
- package/src/config/generator.js +119 -0
- package/src/mcp/memory-server.js +241 -0
- package/src/mcp/state-server.js +112 -0
- package/src/mcp/trace-server.js +168 -0
- package/src/notify/dispatch.js +74 -0
- package/src/notify/extensibility/dispatcher.js +113 -0
- package/src/notify/extensibility/events.js +15 -0
- package/src/notify/extensibility/loader.js +54 -0
- package/src/router/skill-router.js +90 -0
- package/src/team/auto-advance.js +72 -0
- package/src/team/orchestrator.js +82 -0
- package/src/team/state-store.js +33 -0
- package/src/utils/paths.js +33 -0
- package/templates/AGENTS.md +15 -0
- package/templates/catalog-manifest.json +542 -0
- package/templates/code_styleguides/csharp.md +115 -0
- package/templates/code_styleguides/dart.md +238 -0
- package/templates/code_styleguides/general.md +23 -0
- package/templates/code_styleguides/go.md +48 -0
- package/templates/code_styleguides/html-css.md +49 -0
- package/templates/code_styleguides/javascript.md +51 -0
- package/templates/code_styleguides/python.md +37 -0
- package/templates/code_styleguides/typescript.md +43 -0
- package/templates/rules/README.md +23 -0
- package/templates/rules/agents.md +49 -0
- package/templates/rules/coding-style.md +70 -0
- package/templates/rules/dev.md +20 -0
- package/templates/rules/git-workflow.md +45 -0
- package/templates/rules/notify.md +6 -0
- package/templates/rules/patterns.md +55 -0
- package/templates/rules/performance.md +47 -0
- package/templates/rules/research.md +26 -0
- package/templates/rules/review.md +22 -0
- package/templates/rules/security.md +36 -0
- package/templates/rules/testing.md +30 -0
- package/templates/workflow.md +333 -0
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: swarm
|
|
3
|
+
description: N coordinated agents on shared task list with SQLite-based atomic claiming
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Swarm Skill
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Native Subagent Protocol (Codex)
|
|
10
|
+
|
|
11
|
+
Codex supports native subagents. Delegate with `spawn_agent`, coordinate with `send_input`, collect via `wait`, and clean up with `close_agent`.
|
|
12
|
+
|
|
13
|
+
Execution preference:
|
|
14
|
+
1. Use native subagents first for independent workstreams (parallel when possible).
|
|
15
|
+
2. Merge results in main thread and run final verification.
|
|
16
|
+
3. Fallback only when delegation is blocked: use the `[ANALYST]`/`[ARCHITECT]`/`[EXECUTOR]`/`[REVIEWER]` structure in a single response.
|
|
17
|
+
|
|
18
|
+
Minimal orchestration pattern:
|
|
19
|
+
```text
|
|
20
|
+
spawn_agent -> send_input (optional) -> wait -> close_agent
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
> Codex invocation: use `$swarm ...` or `swarm: ...`
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Spawn N coordinated agents working on a shared task list with SQLite-based atomic claiming. Like a dev team tackling multiple files in parallel—fast, reliable, and with full fault tolerance.
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
$swarm N:agent-type "task description"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Parameters
|
|
35
|
+
|
|
36
|
+
- **N** - Number of agents (1-5, enforced by Codex limit)
|
|
37
|
+
- **agent-type** - Agent to spawn (e.g., executor, build-fixer, architect)
|
|
38
|
+
- **task** - High-level task to decompose and distribute
|
|
39
|
+
|
|
40
|
+
### Examples
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
$swarm 5:executor "fix all TypeScript errors"
|
|
44
|
+
$swarm 3:build-fixer "fix build errors in src/"
|
|
45
|
+
$swarm 4:designer "implement responsive layouts for all components"
|
|
46
|
+
$swarm 2:architect "analyze and document all API endpoints"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Architecture
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
User: "$swarm 5:executor fix all TypeScript errors"
|
|
53
|
+
|
|
|
54
|
+
v
|
|
55
|
+
[SWARM ORCHESTRATOR]
|
|
56
|
+
|
|
|
57
|
+
+--+--+--+--+--+
|
|
58
|
+
| | | | |
|
|
59
|
+
v v v v v
|
|
60
|
+
E1 E2 E3 E4 E5
|
|
61
|
+
| | | | |
|
|
62
|
+
+--+--+--+--+
|
|
63
|
+
|
|
|
64
|
+
v
|
|
65
|
+
[SQLITE DATABASE]
|
|
66
|
+
┌─────────────────────┐
|
|
67
|
+
│ tasks table │
|
|
68
|
+
├─────────────────────┤
|
|
69
|
+
│ id, description │
|
|
70
|
+
│ status (pending, │
|
|
71
|
+
│ claimed, done, │
|
|
72
|
+
│ failed) │
|
|
73
|
+
│ claimed_by, claimed_at
|
|
74
|
+
│ completed_at, result│
|
|
75
|
+
│ error │
|
|
76
|
+
├─────────────────────┤
|
|
77
|
+
│ heartbeats table │
|
|
78
|
+
│ (agent monitoring) │
|
|
79
|
+
└─────────────────────┘
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Key Features:**
|
|
83
|
+
- SQLite transactions ensure only one agent can claim a task
|
|
84
|
+
- Lease-based ownership with automatic timeout and recovery
|
|
85
|
+
- Heartbeat monitoring for detecting dead agents
|
|
86
|
+
- Full ACID compliance for task state
|
|
87
|
+
|
|
88
|
+
## Workflow
|
|
89
|
+
|
|
90
|
+
### 1. Parse Input
|
|
91
|
+
- Extract N (agent count)
|
|
92
|
+
- Extract agent-type
|
|
93
|
+
- Extract task description
|
|
94
|
+
- Validate N <= 5
|
|
95
|
+
|
|
96
|
+
### 2. Create Task Pool
|
|
97
|
+
- Analyze codebase based on task
|
|
98
|
+
- Break into file-specific subtasks
|
|
99
|
+
- Initialize SQLite database with task pool
|
|
100
|
+
- Each task gets: id, description, status (pending), and metadata columns
|
|
101
|
+
|
|
102
|
+
### 3. Spawn Agents
|
|
103
|
+
- Launch N agents via native subagent orchestration (`spawn_agent` + `wait`)
|
|
104
|
+
- Set `run_in_background: true` for all
|
|
105
|
+
- Each agent connects to the SQLite database
|
|
106
|
+
- Agents enter claiming loop automatically
|
|
107
|
+
|
|
108
|
+
### 3.1. Agent Preamble (IMPORTANT)
|
|
109
|
+
|
|
110
|
+
When spawning swarm agents, ALWAYS wrap the task with the worker preamble to prevent recursive sub-agent spawning:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { wrapWithPreamble } from '../agents/preamble.js';
|
|
114
|
+
|
|
115
|
+
// When spawning each agent:
|
|
116
|
+
const agentPrompt = wrapWithPreamble(`
|
|
117
|
+
Connect to swarm at ${cwd}/.omc/state/swarm.db
|
|
118
|
+
Claim tasks with claimTask('agent-${n}')
|
|
119
|
+
Complete work with completeTask() or failTask()
|
|
120
|
+
Send heartbeat every 60 seconds
|
|
121
|
+
Exit when hasPendingWork() returns false
|
|
122
|
+
`);
|
|
123
|
+
|
|
124
|
+
runWorker({
|
|
125
|
+
role: 'EXECUTOR',
|
|
126
|
+
prompt: agentPrompt,
|
|
127
|
+
runInBackground: true
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
The worker preamble ensures agents:
|
|
132
|
+
- Execute tasks directly using tools (Read, Write, Edit, Bash)
|
|
133
|
+
- Do NOT spawn sub-agents (prevents recursive agent storms)
|
|
134
|
+
- Report results with absolute file paths
|
|
135
|
+
|
|
136
|
+
### 4. Task Claiming Protocol (SQLite Transactional)
|
|
137
|
+
Each agent follows this loop:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
LOOP:
|
|
141
|
+
1. Call claimTask(agentId)
|
|
142
|
+
2. SQLite transaction:
|
|
143
|
+
- Find first pending task
|
|
144
|
+
- UPDATE status='claimed', claimed_by=agentId, claimed_at=now
|
|
145
|
+
- INSERT/UPDATE heartbeat record
|
|
146
|
+
- Atomically commit (only one agent succeeds)
|
|
147
|
+
3. Execute task
|
|
148
|
+
4. Call completeTask(agentId, taskId, result) or failTask()
|
|
149
|
+
5. GOTO LOOP (until hasPendingWork() returns false)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Atomic Claiming Details:**
|
|
153
|
+
- SQLite `IMMEDIATE` transaction prevents race conditions
|
|
154
|
+
- Only agent updating the row successfully gets the task
|
|
155
|
+
- Heartbeat automatically updated on claim
|
|
156
|
+
- If claim fails (already claimed), agent retries with next task
|
|
157
|
+
- Lease Timeout: 5 minutes per task
|
|
158
|
+
- If timeout exceeded + no heartbeat, cleanupStaleClaims releases task back to pending
|
|
159
|
+
|
|
160
|
+
### 5. Heartbeat Protocol
|
|
161
|
+
- Agents call `heartbeat(agentId)` every 60 seconds (or custom interval)
|
|
162
|
+
- Heartbeat records: agent_id, last_heartbeat timestamp, current_task_id
|
|
163
|
+
- Orchestrator runs cleanupStaleClaims every 60 seconds
|
|
164
|
+
- If heartbeat is stale (>5 minutes old) and task claimed, task auto-releases
|
|
165
|
+
|
|
166
|
+
### 6. Progress Tracking
|
|
167
|
+
- Orchestrator monitors via TaskOutput
|
|
168
|
+
- Shows live progress: pending/claimed/done/failed counts
|
|
169
|
+
- Active agent count via getActiveAgents()
|
|
170
|
+
- Reports which agent is working on which task via getAgentTasks()
|
|
171
|
+
- Detects idle agents (all tasks claimed by others)
|
|
172
|
+
|
|
173
|
+
### 7. Completion
|
|
174
|
+
Exit when ANY of:
|
|
175
|
+
- isSwarmComplete() returns true (all tasks done or failed)
|
|
176
|
+
- All agents idle (no pending tasks, no claimed tasks)
|
|
177
|
+
- User cancels via `$cancel`
|
|
178
|
+
|
|
179
|
+
## Storage
|
|
180
|
+
|
|
181
|
+
### SQLite Database (`.omc/state/swarm.db`)
|
|
182
|
+
|
|
183
|
+
The swarm uses a single SQLite database stored at `.omc/state/swarm.db`. This provides:
|
|
184
|
+
- **ACID compliance** - All task state transitions are atomic
|
|
185
|
+
- **Concurrent access** - Multiple agents query/update safely
|
|
186
|
+
- **Persistence** - State survives agent crashes
|
|
187
|
+
- **Query efficiency** - Fast status lookups and filtering
|
|
188
|
+
|
|
189
|
+
#### `tasks` Table Schema
|
|
190
|
+
```sql
|
|
191
|
+
CREATE TABLE tasks (
|
|
192
|
+
id TEXT PRIMARY KEY,
|
|
193
|
+
description TEXT NOT NULL,
|
|
194
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
195
|
+
-- pending: waiting to be claimed
|
|
196
|
+
-- claimed: claimed by an agent, in progress
|
|
197
|
+
-- done: completed successfully
|
|
198
|
+
-- failed: completed with error
|
|
199
|
+
claimed_by TEXT, -- agent ID that claimed this task
|
|
200
|
+
claimed_at INTEGER, -- Unix timestamp when claimed
|
|
201
|
+
completed_at INTEGER, -- Unix timestamp when completed
|
|
202
|
+
result TEXT, -- Optional result/output from task
|
|
203
|
+
error TEXT -- Error message if task failed
|
|
204
|
+
);
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### `heartbeats` Table Schema
|
|
208
|
+
```sql
|
|
209
|
+
CREATE TABLE heartbeats (
|
|
210
|
+
agent_id TEXT PRIMARY KEY,
|
|
211
|
+
last_heartbeat INTEGER NOT NULL, -- Unix timestamp of last heartbeat
|
|
212
|
+
current_task_id TEXT -- Task agent is currently working on
|
|
213
|
+
);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
#### `session` Table Schema
|
|
217
|
+
```sql
|
|
218
|
+
CREATE TABLE session (
|
|
219
|
+
id TEXT PRIMARY KEY,
|
|
220
|
+
agent_count INTEGER NOT NULL,
|
|
221
|
+
started_at INTEGER NOT NULL,
|
|
222
|
+
completed_at INTEGER,
|
|
223
|
+
active INTEGER DEFAULT 1
|
|
224
|
+
);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Task Claiming Protocol (Detailed)
|
|
228
|
+
|
|
229
|
+
### Atomic Claim Operation with SQLite
|
|
230
|
+
|
|
231
|
+
The core strength of the new implementation is transactional atomicity:
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
function claimTask(agentId: string): ClaimResult {
|
|
235
|
+
// Transaction ensures only ONE agent succeeds
|
|
236
|
+
const claimTransaction = db.transaction(() => {
|
|
237
|
+
// Step 1: Find first pending task
|
|
238
|
+
const task = db.prepare(
|
|
239
|
+
'SELECT id, description FROM tasks WHERE status = "pending" ORDER BY id LIMIT 1'
|
|
240
|
+
).get();
|
|
241
|
+
|
|
242
|
+
if (!task) {
|
|
243
|
+
return { success: false, reason: 'No pending tasks' };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Step 2: Attempt claim (will only succeed if status is still 'pending')
|
|
247
|
+
const result = db.prepare(
|
|
248
|
+
'UPDATE tasks SET status = "claimed", claimed_by = ?, claimed_at = ? WHERE id = ? AND status = "pending"'
|
|
249
|
+
).run(agentId, Date.now(), task.id);
|
|
250
|
+
|
|
251
|
+
if (result.changes === 0) {
|
|
252
|
+
// Another agent claimed it between SELECT and UPDATE - try next
|
|
253
|
+
return { success: false, reason: 'Task was claimed by another agent' };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Step 3: Update heartbeat to show we're alive and working
|
|
257
|
+
db.prepare(
|
|
258
|
+
'INSERT OR REPLACE INTO heartbeats (agent_id, last_heartbeat, current_task_id) VALUES (?, ?, ?)'
|
|
259
|
+
).run(agentId, Date.now(), task.id);
|
|
260
|
+
|
|
261
|
+
return { success: true, taskId: task.id, description: task.description };
|
|
262
|
+
}).immediate(); // Explicitly acquire RESERVED lock for immediate transaction
|
|
263
|
+
|
|
264
|
+
return claimTransaction(); // Atomic execution
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Why SQLite Transactions Work:**
|
|
269
|
+
- Transactions are called with `.immediate()` to acquire RESERVED lock
|
|
270
|
+
- Prevents other agents from modifying rows between SELECT and UPDATE
|
|
271
|
+
- All-or-nothing atomicity: claim succeeds completely or fails completely
|
|
272
|
+
- No race conditions, no lost updates
|
|
273
|
+
|
|
274
|
+
### Lease Timeout & Auto-Release
|
|
275
|
+
|
|
276
|
+
Tasks are automatically released if claimed too long without heartbeat:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
function cleanupStaleClaims(leaseTimeout: number = 5 * 60 * 1000) {
|
|
280
|
+
// Default 5-minute timeout
|
|
281
|
+
const cutoffTime = Date.now() - leaseTimeout;
|
|
282
|
+
|
|
283
|
+
const cleanupTransaction = db.transaction(() => {
|
|
284
|
+
// Find claimed tasks where:
|
|
285
|
+
// 1. Claimed longer than timeout, OR
|
|
286
|
+
// 2. Agent hasn't sent heartbeat in that time
|
|
287
|
+
const staleTasks = db.prepare(`
|
|
288
|
+
SELECT t.id
|
|
289
|
+
FROM tasks t
|
|
290
|
+
LEFT JOIN heartbeats h ON t.claimed_by = h.agent_id
|
|
291
|
+
WHERE t.status = 'claimed'
|
|
292
|
+
AND t.claimed_at < ?
|
|
293
|
+
AND (h.last_heartbeat IS NULL OR h.last_heartbeat < ?)
|
|
294
|
+
`).all(cutoffTime, cutoffTime);
|
|
295
|
+
|
|
296
|
+
// Release each stale task back to pending
|
|
297
|
+
for (const staleTask of staleTasks) {
|
|
298
|
+
db.prepare('UPDATE tasks SET status = "pending", claimed_by = NULL, claimed_at = NULL WHERE id = ?')
|
|
299
|
+
.run(staleTask.id);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return staleTasks.length;
|
|
303
|
+
}).immediate(); // Explicitly acquire RESERVED lock for immediate transaction
|
|
304
|
+
|
|
305
|
+
return cleanupTransaction();
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
**How Recovery Works:**
|
|
310
|
+
1. Orchestrator calls cleanupStaleClaims() every 60 seconds
|
|
311
|
+
2. If agent hasn't sent heartbeat in 5 minutes, task is auto-released
|
|
312
|
+
3. Another agent picks up the orphaned task
|
|
313
|
+
4. Original agent can continue working (it doesn't know it was released)
|
|
314
|
+
5. When original agent tries to mark task as done, verification fails safely
|
|
315
|
+
|
|
316
|
+
## API Reference
|
|
317
|
+
|
|
318
|
+
Agents interact with the swarm via a TypeScript API:
|
|
319
|
+
|
|
320
|
+
### Initialization
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import { startSwarm, connectToSwarm } from './swarm';
|
|
324
|
+
|
|
325
|
+
// Orchestrator starts the swarm
|
|
326
|
+
await startSwarm({
|
|
327
|
+
agentCount: 5,
|
|
328
|
+
tasks: ['fix a.ts', 'fix b.ts', ...],
|
|
329
|
+
leaseTimeout: 5 * 60 * 1000, // 5 minutes (default)
|
|
330
|
+
heartbeatInterval: 60 * 1000 // 60 seconds (default)
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Agents join existing swarm
|
|
334
|
+
await connectToSwarm(process.cwd());
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Agent Loop Pattern
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import {
|
|
341
|
+
claimTask,
|
|
342
|
+
completeTask,
|
|
343
|
+
failTask,
|
|
344
|
+
heartbeat,
|
|
345
|
+
hasPendingWork,
|
|
346
|
+
disconnectFromSwarm
|
|
347
|
+
} from './swarm';
|
|
348
|
+
|
|
349
|
+
const agentId = 'agent-1';
|
|
350
|
+
|
|
351
|
+
// Main work loop
|
|
352
|
+
while (hasPendingWork()) {
|
|
353
|
+
// Claim next task
|
|
354
|
+
const claim = claimTask(agentId);
|
|
355
|
+
|
|
356
|
+
if (!claim.success) {
|
|
357
|
+
console.log('No tasks available:', claim.reason);
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const { taskId, description } = claim;
|
|
362
|
+
console.log(`Agent ${agentId} working on: ${description}`);
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
// Do the work...
|
|
366
|
+
const result = await executeTask(description);
|
|
367
|
+
|
|
368
|
+
// Mark complete
|
|
369
|
+
completeTask(agentId, taskId, result);
|
|
370
|
+
console.log(`Agent ${agentId} completed task ${taskId}`);
|
|
371
|
+
|
|
372
|
+
} catch (error) {
|
|
373
|
+
// Mark failed
|
|
374
|
+
failTask(agentId, taskId, error.message);
|
|
375
|
+
console.error(`Agent ${agentId} failed on ${taskId}:`, error);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Send heartbeat every 60 seconds (while working on long tasks)
|
|
379
|
+
heartbeat(agentId);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Cleanup
|
|
383
|
+
disconnectFromSwarm();
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Core API Functions
|
|
387
|
+
|
|
388
|
+
#### `startSwarm(config: SwarmConfig): Promise<boolean>`
|
|
389
|
+
Initialize the swarm with task pool and start cleanup timer.
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
const success = await startSwarm({
|
|
393
|
+
agentCount: 5,
|
|
394
|
+
tasks: ['task 1', 'task 2', 'task 3'],
|
|
395
|
+
leaseTimeout: 5 * 60 * 1000,
|
|
396
|
+
heartbeatInterval: 60 * 1000
|
|
397
|
+
});
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### `stopSwarm(deleteDatabase?: boolean): boolean`
|
|
401
|
+
Stop the swarm and optionally delete the database.
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
stopSwarm(true); // Delete database on cleanup
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### `claimTask(agentId: string): ClaimResult`
|
|
408
|
+
Claim the next pending task. Returns `{ success, taskId, description, reason }`.
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
const claim = claimTask('agent-1');
|
|
412
|
+
if (claim.success) {
|
|
413
|
+
console.log(`Claimed: ${claim.description}`);
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
#### `completeTask(agentId: string, taskId: string, result?: string): boolean`
|
|
418
|
+
Mark a task as done. Only succeeds if agent still owns the task.
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
completeTask('agent-1', 'task-1', 'Fixed the bug');
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
#### `failTask(agentId: string, taskId: string, error: string): boolean`
|
|
425
|
+
Mark a task as failed with error details.
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
failTask('agent-1', 'task-1', 'Could not compile: missing dependency');
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
#### `heartbeat(agentId: string): boolean`
|
|
432
|
+
Send a heartbeat to indicate agent is alive. Call every 60 seconds during long-running tasks.
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
heartbeat('agent-1');
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### `cleanupStaleClaims(leaseTimeout?: number): number`
|
|
439
|
+
Manually trigger cleanup of expired claims. Called automatically every 60 seconds.
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
const released = cleanupStaleClaims(5 * 60 * 1000);
|
|
443
|
+
console.log(`Released ${released} stale tasks`);
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
#### `hasPendingWork(): boolean`
|
|
447
|
+
Check if there are unclaimed tasks available.
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
if (!hasPendingWork()) {
|
|
451
|
+
console.log('All tasks claimed or completed');
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
#### `isSwarmComplete(): boolean`
|
|
456
|
+
Check if all tasks are done or failed.
|
|
457
|
+
|
|
458
|
+
```typescript
|
|
459
|
+
if (isSwarmComplete()) {
|
|
460
|
+
console.log('Swarm finished!');
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### `getSwarmStats(): SwarmStats | null`
|
|
465
|
+
Get task counts and timing info.
|
|
466
|
+
|
|
467
|
+
```typescript
|
|
468
|
+
const stats = getSwarmStats();
|
|
469
|
+
console.log(`${stats.doneTasks}/${stats.totalTasks} done`);
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
#### `getActiveAgents(): number`
|
|
473
|
+
Get count of agents with recent heartbeats.
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
const active = getActiveAgents();
|
|
477
|
+
console.log(`${active} agents currently active`);
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### `getAllTasks(): SwarmTask[]`
|
|
481
|
+
Get all tasks with current status.
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
const tasks = getAllTasks();
|
|
485
|
+
const pending = tasks.filter(t => t.status === 'pending');
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
#### `getTasksWithStatus(status: string): SwarmTask[]`
|
|
489
|
+
Filter tasks by status: 'pending', 'claimed', 'done', 'failed'.
|
|
490
|
+
|
|
491
|
+
```typescript
|
|
492
|
+
const failed = getTasksWithStatus('failed');
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### `getAgentTasks(agentId: string): SwarmTask[]`
|
|
496
|
+
Get all tasks claimed by a specific agent.
|
|
497
|
+
|
|
498
|
+
```typescript
|
|
499
|
+
const myTasks = getAgentTasks('agent-1');
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### `retryTask(agentId: string, taskId: string): ClaimResult`
|
|
503
|
+
Attempt to reclaim a failed task.
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
const retry = retryTask('agent-1', 'task-1');
|
|
507
|
+
if (retry.success) {
|
|
508
|
+
console.log('Task reclaimed, trying again...');
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Configuration (SwarmConfig)
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
interface SwarmConfig {
|
|
516
|
+
agentCount: number; // Number of agents (1-5)
|
|
517
|
+
tasks: string[]; // Task descriptions
|
|
518
|
+
agentType?: string; // Agent type (default: 'executor')
|
|
519
|
+
leaseTimeout?: number; // Milliseconds (default: 5 min)
|
|
520
|
+
heartbeatInterval?: number; // Milliseconds (default: 60 sec)
|
|
521
|
+
cwd?: string; // Working directory
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### Types
|
|
526
|
+
|
|
527
|
+
```typescript
|
|
528
|
+
interface SwarmTask {
|
|
529
|
+
id: string;
|
|
530
|
+
description: string;
|
|
531
|
+
status: 'pending' | 'claimed' | 'done' | 'failed';
|
|
532
|
+
claimedBy: string | null;
|
|
533
|
+
claimedAt: number | null;
|
|
534
|
+
completedAt: number | null;
|
|
535
|
+
error?: string;
|
|
536
|
+
result?: string;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
interface ClaimResult {
|
|
540
|
+
success: boolean;
|
|
541
|
+
taskId: string | null;
|
|
542
|
+
description?: string;
|
|
543
|
+
reason?: string;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
interface SwarmStats {
|
|
547
|
+
totalTasks: number;
|
|
548
|
+
pendingTasks: number;
|
|
549
|
+
claimedTasks: number;
|
|
550
|
+
doneTasks: number;
|
|
551
|
+
failedTasks: number;
|
|
552
|
+
activeAgents: number;
|
|
553
|
+
elapsedTime: number;
|
|
554
|
+
}
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
## Key Parameters
|
|
558
|
+
|
|
559
|
+
- **Max Agents:** 5 (enforced by Codex background task limit)
|
|
560
|
+
- **Lease Timeout:** 5 minutes (default, configurable)
|
|
561
|
+
- Tasks claimed longer than this without heartbeat are auto-released
|
|
562
|
+
- **Heartbeat Interval:** 60 seconds (recommended)
|
|
563
|
+
- Agents should call `heartbeat()` at least this often
|
|
564
|
+
- Prevents false timeout while working on long tasks
|
|
565
|
+
- **Cleanup Interval:** 60 seconds
|
|
566
|
+
- Orchestrator automatically runs `cleanupStaleClaims()` to release orphaned tasks
|
|
567
|
+
- **Database:** SQLite (stored at `.omc/state/swarm.db`)
|
|
568
|
+
- One database per swarm session
|
|
569
|
+
- Survives agent crashes
|
|
570
|
+
- Provides ACID guarantees
|
|
571
|
+
|
|
572
|
+
## Error Handling & Recovery
|
|
573
|
+
|
|
574
|
+
### Agent Crash
|
|
575
|
+
- Task is claimed but agent stops sending heartbeats
|
|
576
|
+
- After 5 minutes of no heartbeat, cleanupStaleClaims() releases the task
|
|
577
|
+
- Task returns to 'pending' status for another agent to claim
|
|
578
|
+
- Original agent's incomplete work is safely abandoned
|
|
579
|
+
|
|
580
|
+
### Task Completion Failure
|
|
581
|
+
- Agent calls `completeTask()` but is no longer the owner (was released)
|
|
582
|
+
- The update silently fails (no agent matches in WHERE clause)
|
|
583
|
+
- Agent can detect this by checking return value
|
|
584
|
+
- Agent should log error and continue to next task
|
|
585
|
+
|
|
586
|
+
### Database Unavailable
|
|
587
|
+
- `startSwarm()` returns false if database initialization fails
|
|
588
|
+
- `claimTask()` returns `{ success: false, reason: 'Database not initialized' }`
|
|
589
|
+
- Check `isSwarmReady()` before proceeding
|
|
590
|
+
|
|
591
|
+
### All Agents Idle
|
|
592
|
+
- Orchestrator detects via `getActiveAgents() === 0` or `hasPendingWork() === false`
|
|
593
|
+
- Triggers final cleanup and marks swarm as complete
|
|
594
|
+
- Remaining failed tasks are preserved in database
|
|
595
|
+
|
|
596
|
+
### No Tasks Available
|
|
597
|
+
- `claimTask()` returns success=false with reason 'No pending tasks available'
|
|
598
|
+
- Agent should check `hasPendingWork()` before looping
|
|
599
|
+
- Safe for agent to exit cleanly when no work remains
|
|
600
|
+
|
|
601
|
+
## Cancel Swarm
|
|
602
|
+
|
|
603
|
+
User can cancel via `$cancel`:
|
|
604
|
+
- Stops orchestrator monitoring
|
|
605
|
+
- Signals all background agents to exit
|
|
606
|
+
- Preserves partial progress in SQLite database
|
|
607
|
+
- Marks session as "cancelled" in database
|
|
608
|
+
|
|
609
|
+
## Use Cases
|
|
610
|
+
|
|
611
|
+
### 1. Fix All Type Errors
|
|
612
|
+
```
|
|
613
|
+
$swarm 5:executor "fix all TypeScript type errors"
|
|
614
|
+
```
|
|
615
|
+
Spawns 5 executors, each claiming and fixing individual files.
|
|
616
|
+
|
|
617
|
+
### 2. Implement UI Components
|
|
618
|
+
```
|
|
619
|
+
$swarm 3:designer "implement Material-UI styling for all components in src/components/"
|
|
620
|
+
```
|
|
621
|
+
Spawns 3 designers, each styling different component files.
|
|
622
|
+
|
|
623
|
+
### 3. Security Audit
|
|
624
|
+
```
|
|
625
|
+
$swarm 4:security-reviewer "review all API endpoints for vulnerabilities"
|
|
626
|
+
```
|
|
627
|
+
Spawns 4 security reviewers, each auditing different endpoints.
|
|
628
|
+
|
|
629
|
+
### 4. Documentation Sprint
|
|
630
|
+
```
|
|
631
|
+
$swarm 2:writer "add JSDoc comments to all exported functions"
|
|
632
|
+
```
|
|
633
|
+
Spawns 2 writers, each documenting different modules.
|
|
634
|
+
|
|
635
|
+
## Benefits of SQLite-Based Implementation
|
|
636
|
+
|
|
637
|
+
### Atomicity & Safety
|
|
638
|
+
- **Race-Condition Free:** SQLite transactions guarantee only one agent claims each task
|
|
639
|
+
- **No Lost Updates:** ACID compliance means state changes are durable
|
|
640
|
+
- **Orphan Prevention:** Expired claims are automatically released without manual intervention
|
|
641
|
+
|
|
642
|
+
### Performance
|
|
643
|
+
- **Fast Queries:** Indexed lookups on task status and agent ID
|
|
644
|
+
- **Concurrent Access:** Multiple agents read/write without blocking
|
|
645
|
+
- **Minimal Lock Time:** Transactions are microseconds, not seconds
|
|
646
|
+
|
|
647
|
+
### Reliability
|
|
648
|
+
- **Crash Recovery:** Database survives agent failures
|
|
649
|
+
- **Automatic Cleanup:** Stale claims don't block progress
|
|
650
|
+
- **Lease-Based:** Time-based expiration prevents indefinite hangs
|
|
651
|
+
|
|
652
|
+
### Developer Experience
|
|
653
|
+
- **Simple API:** Just `claimTask()`, `completeTask()`, `heartbeat()`
|
|
654
|
+
- **Full Visibility:** Query any task or agent status at any time
|
|
655
|
+
- **Easy Debugging:** SQL queries show exact state without decoding JSON
|
|
656
|
+
|
|
657
|
+
### Scalability
|
|
658
|
+
- **10s to 1000s of Tasks:** SQLite handles easily
|
|
659
|
+
- **Full Task Retention:** Complete history in database for analysis
|
|
660
|
+
- **Extensible Schema:** Add custom columns for task metadata
|
|
661
|
+
|
|
662
|
+
## STATE CLEANUP ON COMPLETION
|
|
663
|
+
|
|
664
|
+
**IMPORTANT: Delete state files on completion - do NOT just set `active: false`**
|
|
665
|
+
|
|
666
|
+
When all tasks are done:
|
|
667
|
+
|
|
668
|
+
```bash
|
|
669
|
+
# Delete swarm state files
|
|
670
|
+
rm -f .omc/state/swarm-state.json
|
|
671
|
+
rm -f .omc/state/swarm-tasks.json
|
|
672
|
+
rm -f .omc/state/swarm-claims.json
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
## Implementation Notes
|
|
676
|
+
|
|
677
|
+
The orchestrator (main skill handler) is responsible for:
|
|
678
|
+
1. Initial task decomposition (via explore/architect)
|
|
679
|
+
2. Creating and initializing SQLite database via `startSwarm()`
|
|
680
|
+
3. Spawning N background agents
|
|
681
|
+
4. Monitoring progress via `getSwarmStats()` and `getActiveAgents()`
|
|
682
|
+
5. Running `cleanupStaleClaims()` automatically (via setInterval)
|
|
683
|
+
6. Detecting completion via `isSwarmComplete()`
|
|
684
|
+
7. Reporting final summary from database query
|
|
685
|
+
|
|
686
|
+
Each agent is a standard subagent invocation with:
|
|
687
|
+
- Spawn with `spawn_agent`, then coordinate via `wait`/`send_input`
|
|
688
|
+
- Agent-specific prompt with work loop instructions
|
|
689
|
+
- API import: `import { claimTask, completeTask, ... } from './swarm'`
|
|
690
|
+
- Connection: `await connectToSwarm(cwd)` to join existing swarm
|
|
691
|
+
- Loop: repeatedly call `claimTask()` → do work → `completeTask()` or `failTask()`
|