oh-my-claude-sisyphus 3.5.8 → 3.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (399) hide show
  1. package/agents/executor-high.md +2 -0
  2. package/agents/executor-low.md +2 -0
  3. package/agents/executor.md +2 -0
  4. package/agents/templates/base-agent.md +9 -0
  5. package/commands/cancel.md +8 -8
  6. package/commands/omc-setup.md +3 -3
  7. package/commands/release.md +1 -1
  8. package/commands/swarm.md +350 -148
  9. package/dist/__tests__/analytics/transcript-scanner.test.js +69 -27
  10. package/dist/__tests__/analytics/transcript-scanner.test.js.map +1 -1
  11. package/dist/__tests__/hooks.test.js +10 -9
  12. package/dist/__tests__/hooks.test.js.map +1 -1
  13. package/dist/__tests__/installer.test.js +2 -1
  14. package/dist/__tests__/installer.test.js.map +1 -1
  15. package/dist/agents/preamble.d.ts +14 -0
  16. package/dist/agents/preamble.d.ts.map +1 -0
  17. package/dist/agents/preamble.js +26 -0
  18. package/dist/agents/preamble.js.map +1 -0
  19. package/dist/analytics/session-manager.d.ts +24 -0
  20. package/dist/analytics/session-manager.d.ts.map +1 -1
  21. package/dist/analytics/session-manager.js +98 -9
  22. package/dist/analytics/session-manager.js.map +1 -1
  23. package/dist/analytics/transcript-scanner.d.ts +9 -8
  24. package/dist/analytics/transcript-scanner.d.ts.map +1 -1
  25. package/dist/analytics/transcript-scanner.js +146 -16
  26. package/dist/analytics/transcript-scanner.js.map +1 -1
  27. package/dist/cli/analytics.js +0 -0
  28. package/dist/cli/index.js +0 -0
  29. package/dist/hooks/autopilot/__tests__/cancel.test.js +14 -4
  30. package/dist/hooks/autopilot/__tests__/cancel.test.js.map +1 -1
  31. package/dist/hooks/autopilot/__tests__/state.test.js +1 -0
  32. package/dist/hooks/autopilot/__tests__/state.test.js.map +1 -1
  33. package/dist/hooks/autopilot/__tests__/summary.test.js +38 -3
  34. package/dist/hooks/autopilot/__tests__/summary.test.js.map +1 -1
  35. package/dist/hooks/autopilot/state.d.ts +1 -1
  36. package/dist/hooks/autopilot/state.d.ts.map +1 -1
  37. package/dist/hooks/autopilot/state.js +15 -8
  38. package/dist/hooks/autopilot/state.js.map +1 -1
  39. package/dist/hooks/empty-message-sanitizer/__tests__/index.test.d.ts +2 -0
  40. package/dist/hooks/empty-message-sanitizer/__tests__/index.test.d.ts.map +1 -0
  41. package/dist/hooks/empty-message-sanitizer/__tests__/index.test.js +416 -0
  42. package/dist/hooks/empty-message-sanitizer/__tests__/index.test.js.map +1 -0
  43. package/dist/hooks/index.d.ts +2 -0
  44. package/dist/hooks/index.d.ts.map +1 -1
  45. package/dist/hooks/index.js +7 -0
  46. package/dist/hooks/index.js.map +1 -1
  47. package/dist/hooks/keyword-detector/__tests__/index.test.d.ts +2 -0
  48. package/dist/hooks/keyword-detector/__tests__/index.test.d.ts.map +1 -0
  49. package/dist/hooks/keyword-detector/__tests__/index.test.js +427 -0
  50. package/dist/hooks/keyword-detector/__tests__/index.test.js.map +1 -0
  51. package/dist/hooks/mode-registry/index.d.ts +135 -0
  52. package/dist/hooks/mode-registry/index.d.ts.map +1 -0
  53. package/dist/hooks/mode-registry/index.js +445 -0
  54. package/dist/hooks/mode-registry/index.js.map +1 -0
  55. package/dist/hooks/mode-registry/types.d.ts +31 -0
  56. package/dist/hooks/mode-registry/types.d.ts.map +1 -0
  57. package/dist/hooks/mode-registry/types.js +7 -0
  58. package/dist/hooks/mode-registry/types.js.map +1 -0
  59. package/dist/hooks/ralph/loop.js +6 -6
  60. package/dist/hooks/ralph/loop.js.map +1 -1
  61. package/dist/hooks/swarm/__tests__/claiming.test.d.ts +2 -0
  62. package/dist/hooks/swarm/__tests__/claiming.test.d.ts.map +1 -0
  63. package/dist/hooks/swarm/__tests__/claiming.test.js +170 -0
  64. package/dist/hooks/swarm/__tests__/claiming.test.js.map +1 -0
  65. package/dist/hooks/swarm/__tests__/index.test.d.ts +2 -0
  66. package/dist/hooks/swarm/__tests__/index.test.d.ts.map +1 -0
  67. package/dist/hooks/swarm/__tests__/index.test.js +157 -0
  68. package/dist/hooks/swarm/__tests__/index.test.js.map +1 -0
  69. package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts +2 -0
  70. package/dist/hooks/swarm/__tests__/mode-registry.test.d.ts.map +1 -0
  71. package/dist/hooks/swarm/__tests__/mode-registry.test.js +177 -0
  72. package/dist/hooks/swarm/__tests__/mode-registry.test.js.map +1 -0
  73. package/dist/hooks/swarm/claiming.d.ts +101 -0
  74. package/dist/hooks/swarm/claiming.d.ts.map +1 -0
  75. package/dist/hooks/swarm/claiming.js +460 -0
  76. package/dist/hooks/swarm/claiming.js.map +1 -0
  77. package/dist/hooks/swarm/index.d.ts +221 -0
  78. package/dist/hooks/swarm/index.d.ts.map +1 -0
  79. package/dist/hooks/swarm/index.js +413 -0
  80. package/dist/hooks/swarm/index.js.map +1 -0
  81. package/dist/hooks/swarm/state.d.ts +94 -0
  82. package/dist/hooks/swarm/state.d.ts.map +1 -0
  83. package/dist/hooks/swarm/state.js +530 -0
  84. package/dist/hooks/swarm/state.js.map +1 -0
  85. package/dist/hooks/swarm/types.d.ts +116 -0
  86. package/dist/hooks/swarm/types.d.ts.map +1 -0
  87. package/dist/hooks/swarm/types.js +22 -0
  88. package/dist/hooks/swarm/types.js.map +1 -0
  89. package/dist/hooks/think-mode/__tests__/index.test.d.ts +2 -0
  90. package/dist/hooks/think-mode/__tests__/index.test.d.ts.map +1 -0
  91. package/dist/hooks/think-mode/__tests__/index.test.js +556 -0
  92. package/dist/hooks/think-mode/__tests__/index.test.js.map +1 -0
  93. package/dist/hooks/ultrapilot/decomposer.d.ts +141 -0
  94. package/dist/hooks/ultrapilot/decomposer.d.ts.map +1 -0
  95. package/dist/hooks/ultrapilot/decomposer.js +377 -0
  96. package/dist/hooks/ultrapilot/decomposer.js.map +1 -0
  97. package/dist/hooks/ultrapilot/index.d.ts +31 -0
  98. package/dist/hooks/ultrapilot/index.d.ts.map +1 -1
  99. package/dist/hooks/ultrapilot/index.js +43 -2
  100. package/dist/hooks/ultrapilot/index.js.map +1 -1
  101. package/dist/hooks/ultrapilot/state.d.ts +1 -1
  102. package/dist/hooks/ultrapilot/state.d.ts.map +1 -1
  103. package/dist/hooks/ultrapilot/state.js +7 -0
  104. package/dist/hooks/ultrapilot/state.js.map +1 -1
  105. package/dist/hooks/ultraqa/index.js +5 -5
  106. package/dist/hooks/ultraqa/index.js.map +1 -1
  107. package/dist/hooks/ultrawork/index.js +3 -3
  108. package/dist/hooks/ultrawork/index.js.map +1 -1
  109. package/dist/installer/index.d.ts.map +1 -1
  110. package/dist/installer/index.js +8 -0
  111. package/dist/installer/index.js.map +1 -1
  112. package/package.json +3 -1
  113. package/skills/autopilot/SKILL.md +18 -0
  114. package/skills/cancel/SKILL.md +166 -141
  115. package/skills/ecomode/SKILL.md +14 -0
  116. package/skills/omc-setup/SKILL.md +27 -3
  117. package/skills/pipeline/SKILL.md +13 -0
  118. package/skills/ralph/SKILL.md +22 -1
  119. package/skills/release/SKILL.md +1 -1
  120. package/skills/swarm/SKILL.md +521 -197
  121. package/skills/ultrapilot/SKILL.md +82 -13
  122. package/skills/ultraqa/SKILL.md +13 -0
  123. package/skills/ultrawork/SKILL.md +14 -0
  124. package/dist/__tests__/analytics/analytics-summary.test.d.ts +0 -2
  125. package/dist/__tests__/analytics/analytics-summary.test.d.ts.map +0 -1
  126. package/dist/__tests__/analytics/analytics-summary.test.js +0 -267
  127. package/dist/__tests__/analytics/analytics-summary.test.js.map +0 -1
  128. package/dist/__tests__/analytics/cost-estimator.test.d.ts +0 -2
  129. package/dist/__tests__/analytics/cost-estimator.test.d.ts.map +0 -1
  130. package/dist/__tests__/analytics/cost-estimator.test.js +0 -212
  131. package/dist/__tests__/analytics/cost-estimator.test.js.map +0 -1
  132. package/dist/__tests__/hooks/auto-slash-command/executor.test.d.ts +0 -7
  133. package/dist/__tests__/hooks/auto-slash-command/executor.test.d.ts.map +0 -1
  134. package/dist/__tests__/hooks/auto-slash-command/executor.test.js +0 -374
  135. package/dist/__tests__/hooks/auto-slash-command/executor.test.js.map +0 -1
  136. package/dist/__tests__/hud/auto-tracking.integration.test.d.ts +0 -2
  137. package/dist/__tests__/hud/auto-tracking.integration.test.d.ts.map +0 -1
  138. package/dist/__tests__/hud/auto-tracking.integration.test.js +0 -12
  139. package/dist/__tests__/hud/auto-tracking.integration.test.js.map +0 -1
  140. package/dist/__tests__/learned-skills/config.test.d.ts +0 -2
  141. package/dist/__tests__/learned-skills/config.test.d.ts.map +0 -1
  142. package/dist/__tests__/learned-skills/config.test.js +0 -37
  143. package/dist/__tests__/learned-skills/config.test.js.map +0 -1
  144. package/dist/__tests__/learned-skills/detector.test.d.ts +0 -2
  145. package/dist/__tests__/learned-skills/detector.test.d.ts.map +0 -1
  146. package/dist/__tests__/learned-skills/detector.test.js +0 -99
  147. package/dist/__tests__/learned-skills/detector.test.js.map +0 -1
  148. package/dist/__tests__/learned-skills/finder.test.d.ts +0 -2
  149. package/dist/__tests__/learned-skills/finder.test.d.ts.map +0 -1
  150. package/dist/__tests__/learned-skills/finder.test.js +0 -59
  151. package/dist/__tests__/learned-skills/finder.test.js.map +0 -1
  152. package/dist/__tests__/learned-skills/loader.test.d.ts +0 -2
  153. package/dist/__tests__/learned-skills/loader.test.d.ts.map +0 -1
  154. package/dist/__tests__/learned-skills/loader.test.js +0 -69
  155. package/dist/__tests__/learned-skills/loader.test.js.map +0 -1
  156. package/dist/__tests__/learned-skills/parser.test.d.ts +0 -2
  157. package/dist/__tests__/learned-skills/parser.test.d.ts.map +0 -1
  158. package/dist/__tests__/learned-skills/parser.test.js +0 -81
  159. package/dist/__tests__/learned-skills/parser.test.js.map +0 -1
  160. package/dist/__tests__/learned-skills/validator.test.d.ts +0 -2
  161. package/dist/__tests__/learned-skills/validator.test.d.ts.map +0 -1
  162. package/dist/__tests__/learned-skills/validator.test.js +0 -85
  163. package/dist/__tests__/learned-skills/validator.test.js.map +0 -1
  164. package/dist/agents/document-writer.d.ts +0 -11
  165. package/dist/agents/document-writer.d.ts.map +0 -1
  166. package/dist/agents/document-writer.js +0 -209
  167. package/dist/agents/document-writer.js.map +0 -1
  168. package/dist/agents/frontend-engineer.d.ts +0 -11
  169. package/dist/agents/frontend-engineer.d.ts.map +0 -1
  170. package/dist/agents/frontend-engineer.js +0 -115
  171. package/dist/agents/frontend-engineer.js.map +0 -1
  172. package/dist/agents/librarian.d.ts +0 -12
  173. package/dist/agents/librarian.d.ts.map +0 -1
  174. package/dist/agents/librarian.js +0 -103
  175. package/dist/agents/librarian.js.map +0 -1
  176. package/dist/agents/metis.d.ts +0 -12
  177. package/dist/agents/metis.d.ts.map +0 -1
  178. package/dist/agents/metis.js +0 -117
  179. package/dist/agents/metis.js.map +0 -1
  180. package/dist/agents/momus.d.ts +0 -12
  181. package/dist/agents/momus.d.ts.map +0 -1
  182. package/dist/agents/momus.js +0 -128
  183. package/dist/agents/momus.js.map +0 -1
  184. package/dist/agents/multimodal-looker.d.ts +0 -11
  185. package/dist/agents/multimodal-looker.d.ts.map +0 -1
  186. package/dist/agents/multimodal-looker.js +0 -70
  187. package/dist/agents/multimodal-looker.js.map +0 -1
  188. package/dist/agents/oracle.d.ts +0 -13
  189. package/dist/agents/oracle.d.ts.map +0 -1
  190. package/dist/agents/oracle.js +0 -191
  191. package/dist/agents/oracle.js.map +0 -1
  192. package/dist/agents/orchestrator-sisyphus.d.ts +0 -11
  193. package/dist/agents/orchestrator-sisyphus.d.ts.map +0 -1
  194. package/dist/agents/orchestrator-sisyphus.js +0 -115
  195. package/dist/agents/orchestrator-sisyphus.js.map +0 -1
  196. package/dist/agents/prometheus.d.ts +0 -12
  197. package/dist/agents/prometheus.d.ts.map +0 -1
  198. package/dist/agents/prometheus.js +0 -195
  199. package/dist/agents/prometheus.js.map +0 -1
  200. package/dist/agents/sisyphus-junior.d.ts +0 -12
  201. package/dist/agents/sisyphus-junior.d.ts.map +0 -1
  202. package/dist/agents/sisyphus-junior.js +0 -93
  203. package/dist/agents/sisyphus-junior.js.map +0 -1
  204. package/dist/cli/components/CostDashboard.d.ts +0 -15
  205. package/dist/cli/components/CostDashboard.d.ts.map +0 -1
  206. package/dist/cli/components/CostDashboard.js +0 -15
  207. package/dist/cli/components/CostDashboard.js.map +0 -1
  208. package/dist/cli/components/LiveStats.d.ts +0 -16
  209. package/dist/cli/components/LiveStats.d.ts.map +0 -1
  210. package/dist/cli/components/LiveStats.js +0 -16
  211. package/dist/cli/components/LiveStats.js.map +0 -1
  212. package/dist/cli/components/SessionBrowser.d.ts +0 -14
  213. package/dist/cli/components/SessionBrowser.d.ts.map +0 -1
  214. package/dist/cli/components/SessionBrowser.js +0 -14
  215. package/dist/cli/components/SessionBrowser.js.map +0 -1
  216. package/dist/cli/tui.d.ts +0 -21
  217. package/dist/cli/tui.d.ts.map +0 -1
  218. package/dist/cli/tui.js +0 -21
  219. package/dist/cli/tui.js.map +0 -1
  220. package/dist/hooks/autopilot/signals.d.ts +0 -20
  221. package/dist/hooks/autopilot/signals.d.ts.map +0 -1
  222. package/dist/hooks/autopilot/signals.js +0 -75
  223. package/dist/hooks/autopilot/signals.js.map +0 -1
  224. package/dist/hooks/autopilot/summary.d.ts +0 -27
  225. package/dist/hooks/autopilot/summary.d.ts.map +0 -1
  226. package/dist/hooks/autopilot/summary.js +0 -160
  227. package/dist/hooks/autopilot/summary.js.map +0 -1
  228. package/dist/hooks/autopilot/transition.d.ts +0 -39
  229. package/dist/hooks/autopilot/transition.d.ts.map +0 -1
  230. package/dist/hooks/autopilot/transition.js +0 -216
  231. package/dist/hooks/autopilot/transition.js.map +0 -1
  232. package/dist/hooks/context-window-limit-recovery/constants.d.ts +0 -28
  233. package/dist/hooks/context-window-limit-recovery/constants.d.ts.map +0 -1
  234. package/dist/hooks/context-window-limit-recovery/constants.js +0 -85
  235. package/dist/hooks/context-window-limit-recovery/constants.js.map +0 -1
  236. package/dist/hooks/context-window-limit-recovery/index.d.ts +0 -62
  237. package/dist/hooks/context-window-limit-recovery/index.d.ts.map +0 -1
  238. package/dist/hooks/context-window-limit-recovery/index.js +0 -201
  239. package/dist/hooks/context-window-limit-recovery/index.js.map +0 -1
  240. package/dist/hooks/context-window-limit-recovery/parser.d.ts +0 -31
  241. package/dist/hooks/context-window-limit-recovery/parser.d.ts.map +0 -1
  242. package/dist/hooks/context-window-limit-recovery/parser.js +0 -241
  243. package/dist/hooks/context-window-limit-recovery/parser.js.map +0 -1
  244. package/dist/hooks/context-window-limit-recovery/types.d.ts +0 -84
  245. package/dist/hooks/context-window-limit-recovery/types.d.ts.map +0 -1
  246. package/dist/hooks/context-window-limit-recovery/types.js +0 -34
  247. package/dist/hooks/context-window-limit-recovery/types.js.map +0 -1
  248. package/dist/hooks/edit-error-recovery/index.d.ts +0 -62
  249. package/dist/hooks/edit-error-recovery/index.d.ts.map +0 -1
  250. package/dist/hooks/edit-error-recovery/index.js +0 -89
  251. package/dist/hooks/edit-error-recovery/index.js.map +0 -1
  252. package/dist/hooks/learned-skills/config.d.ts +0 -53
  253. package/dist/hooks/learned-skills/config.d.ts.map +0 -1
  254. package/dist/hooks/learned-skills/config.js +0 -103
  255. package/dist/hooks/learned-skills/config.js.map +0 -1
  256. package/dist/hooks/learned-skills/constants.d.ts +0 -24
  257. package/dist/hooks/learned-skills/constants.d.ts.map +0 -1
  258. package/dist/hooks/learned-skills/constants.js +0 -26
  259. package/dist/hooks/learned-skills/constants.js.map +0 -1
  260. package/dist/hooks/learned-skills/detection-hook.d.ts +0 -39
  261. package/dist/hooks/learned-skills/detection-hook.d.ts.map +0 -1
  262. package/dist/hooks/learned-skills/detection-hook.js +0 -83
  263. package/dist/hooks/learned-skills/detection-hook.js.map +0 -1
  264. package/dist/hooks/learned-skills/detector.d.ts +0 -30
  265. package/dist/hooks/learned-skills/detector.d.ts.map +0 -1
  266. package/dist/hooks/learned-skills/detector.js +0 -150
  267. package/dist/hooks/learned-skills/detector.js.map +0 -1
  268. package/dist/hooks/learned-skills/finder.d.ts +0 -21
  269. package/dist/hooks/learned-skills/finder.d.ts.map +0 -1
  270. package/dist/hooks/learned-skills/finder.js +0 -117
  271. package/dist/hooks/learned-skills/finder.js.map +0 -1
  272. package/dist/hooks/learned-skills/index.d.ts +0 -62
  273. package/dist/hooks/learned-skills/index.d.ts.map +0 -1
  274. package/dist/hooks/learned-skills/index.js +0 -137
  275. package/dist/hooks/learned-skills/index.js.map +0 -1
  276. package/dist/hooks/learned-skills/loader.d.ts +0 -20
  277. package/dist/hooks/learned-skills/loader.d.ts.map +0 -1
  278. package/dist/hooks/learned-skills/loader.js +0 -107
  279. package/dist/hooks/learned-skills/loader.js.map +0 -1
  280. package/dist/hooks/learned-skills/parser.d.ts +0 -21
  281. package/dist/hooks/learned-skills/parser.d.ts.map +0 -1
  282. package/dist/hooks/learned-skills/parser.js +0 -190
  283. package/dist/hooks/learned-skills/parser.js.map +0 -1
  284. package/dist/hooks/learned-skills/promotion.d.ts +0 -29
  285. package/dist/hooks/learned-skills/promotion.d.ts.map +0 -1
  286. package/dist/hooks/learned-skills/promotion.js +0 -87
  287. package/dist/hooks/learned-skills/promotion.js.map +0 -1
  288. package/dist/hooks/learned-skills/types.d.ts +0 -109
  289. package/dist/hooks/learned-skills/types.d.ts.map +0 -1
  290. package/dist/hooks/learned-skills/types.js +0 -8
  291. package/dist/hooks/learned-skills/types.js.map +0 -1
  292. package/dist/hooks/learned-skills/validator.d.ts +0 -15
  293. package/dist/hooks/learned-skills/validator.d.ts.map +0 -1
  294. package/dist/hooks/learned-skills/validator.js +0 -87
  295. package/dist/hooks/learned-skills/validator.js.map +0 -1
  296. package/dist/hooks/learned-skills/writer.d.ts +0 -27
  297. package/dist/hooks/learned-skills/writer.d.ts.map +0 -1
  298. package/dist/hooks/learned-skills/writer.js +0 -126
  299. package/dist/hooks/learned-skills/writer.js.map +0 -1
  300. package/dist/hooks/mnemosyne/config.d.ts +0 -53
  301. package/dist/hooks/mnemosyne/config.d.ts.map +0 -1
  302. package/dist/hooks/mnemosyne/config.js +0 -103
  303. package/dist/hooks/mnemosyne/config.js.map +0 -1
  304. package/dist/hooks/mnemosyne/constants.d.ts +0 -24
  305. package/dist/hooks/mnemosyne/constants.d.ts.map +0 -1
  306. package/dist/hooks/mnemosyne/constants.js +0 -26
  307. package/dist/hooks/mnemosyne/constants.js.map +0 -1
  308. package/dist/hooks/mnemosyne/detection-hook.d.ts +0 -39
  309. package/dist/hooks/mnemosyne/detection-hook.d.ts.map +0 -1
  310. package/dist/hooks/mnemosyne/detection-hook.js +0 -83
  311. package/dist/hooks/mnemosyne/detection-hook.js.map +0 -1
  312. package/dist/hooks/mnemosyne/detector.d.ts +0 -30
  313. package/dist/hooks/mnemosyne/detector.d.ts.map +0 -1
  314. package/dist/hooks/mnemosyne/detector.js +0 -150
  315. package/dist/hooks/mnemosyne/detector.js.map +0 -1
  316. package/dist/hooks/mnemosyne/finder.d.ts +0 -21
  317. package/dist/hooks/mnemosyne/finder.d.ts.map +0 -1
  318. package/dist/hooks/mnemosyne/finder.js +0 -117
  319. package/dist/hooks/mnemosyne/finder.js.map +0 -1
  320. package/dist/hooks/mnemosyne/index.d.ts +0 -62
  321. package/dist/hooks/mnemosyne/index.d.ts.map +0 -1
  322. package/dist/hooks/mnemosyne/index.js +0 -137
  323. package/dist/hooks/mnemosyne/index.js.map +0 -1
  324. package/dist/hooks/mnemosyne/loader.d.ts +0 -20
  325. package/dist/hooks/mnemosyne/loader.d.ts.map +0 -1
  326. package/dist/hooks/mnemosyne/loader.js +0 -113
  327. package/dist/hooks/mnemosyne/loader.js.map +0 -1
  328. package/dist/hooks/mnemosyne/parser.d.ts +0 -21
  329. package/dist/hooks/mnemosyne/parser.d.ts.map +0 -1
  330. package/dist/hooks/mnemosyne/parser.js +0 -190
  331. package/dist/hooks/mnemosyne/parser.js.map +0 -1
  332. package/dist/hooks/mnemosyne/promotion.d.ts +0 -29
  333. package/dist/hooks/mnemosyne/promotion.d.ts.map +0 -1
  334. package/dist/hooks/mnemosyne/promotion.js +0 -87
  335. package/dist/hooks/mnemosyne/promotion.js.map +0 -1
  336. package/dist/hooks/mnemosyne/types.d.ts +0 -109
  337. package/dist/hooks/mnemosyne/types.d.ts.map +0 -1
  338. package/dist/hooks/mnemosyne/types.js +0 -8
  339. package/dist/hooks/mnemosyne/types.js.map +0 -1
  340. package/dist/hooks/mnemosyne/validator.d.ts +0 -15
  341. package/dist/hooks/mnemosyne/validator.d.ts.map +0 -1
  342. package/dist/hooks/mnemosyne/validator.js +0 -87
  343. package/dist/hooks/mnemosyne/validator.js.map +0 -1
  344. package/dist/hooks/mnemosyne/writer.d.ts +0 -27
  345. package/dist/hooks/mnemosyne/writer.d.ts.map +0 -1
  346. package/dist/hooks/mnemosyne/writer.js +0 -126
  347. package/dist/hooks/mnemosyne/writer.js.map +0 -1
  348. package/dist/hooks/ralph-loop/index.d.ts +0 -116
  349. package/dist/hooks/ralph-loop/index.d.ts.map +0 -1
  350. package/dist/hooks/ralph-loop/index.js +0 -322
  351. package/dist/hooks/ralph-loop/index.js.map +0 -1
  352. package/dist/hooks/ralph-prd/index.d.ts +0 -130
  353. package/dist/hooks/ralph-prd/index.d.ts.map +0 -1
  354. package/dist/hooks/ralph-prd/index.js +0 -310
  355. package/dist/hooks/ralph-prd/index.js.map +0 -1
  356. package/dist/hooks/ralph-progress/index.d.ts +0 -102
  357. package/dist/hooks/ralph-progress/index.d.ts.map +0 -1
  358. package/dist/hooks/ralph-progress/index.js +0 -408
  359. package/dist/hooks/ralph-progress/index.js.map +0 -1
  360. package/dist/hooks/ralph-verifier/index.d.ts +0 -72
  361. package/dist/hooks/ralph-verifier/index.d.ts.map +0 -1
  362. package/dist/hooks/ralph-verifier/index.js +0 -223
  363. package/dist/hooks/ralph-verifier/index.js.map +0 -1
  364. package/dist/hooks/session-recovery/constants.d.ts +0 -56
  365. package/dist/hooks/session-recovery/constants.d.ts.map +0 -1
  366. package/dist/hooks/session-recovery/constants.js +0 -78
  367. package/dist/hooks/session-recovery/constants.js.map +0 -1
  368. package/dist/hooks/session-recovery/index.d.ts +0 -53
  369. package/dist/hooks/session-recovery/index.d.ts.map +0 -1
  370. package/dist/hooks/session-recovery/index.js +0 -321
  371. package/dist/hooks/session-recovery/index.js.map +0 -1
  372. package/dist/hooks/session-recovery/storage.d.ts +0 -76
  373. package/dist/hooks/session-recovery/storage.d.ts.map +0 -1
  374. package/dist/hooks/session-recovery/storage.js +0 -383
  375. package/dist/hooks/session-recovery/storage.js.map +0 -1
  376. package/dist/hooks/session-recovery/types.d.ts +0 -145
  377. package/dist/hooks/session-recovery/types.d.ts.map +0 -1
  378. package/dist/hooks/session-recovery/types.js +0 -8
  379. package/dist/hooks/session-recovery/types.js.map +0 -1
  380. package/dist/hooks/sisyphus-orchestrator/constants.d.ts +0 -23
  381. package/dist/hooks/sisyphus-orchestrator/constants.d.ts.map +0 -1
  382. package/dist/hooks/sisyphus-orchestrator/constants.js +0 -142
  383. package/dist/hooks/sisyphus-orchestrator/constants.js.map +0 -1
  384. package/dist/hooks/sisyphus-orchestrator/index.d.ts +0 -113
  385. package/dist/hooks/sisyphus-orchestrator/index.d.ts.map +0 -1
  386. package/dist/hooks/sisyphus-orchestrator/index.js +0 -309
  387. package/dist/hooks/sisyphus-orchestrator/index.js.map +0 -1
  388. package/dist/hooks/ultraqa-loop/index.d.ts +0 -94
  389. package/dist/hooks/ultraqa-loop/index.d.ts.map +0 -1
  390. package/dist/hooks/ultraqa-loop/index.js +0 -216
  391. package/dist/hooks/ultraqa-loop/index.js.map +0 -1
  392. package/dist/hooks/ultrawork-state/index.d.ts +0 -62
  393. package/dist/hooks/ultrawork-state/index.d.ts.map +0 -1
  394. package/dist/hooks/ultrawork-state/index.js +0 -208
  395. package/dist/hooks/ultrawork-state/index.js.map +0 -1
  396. package/dist/hud/sisyphus-state.d.ts +0 -31
  397. package/dist/hud/sisyphus-state.d.ts.map +0 -1
  398. package/dist/hud/sisyphus-state.js +0 -163
  399. package/dist/hud/sisyphus-state.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: swarm
3
- description: N coordinated agents on shared task list with atomic claiming
3
+ description: N coordinated agents on shared task list with SQLite-based atomic claiming
4
4
  ---
5
5
 
6
6
  # Swarm Skill
7
7
 
8
- Spawn N coordinated agents working on a shared task list with atomic claiming. Like a dev team tackling multiple files in parallel.
8
+ 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.
9
9
 
10
10
  ## Usage
11
11
 
@@ -44,14 +44,29 @@ User: "/swarm 5:executor fix all TypeScript errors"
44
44
  +--+--+--+--+
45
45
  |
46
46
  v
47
- [SHARED TASK LIST]
48
- - Fix a.ts (claimed E1)
49
- - Fix b.ts (done E2)
50
- - Fix c.ts (claimed E3)
51
- - Fix d.ts (pending)
52
- ...
47
+ [SQLITE DATABASE]
48
+ ┌─────────────────────┐
49
+ tasks table │
50
+ ├─────────────────────┤
51
+ id, description │
52
+ │ status (pending, │
53
+ │ claimed, done, │
54
+ │ failed) │
55
+ │ claimed_by, claimed_at
56
+ │ completed_at, result│
57
+ │ error │
58
+ ├─────────────────────┤
59
+ │ heartbeats table │
60
+ │ (agent monitoring) │
61
+ └─────────────────────┘
53
62
  ```
54
63
 
64
+ **Key Features:**
65
+ - SQLite transactions ensure only one agent can claim a task
66
+ - Lease-based ownership with automatic timeout and recovery
67
+ - Heartbeat monitoring for detecting dead agents
68
+ - Full ACID compliance for task state
69
+
55
70
  ## Workflow
56
71
 
57
72
  ### 1. Parse Input
@@ -60,243 +75,518 @@ User: "/swarm 5:executor fix all TypeScript errors"
60
75
  - Extract task description
61
76
  - Validate N <= 5
62
77
 
63
- ### 2. Create Task List
78
+ ### 2. Create Task Pool
64
79
  - Analyze codebase based on task
65
80
  - Break into file-specific subtasks
66
- - Initialize shared task list with all subtasks
67
- - Each task gets: id, file, description, status, owner, timestamp
81
+ - Initialize SQLite database with task pool
82
+ - Each task gets: id, description, status (pending), and metadata columns
68
83
 
69
84
  ### 3. Spawn Agents
70
85
  - Launch N agents via Task tool
71
86
  - Set `run_in_background: true` for all
72
- - Each agent gets:
73
- - Reference to shared task list
74
- - Claiming protocol instructions
75
- - Completion criteria
87
+ - Each agent connects to the SQLite database
88
+ - Agents enter claiming loop automatically
89
+
90
+ ### 3.1. Agent Preamble (IMPORTANT)
91
+
92
+ When spawning swarm agents, ALWAYS wrap the task with the worker preamble to prevent recursive sub-agent spawning:
93
+
94
+ ```typescript
95
+ import { wrapWithPreamble } from '../agents/preamble.js';
96
+
97
+ // When spawning each agent:
98
+ const agentPrompt = wrapWithPreamble(`
99
+ Connect to swarm at ${cwd}/.omc/state/swarm.db
100
+ Claim tasks with claimTask('agent-${n}')
101
+ Complete work with completeTask() or failTask()
102
+ Send heartbeat every 60 seconds
103
+ Exit when hasPendingWork() returns false
104
+ `);
105
+
106
+ Task({
107
+ subagent_type: 'oh-my-claudecode:executor',
108
+ prompt: agentPrompt,
109
+ run_in_background: true
110
+ });
111
+ ```
112
+
113
+ The worker preamble ensures agents:
114
+ - Execute tasks directly using tools (Read, Write, Edit, Bash)
115
+ - Do NOT spawn sub-agents (prevents recursive agent storms)
116
+ - Report results with absolute file paths
76
117
 
77
- ### 4. Task Claiming Protocol
118
+ ### 4. Task Claiming Protocol (SQLite Transactional)
78
119
  Each agent follows this loop:
79
120
 
80
121
  ```
81
122
  LOOP:
82
- 1. Read swarm-tasks.json
83
- 2. Find first pending task
84
- 3. Atomically claim task (check status, set to claimed, add owner)
85
- 4. Execute task
86
- 5. Mark task as done
87
- 6. GOTO LOOP (until no pending tasks)
88
- ```
89
-
90
- **Atomic Claiming:**
91
- - Read current task status
92
- - If still "pending", claim it
93
- - If someone else claimed, try next task
94
- - Timeout: 5 minutes per task
95
- - If timeout exceeded, task auto-releases to pending
96
-
97
- ### 5. Progress Tracking
123
+ 1. Call claimTask(agentId)
124
+ 2. SQLite transaction:
125
+ - Find first pending task
126
+ - UPDATE status='claimed', claimed_by=agentId, claimed_at=now
127
+ - INSERT/UPDATE heartbeat record
128
+ - Atomically commit (only one agent succeeds)
129
+ 3. Execute task
130
+ 4. Call completeTask(agentId, taskId, result) or failTask()
131
+ 5. GOTO LOOP (until hasPendingWork() returns false)
132
+ ```
133
+
134
+ **Atomic Claiming Details:**
135
+ - SQLite `IMMEDIATE` transaction prevents race conditions
136
+ - Only agent updating the row successfully gets the task
137
+ - Heartbeat automatically updated on claim
138
+ - If claim fails (already claimed), agent retries with next task
139
+ - Lease Timeout: 5 minutes per task
140
+ - If timeout exceeded + no heartbeat, cleanupStaleClaims releases task back to pending
141
+
142
+ ### 5. Heartbeat Protocol
143
+ - Agents call `heartbeat(agentId)` every 60 seconds (or custom interval)
144
+ - Heartbeat records: agent_id, last_heartbeat timestamp, current_task_id
145
+ - Orchestrator runs cleanupStaleClaims every 60 seconds
146
+ - If heartbeat is stale (>5 minutes old) and task claimed, task auto-releases
147
+
148
+ ### 6. Progress Tracking
98
149
  - Orchestrator monitors via TaskOutput
99
- - Shows live progress: claimed/done/pending counts
100
- - Reports which agent is working on which file
150
+ - Shows live progress: pending/claimed/done/failed counts
151
+ - Active agent count via getActiveAgents()
152
+ - Reports which agent is working on which task via getAgentTasks()
101
153
  - Detects idle agents (all tasks claimed by others)
102
154
 
103
- ### 6. Completion
155
+ ### 7. Completion
104
156
  Exit when ANY of:
105
- - All tasks marked "done"
106
- - All agents idle (no pending tasks)
107
- - User cancels via `/cancel-swarm`
108
-
109
- ## State Files
110
-
111
- ### `.omc/swarm-state.json`
112
- Session-level state:
113
-
114
- ```json
115
- {
116
- "session_id": "swarm-20260123-143022",
117
- "agent_count": 5,
118
- "agent_type": "executor",
119
- "task_description": "fix all TypeScript errors",
120
- "status": "active",
121
- "started_at": "2026-01-23T14:30:22Z",
122
- "agents": [
123
- {"id": "agent-1", "background_task_id": "task_abc123", "status": "working"},
124
- {"id": "agent-2", "background_task_id": "task_def456", "status": "working"},
125
- ...
126
- ]
157
+ - isSwarmComplete() returns true (all tasks done or failed)
158
+ - All agents idle (no pending tasks, no claimed tasks)
159
+ - User cancels via `/oh-my-claudecode:cancel`
160
+
161
+ ## Storage
162
+
163
+ ### SQLite Database (`.omc/state/swarm.db`)
164
+
165
+ The swarm uses a single SQLite database stored at `.omc/state/swarm.db`. This provides:
166
+ - **ACID compliance** - All task state transitions are atomic
167
+ - **Concurrent access** - Multiple agents query/update safely
168
+ - **Persistence** - State survives agent crashes
169
+ - **Query efficiency** - Fast status lookups and filtering
170
+
171
+ #### `tasks` Table Schema
172
+ ```sql
173
+ CREATE TABLE tasks (
174
+ id TEXT PRIMARY KEY,
175
+ description TEXT NOT NULL,
176
+ status TEXT NOT NULL DEFAULT 'pending',
177
+ -- pending: waiting to be claimed
178
+ -- claimed: claimed by an agent, in progress
179
+ -- done: completed successfully
180
+ -- failed: completed with error
181
+ claimed_by TEXT, -- agent ID that claimed this task
182
+ claimed_at INTEGER, -- Unix timestamp when claimed
183
+ completed_at INTEGER, -- Unix timestamp when completed
184
+ result TEXT, -- Optional result/output from task
185
+ error TEXT -- Error message if task failed
186
+ );
187
+ ```
188
+
189
+ #### `heartbeats` Table Schema
190
+ ```sql
191
+ CREATE TABLE heartbeats (
192
+ agent_id TEXT PRIMARY KEY,
193
+ last_heartbeat INTEGER NOT NULL, -- Unix timestamp of last heartbeat
194
+ current_task_id TEXT -- Task agent is currently working on
195
+ );
196
+ ```
197
+
198
+ #### `session` Table Schema
199
+ ```sql
200
+ CREATE TABLE session (
201
+ id TEXT PRIMARY KEY,
202
+ agent_count INTEGER NOT NULL,
203
+ started_at INTEGER NOT NULL,
204
+ completed_at INTEGER,
205
+ active INTEGER DEFAULT 1
206
+ );
207
+ ```
208
+
209
+ ## Task Claiming Protocol (Detailed)
210
+
211
+ ### Atomic Claim Operation with SQLite
212
+
213
+ The core strength of the new implementation is transactional atomicity:
214
+
215
+ ```typescript
216
+ function claimTask(agentId: string): ClaimResult {
217
+ // Transaction ensures only ONE agent succeeds
218
+ const claimTransaction = db.transaction(() => {
219
+ // Step 1: Find first pending task
220
+ const task = db.prepare(
221
+ 'SELECT id, description FROM tasks WHERE status = "pending" ORDER BY id LIMIT 1'
222
+ ).get();
223
+
224
+ if (!task) {
225
+ return { success: false, reason: 'No pending tasks' };
226
+ }
227
+
228
+ // Step 2: Attempt claim (will only succeed if status is still 'pending')
229
+ const result = db.prepare(
230
+ 'UPDATE tasks SET status = "claimed", claimed_by = ?, claimed_at = ? WHERE id = ? AND status = "pending"'
231
+ ).run(agentId, Date.now(), task.id);
232
+
233
+ if (result.changes === 0) {
234
+ // Another agent claimed it between SELECT and UPDATE - try next
235
+ return { success: false, reason: 'Task was claimed by another agent' };
236
+ }
237
+
238
+ // Step 3: Update heartbeat to show we're alive and working
239
+ db.prepare(
240
+ 'INSERT OR REPLACE INTO heartbeats (agent_id, last_heartbeat, current_task_id) VALUES (?, ?, ?)'
241
+ ).run(agentId, Date.now(), task.id);
242
+
243
+ return { success: true, taskId: task.id, description: task.description };
244
+ }).immediate(); // Explicitly acquire RESERVED lock for immediate transaction
245
+
246
+ return claimTransaction(); // Atomic execution
127
247
  }
128
248
  ```
129
249
 
130
- ### `.omc/state/swarm-tasks.json`
131
- Shared task list with atomic claiming:
132
-
133
- ```json
134
- {
135
- "tasks": [
136
- {
137
- "id": "task-001",
138
- "file": "src/utils/validation.ts",
139
- "description": "Fix type errors in validation helpers",
140
- "status": "claimed",
141
- "owner": "agent-1",
142
- "claimed_at": "2026-01-23T14:30:25Z",
143
- "timeout_at": "2026-01-23T14:35:25Z"
144
- },
145
- {
146
- "id": "task-002",
147
- "file": "src/components/Header.tsx",
148
- "description": "Fix missing prop types",
149
- "status": "done",
150
- "owner": "agent-2",
151
- "claimed_at": "2026-01-23T14:30:26Z",
152
- "completed_at": "2026-01-23T14:32:15Z"
153
- },
154
- {
155
- "id": "task-003",
156
- "file": "src/api/client.ts",
157
- "description": "Add return type annotations",
158
- "status": "pending",
159
- "owner": null,
160
- "claimed_at": null,
161
- "timeout_at": null
250
+ **Why SQLite Transactions Work:**
251
+ - Transactions are called with `.immediate()` to acquire RESERVED lock
252
+ - Prevents other agents from modifying rows between SELECT and UPDATE
253
+ - All-or-nothing atomicity: claim succeeds completely or fails completely
254
+ - No race conditions, no lost updates
255
+
256
+ ### Lease Timeout & Auto-Release
257
+
258
+ Tasks are automatically released if claimed too long without heartbeat:
259
+
260
+ ```typescript
261
+ function cleanupStaleClaims(leaseTimeout: number = 5 * 60 * 1000) {
262
+ // Default 5-minute timeout
263
+ const cutoffTime = Date.now() - leaseTimeout;
264
+
265
+ const cleanupTransaction = db.transaction(() => {
266
+ // Find claimed tasks where:
267
+ // 1. Claimed longer than timeout, OR
268
+ // 2. Agent hasn't sent heartbeat in that time
269
+ const staleTasks = db.prepare(`
270
+ SELECT t.id
271
+ FROM tasks t
272
+ LEFT JOIN heartbeats h ON t.claimed_by = h.agent_id
273
+ WHERE t.status = 'claimed'
274
+ AND t.claimed_at < ?
275
+ AND (h.last_heartbeat IS NULL OR h.last_heartbeat < ?)
276
+ `).all(cutoffTime, cutoffTime);
277
+
278
+ // Release each stale task back to pending
279
+ for (const staleTask of staleTasks) {
280
+ db.prepare('UPDATE tasks SET status = "pending", claimed_by = NULL, claimed_at = NULL WHERE id = ?')
281
+ .run(staleTask.id);
162
282
  }
163
- ],
164
- "stats": {
165
- "total": 15,
166
- "pending": 8,
167
- "claimed": 5,
168
- "done": 2
169
- }
283
+
284
+ return staleTasks.length;
285
+ }).immediate(); // Explicitly acquire RESERVED lock for immediate transaction
286
+
287
+ return cleanupTransaction();
170
288
  }
171
289
  ```
172
290
 
173
- ### `.omc/state/swarm-claims.json`
174
- Ownership tracking and timeout enforcement:
291
+ **How Recovery Works:**
292
+ 1. Orchestrator calls cleanupStaleClaims() every 60 seconds
293
+ 2. If agent hasn't sent heartbeat in 5 minutes, task is auto-released
294
+ 3. Another agent picks up the orphaned task
295
+ 4. Original agent can continue working (it doesn't know it was released)
296
+ 5. When original agent tries to mark task as done, verification fails safely
175
297
 
176
- ```json
177
- {
178
- "claims": [
179
- {
180
- "task_id": "task-001",
181
- "agent_id": "agent-1",
182
- "claimed_at": "2026-01-23T14:30:25Z",
183
- "timeout_at": "2026-01-23T14:35:25Z",
184
- "heartbeat_at": "2026-01-23T14:33:10Z"
185
- }
186
- ],
187
- "timeouts": {
188
- "claim_timeout_seconds": 300,
189
- "heartbeat_interval_seconds": 60
298
+ ## API Reference
299
+
300
+ Agents interact with the swarm via a TypeScript API:
301
+
302
+ ### Initialization
303
+
304
+ ```typescript
305
+ import { startSwarm, connectToSwarm } from './swarm';
306
+
307
+ // Orchestrator starts the swarm
308
+ await startSwarm({
309
+ agentCount: 5,
310
+ tasks: ['fix a.ts', 'fix b.ts', ...],
311
+ leaseTimeout: 5 * 60 * 1000, // 5 minutes (default)
312
+ heartbeatInterval: 60 * 1000 // 60 seconds (default)
313
+ });
314
+
315
+ // Agents join existing swarm
316
+ await connectToSwarm(process.cwd());
317
+ ```
318
+
319
+ ### Agent Loop Pattern
320
+
321
+ ```typescript
322
+ import {
323
+ claimTask,
324
+ completeTask,
325
+ failTask,
326
+ heartbeat,
327
+ hasPendingWork,
328
+ disconnectFromSwarm
329
+ } from './swarm';
330
+
331
+ const agentId = 'agent-1';
332
+
333
+ // Main work loop
334
+ while (hasPendingWork()) {
335
+ // Claim next task
336
+ const claim = claimTask(agentId);
337
+
338
+ if (!claim.success) {
339
+ console.log('No tasks available:', claim.reason);
340
+ break;
341
+ }
342
+
343
+ const { taskId, description } = claim;
344
+ console.log(`Agent ${agentId} working on: ${description}`);
345
+
346
+ try {
347
+ // Do the work...
348
+ const result = await executeTask(description);
349
+
350
+ // Mark complete
351
+ completeTask(agentId, taskId, result);
352
+ console.log(`Agent ${agentId} completed task ${taskId}`);
353
+
354
+ } catch (error) {
355
+ // Mark failed
356
+ failTask(agentId, taskId, error.message);
357
+ console.error(`Agent ${agentId} failed on ${taskId}:`, error);
190
358
  }
359
+
360
+ // Send heartbeat every 60 seconds (while working on long tasks)
361
+ heartbeat(agentId);
191
362
  }
363
+
364
+ // Cleanup
365
+ disconnectFromSwarm();
192
366
  ```
193
367
 
194
- ## Task Claiming Protocol (Detailed)
368
+ ### Core API Functions
195
369
 
196
- ### Atomic Claim Operation
370
+ #### `startSwarm(config: SwarmConfig): Promise<boolean>`
371
+ Initialize the swarm with task pool and start cleanup timer.
197
372
 
198
- ```javascript
199
- // Pseudo-code for agent claiming
200
- function claimTask() {
201
- const tasks = readJSON('.omc/state/swarm-tasks.json');
373
+ ```typescript
374
+ const success = await startSwarm({
375
+ agentCount: 5,
376
+ tasks: ['task 1', 'task 2', 'task 3'],
377
+ leaseTimeout: 5 * 60 * 1000,
378
+ heartbeatInterval: 60 * 1000
379
+ });
380
+ ```
202
381
 
203
- for (const task of tasks.tasks) {
204
- if (task.status === 'pending') {
205
- // Attempt atomic claim
206
- const now = new Date().toISOString();
207
- const timeout = addMinutes(now, 5).toISOString();
382
+ #### `stopSwarm(deleteDatabase?: boolean): boolean`
383
+ Stop the swarm and optionally delete the database.
208
384
 
209
- task.status = 'claimed';
210
- task.owner = agentId;
211
- task.claimed_at = now;
212
- task.timeout_at = timeout;
385
+ ```typescript
386
+ stopSwarm(true); // Delete database on cleanup
387
+ ```
213
388
 
214
- writeJSON('.omc/state/swarm-tasks.json', tasks);
215
- return task;
216
- }
217
- }
389
+ #### `claimTask(agentId: string): ClaimResult`
390
+ Claim the next pending task. Returns `{ success, taskId, description, reason }`.
218
391
 
219
- return null; // No pending tasks
392
+ ```typescript
393
+ const claim = claimTask('agent-1');
394
+ if (claim.success) {
395
+ console.log(`Claimed: ${claim.description}`);
220
396
  }
221
397
  ```
222
398
 
223
- ### Timeout Auto-Release
399
+ #### `completeTask(agentId: string, taskId: string, result?: string): boolean`
400
+ Mark a task as done. Only succeeds if agent still owns the task.
224
401
 
225
- Orchestrator periodically checks for timed-out claims:
402
+ ```typescript
403
+ completeTask('agent-1', 'task-1', 'Fixed the bug');
404
+ ```
226
405
 
227
- ```javascript
228
- function releaseTimedOutTasks() {
229
- const tasks = readJSON('.omc/state/swarm-tasks.json');
230
- const now = new Date();
406
+ #### `failTask(agentId: string, taskId: string, error: string): boolean`
407
+ Mark a task as failed with error details.
231
408
 
232
- for (const task of tasks.tasks) {
233
- if (task.status === 'claimed' && new Date(task.timeout_at) < now) {
234
- task.status = 'pending';
235
- task.owner = null;
236
- task.claimed_at = null;
237
- task.timeout_at = null;
238
- // Log timeout event
239
- }
240
- }
409
+ ```typescript
410
+ failTask('agent-1', 'task-1', 'Could not compile: missing dependency');
411
+ ```
412
+
413
+ #### `heartbeat(agentId: string): boolean`
414
+ Send a heartbeat to indicate agent is alive. Call every 60 seconds during long-running tasks.
415
+
416
+ ```typescript
417
+ heartbeat('agent-1');
418
+ ```
419
+
420
+ #### `cleanupStaleClaims(leaseTimeout?: number): number`
421
+ Manually trigger cleanup of expired claims. Called automatically every 60 seconds.
422
+
423
+ ```typescript
424
+ const released = cleanupStaleClaims(5 * 60 * 1000);
425
+ console.log(`Released ${released} stale tasks`);
426
+ ```
241
427
 
242
- writeJSON('.omc/state/swarm-tasks.json', tasks);
428
+ #### `hasPendingWork(): boolean`
429
+ Check if there are unclaimed tasks available.
430
+
431
+ ```typescript
432
+ if (!hasPendingWork()) {
433
+ console.log('All tasks claimed or completed');
243
434
  }
244
435
  ```
245
436
 
246
- ## Agent Instructions Template
437
+ #### `isSwarmComplete(): boolean`
438
+ Check if all tasks are done or failed.
439
+
440
+ ```typescript
441
+ if (isSwarmComplete()) {
442
+ console.log('Swarm finished!');
443
+ }
444
+ ```
247
445
 
248
- Each spawned agent receives these instructions:
446
+ #### `getSwarmStats(): SwarmStats | null`
447
+ Get task counts and timing info.
249
448
 
250
- ```markdown
251
- You are agent {id} in a swarm of {N} {agent-type} agents.
449
+ ```typescript
450
+ const stats = getSwarmStats();
451
+ console.log(`${stats.doneTasks}/${stats.totalTasks} done`);
452
+ ```
252
453
 
253
- **Your Task:** {task_description}
454
+ #### `getActiveAgents(): number`
455
+ Get count of agents with recent heartbeats.
254
456
 
255
- **Shared Task List:** .omc/state/swarm-tasks.json
457
+ ```typescript
458
+ const active = getActiveAgents();
459
+ console.log(`${active} agents currently active`);
460
+ ```
256
461
 
257
- **Your Loop:**
258
- 1. Read swarm-tasks.json
259
- 2. Find first task with status="pending"
260
- 3. Claim it atomically (set status="claimed", owner="{id}", timestamp)
261
- 4. Execute the task
262
- 5. Mark status="done", set completed_at
263
- 6. Repeat until no pending tasks
462
+ #### `getAllTasks(): SwarmTask[]`
463
+ Get all tasks with current status.
264
464
 
265
- **Claiming Protocol:**
266
- - Read file, check status="pending"
267
- - Update status="claimed", add your ID
268
- - Set timeout_at = now + 5 minutes
269
- - Write file back
270
- - If file changed between read/write, retry
465
+ ```typescript
466
+ const tasks = getAllTasks();
467
+ const pending = tasks.filter(t => t.status === 'pending');
468
+ ```
271
469
 
272
- **Completion:**
273
- When no pending tasks remain, exit cleanly.
470
+ #### `getTasksWithStatus(status: string): SwarmTask[]`
471
+ Filter tasks by status: 'pending', 'claimed', 'done', 'failed'.
274
472
 
275
- **Reporting:**
276
- Update your progress in swarm-state.json under agents[{id}].status
473
+ ```typescript
474
+ const failed = getTasksWithStatus('failed');
277
475
  ```
278
476
 
279
- ## Constraints
477
+ #### `getAgentTasks(agentId: string): SwarmTask[]`
478
+ Get all tasks claimed by a specific agent.
280
479
 
281
- - **Max Agents:** 5 (enforced by Claude Code background task limit)
282
- - **Claim Timeout:** 5 minutes per task
283
- - **Heartbeat:** Agents should update heartbeat every 60 seconds
284
- - **Auto-Release:** Timed-out claims automatically released by orchestrator
480
+ ```typescript
481
+ const myTasks = getAgentTasks('agent-1');
482
+ ```
285
483
 
286
- ## Error Handling
484
+ #### `retryTask(agentId: string, taskId: string): ClaimResult`
485
+ Attempt to reclaim a failed task.
486
+
487
+ ```typescript
488
+ const retry = retryTask('agent-1', 'task-1');
489
+ if (retry.success) {
490
+ console.log('Task reclaimed, trying again...');
491
+ }
492
+ ```
287
493
 
288
- - **Agent Crash:** Task auto-releases after timeout
289
- - **State Corruption:** Orchestrator validates and repairs on each cycle
290
- - **No Pending Tasks:** Agent exits cleanly
291
- - **All Agents Idle:** Orchestrator detects and concludes session
494
+ ### Configuration (SwarmConfig)
495
+
496
+ ```typescript
497
+ interface SwarmConfig {
498
+ agentCount: number; // Number of agents (1-5)
499
+ tasks: string[]; // Task descriptions
500
+ agentType?: string; // Agent type (default: 'executor')
501
+ leaseTimeout?: number; // Milliseconds (default: 5 min)
502
+ heartbeatInterval?: number; // Milliseconds (default: 60 sec)
503
+ cwd?: string; // Working directory
504
+ }
505
+ ```
506
+
507
+ ### Types
508
+
509
+ ```typescript
510
+ interface SwarmTask {
511
+ id: string;
512
+ description: string;
513
+ status: 'pending' | 'claimed' | 'done' | 'failed';
514
+ claimedBy: string | null;
515
+ claimedAt: number | null;
516
+ completedAt: number | null;
517
+ error?: string;
518
+ result?: string;
519
+ }
520
+
521
+ interface ClaimResult {
522
+ success: boolean;
523
+ taskId: string | null;
524
+ description?: string;
525
+ reason?: string;
526
+ }
527
+
528
+ interface SwarmStats {
529
+ totalTasks: number;
530
+ pendingTasks: number;
531
+ claimedTasks: number;
532
+ doneTasks: number;
533
+ failedTasks: number;
534
+ activeAgents: number;
535
+ elapsedTime: number;
536
+ }
537
+ ```
538
+
539
+ ## Key Parameters
540
+
541
+ - **Max Agents:** 5 (enforced by Claude Code background task limit)
542
+ - **Lease Timeout:** 5 minutes (default, configurable)
543
+ - Tasks claimed longer than this without heartbeat are auto-released
544
+ - **Heartbeat Interval:** 60 seconds (recommended)
545
+ - Agents should call `heartbeat()` at least this often
546
+ - Prevents false timeout while working on long tasks
547
+ - **Cleanup Interval:** 60 seconds
548
+ - Orchestrator automatically runs `cleanupStaleClaims()` to release orphaned tasks
549
+ - **Database:** SQLite (stored at `.omc/state/swarm.db`)
550
+ - One database per swarm session
551
+ - Survives agent crashes
552
+ - Provides ACID guarantees
553
+
554
+ ## Error Handling & Recovery
555
+
556
+ ### Agent Crash
557
+ - Task is claimed but agent stops sending heartbeats
558
+ - After 5 minutes of no heartbeat, cleanupStaleClaims() releases the task
559
+ - Task returns to 'pending' status for another agent to claim
560
+ - Original agent's incomplete work is safely abandoned
561
+
562
+ ### Task Completion Failure
563
+ - Agent calls `completeTask()` but is no longer the owner (was released)
564
+ - The update silently fails (no agent matches in WHERE clause)
565
+ - Agent can detect this by checking return value
566
+ - Agent should log error and continue to next task
567
+
568
+ ### Database Unavailable
569
+ - `startSwarm()` returns false if database initialization fails
570
+ - `claimTask()` returns `{ success: false, reason: 'Database not initialized' }`
571
+ - Check `isSwarmReady()` before proceeding
572
+
573
+ ### All Agents Idle
574
+ - Orchestrator detects via `getActiveAgents() === 0` or `hasPendingWork() === false`
575
+ - Triggers final cleanup and marks swarm as complete
576
+ - Remaining failed tasks are preserved in database
577
+
578
+ ### No Tasks Available
579
+ - `claimTask()` returns success=false with reason 'No pending tasks available'
580
+ - Agent should check `hasPendingWork()` before looping
581
+ - Safe for agent to exit cleanly when no work remains
292
582
 
293
583
  ## Cancel Swarm
294
584
 
295
- User can cancel via `/cancel-swarm`:
585
+ User can cancel via `/oh-my-claudecode:cancel`:
296
586
  - Stops orchestrator monitoring
297
587
  - Signals all background agents to exit
298
- - Preserves partial progress in swarm-tasks.json
299
- - Marks session as "cancelled" in swarm-state.json
588
+ - Preserves partial progress in SQLite database
589
+ - Marks session as "cancelled" in database
300
590
 
301
591
  ## Use Cases
302
592
 
@@ -324,26 +614,60 @@ Spawns 4 security reviewers, each auditing different endpoints.
324
614
  ```
325
615
  Spawns 2 writers, each documenting different modules.
326
616
 
327
- ## Benefits
617
+ ## Benefits of SQLite-Based Implementation
618
+
619
+ ### Atomicity & Safety
620
+ - **Race-Condition Free:** SQLite transactions guarantee only one agent claims each task
621
+ - **No Lost Updates:** ACID compliance means state changes are durable
622
+ - **Orphan Prevention:** Expired claims are automatically released without manual intervention
623
+
624
+ ### Performance
625
+ - **Fast Queries:** Indexed lookups on task status and agent ID
626
+ - **Concurrent Access:** Multiple agents read/write without blocking
627
+ - **Minimal Lock Time:** Transactions are microseconds, not seconds
628
+
629
+ ### Reliability
630
+ - **Crash Recovery:** Database survives agent failures
631
+ - **Automatic Cleanup:** Stale claims don't block progress
632
+ - **Lease-Based:** Time-based expiration prevents indefinite hangs
633
+
634
+ ### Developer Experience
635
+ - **Simple API:** Just `claimTask()`, `completeTask()`, `heartbeat()`
636
+ - **Full Visibility:** Query any task or agent status at any time
637
+ - **Easy Debugging:** SQL queries show exact state without decoding JSON
638
+
639
+ ### Scalability
640
+ - **10s to 1000s of Tasks:** SQLite handles easily
641
+ - **Full Task Retention:** Complete history in database for analysis
642
+ - **Extensible Schema:** Add custom columns for task metadata
328
643
 
329
- - **Parallel Execution:** N agents work simultaneously
330
- - **Auto-Balancing:** Fast agents claim more tasks
331
- - **Fault Tolerance:** Timeouts and auto-release prevent deadlocks
332
- - **Progress Visibility:** Live stats on claimed/done/pending
333
- - **Scalable:** Works for 10s to 100s of subtasks
644
+ ## STATE CLEANUP ON COMPLETION
645
+
646
+ **IMPORTANT: Delete state files on completion - do NOT just set `active: false`**
647
+
648
+ When all tasks are done:
649
+
650
+ ```bash
651
+ # Delete swarm state files
652
+ rm -f .omc/state/swarm-state.json
653
+ rm -f .omc/state/swarm-tasks.json
654
+ rm -f .omc/state/swarm-claims.json
655
+ ```
334
656
 
335
657
  ## Implementation Notes
336
658
 
337
659
  The orchestrator (main skill handler) is responsible for:
338
660
  1. Initial task decomposition (via explore/architect)
339
- 2. Creating state files
661
+ 2. Creating and initializing SQLite database via `startSwarm()`
340
662
  3. Spawning N background agents
341
- 4. Monitoring progress via TaskOutput
342
- 5. Enforcing timeouts and auto-release
343
- 6. Detecting completion conditions
344
- 7. Reporting final summary
663
+ 4. Monitoring progress via `getSwarmStats()` and `getActiveAgents()`
664
+ 5. Running `cleanupStaleClaims()` automatically (via setInterval)
665
+ 6. Detecting completion via `isSwarmComplete()`
666
+ 7. Reporting final summary from database query
345
667
 
346
668
  Each agent is a standard Task invocation with:
347
669
  - `run_in_background: true`
348
- - Agent-specific prompt with claiming instructions
349
- - Reference to shared state files
670
+ - Agent-specific prompt with work loop instructions
671
+ - API import: `import { claimTask, completeTask, ... } from './swarm'`
672
+ - Connection: `await connectToSwarm(cwd)` to join existing swarm
673
+ - Loop: repeatedly call `claimTask()` → do work → `completeTask()` or `failTask()`