@desplega.ai/agent-swarm 1.20.0 → 1.51.2

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 (561) hide show
  1. package/README.md +271 -169
  2. package/openapi.json +5015 -0
  3. package/package.json +40 -7
  4. package/plugin/commands/close-issue.md +7 -3
  5. package/plugin/commands/create-pr.md +18 -12
  6. package/plugin/commands/implement-issue.md +7 -3
  7. package/plugin/commands/respond-github.md +8 -4
  8. package/plugin/commands/review-pr.md +44 -10
  9. package/plugin/commands/start-leader.md +1 -3
  10. package/plugin/commands/start-worker.md +1 -3
  11. package/plugin/commands/work-on-task.md +22 -3
  12. package/plugin/pi-skills/close-issue/SKILL.md +90 -0
  13. package/plugin/pi-skills/create-pr/SKILL.md +99 -0
  14. package/plugin/pi-skills/implement-issue/SKILL.md +135 -0
  15. package/plugin/pi-skills/investigate-sentry-issue/SKILL.md +138 -0
  16. package/plugin/pi-skills/respond-github/SKILL.md +98 -0
  17. package/plugin/pi-skills/review-offered-task/SKILL.md +45 -0
  18. package/plugin/pi-skills/review-pr/SKILL.md +261 -0
  19. package/plugin/pi-skills/start-leader/SKILL.md +121 -0
  20. package/plugin/pi-skills/start-worker/SKILL.md +60 -0
  21. package/plugin/pi-skills/swarm-chat/SKILL.md +82 -0
  22. package/plugin/pi-skills/todos/SKILL.md +66 -0
  23. package/plugin/pi-skills/work-on-task/SKILL.md +65 -0
  24. package/plugin/skills/artifacts/examples/approval-flow.ts +34 -0
  25. package/plugin/skills/artifacts/examples/hono-dashboard.ts +31 -0
  26. package/plugin/skills/artifacts/examples/multi-artifact.ts +20 -0
  27. package/plugin/skills/artifacts/examples/static-report.sh +17 -0
  28. package/plugin/skills/artifacts/skill.md +71 -0
  29. package/src/agentmail/app.ts +65 -0
  30. package/src/agentmail/handlers.ts +262 -0
  31. package/src/agentmail/index.ts +9 -0
  32. package/src/agentmail/templates.ts +111 -0
  33. package/src/agentmail/types.ts +51 -0
  34. package/src/artifact-sdk/browser-sdk.ts +30 -0
  35. package/src/artifact-sdk/index.ts +2 -0
  36. package/src/artifact-sdk/localtunnel.d.ts +20 -0
  37. package/src/artifact-sdk/port.ts +12 -0
  38. package/src/artifact-sdk/server.ts +156 -0
  39. package/src/artifact-sdk/tunnel.ts +19 -0
  40. package/src/be/chunking.ts +193 -0
  41. package/src/be/db-queries/oauth.ts +90 -0
  42. package/src/be/db-queries/tracker.ts +182 -0
  43. package/src/be/db.ts +3327 -784
  44. package/src/be/embedding.ts +80 -0
  45. package/src/be/migrations/001_initial.sql +409 -0
  46. package/src/be/migrations/002_one_time_schedules.sql +59 -0
  47. package/src/be/migrations/003_workflows.sql +51 -0
  48. package/src/be/migrations/004_workflow_source.sql +81 -0
  49. package/src/be/migrations/005_epic_next_steps.sql +2 -0
  50. package/src/be/migrations/006_vcs_provider.sql +94 -0
  51. package/src/be/migrations/007_task_dir.sql +2 -0
  52. package/src/be/migrations/008_workflow_redesign.sql +85 -0
  53. package/src/be/migrations/009_tracker_integration.sql +144 -0
  54. package/src/be/migrations/010_step_diagnostics.sql +1 -0
  55. package/src/be/migrations/011_step_next_port.sql +1 -0
  56. package/src/be/migrations/012_trigger_schema.sql +1 -0
  57. package/src/be/migrations/013_task_output_schema.sql +2 -0
  58. package/src/be/migrations/014_prompt_templates.sql +33 -0
  59. package/src/be/migrations/015_workflow_workspace.sql +3 -0
  60. package/src/be/migrations/016_active_session_runner_session.sql +4 -0
  61. package/src/be/migrations/017_channel_activity_cursors.sql +6 -0
  62. package/src/be/migrations/018_fix_seed_double_version.sql +30 -0
  63. package/src/be/migrations/runner.ts +188 -0
  64. package/src/be/seed.ts +62 -0
  65. package/src/cli.tsx +231 -299
  66. package/src/commands/artifact.ts +241 -0
  67. package/src/commands/onboard/compose-generator.ts +169 -0
  68. package/src/commands/onboard/env-generator.ts +79 -0
  69. package/src/commands/onboard/manifest.ts +37 -0
  70. package/src/commands/onboard/presets.ts +85 -0
  71. package/src/commands/onboard/service-names.ts +47 -0
  72. package/src/commands/onboard/steps/core-credentials.tsx +111 -0
  73. package/src/commands/onboard/steps/custom-templates.tsx +168 -0
  74. package/src/commands/onboard/steps/generate.tsx +154 -0
  75. package/src/commands/onboard/steps/harness-credentials.tsx +195 -0
  76. package/src/commands/onboard/steps/harness.tsx +21 -0
  77. package/src/commands/onboard/steps/health-check.tsx +171 -0
  78. package/src/commands/onboard/steps/integration-github.tsx +105 -0
  79. package/src/commands/onboard/steps/integration-gitlab.tsx +79 -0
  80. package/src/commands/onboard/steps/integration-menu.tsx +58 -0
  81. package/src/commands/onboard/steps/integration-sentry.tsx +79 -0
  82. package/src/commands/onboard/steps/integration-slack.tsx +165 -0
  83. package/src/commands/onboard/steps/post-connect.tsx +145 -0
  84. package/src/commands/onboard/steps/post-dashboard.tsx +34 -0
  85. package/src/commands/onboard/steps/post-task.tsx +103 -0
  86. package/src/commands/onboard/steps/prereq-check.tsx +178 -0
  87. package/src/commands/onboard/steps/review.tsx +82 -0
  88. package/src/commands/onboard/steps/start.tsx +97 -0
  89. package/src/commands/onboard/templates.ts +34 -0
  90. package/src/commands/onboard/types.ts +259 -0
  91. package/src/commands/onboard.tsx +425 -0
  92. package/src/commands/runner.ts +1540 -630
  93. package/src/commands/setup.tsx +23 -38
  94. package/src/commands/shared/client-config.ts +41 -0
  95. package/src/commands/templates.ts +172 -0
  96. package/src/github/app.ts +8 -0
  97. package/src/github/handlers.ts +384 -151
  98. package/src/github/index.ts +1 -0
  99. package/src/github/mentions-aliases.test.ts +73 -0
  100. package/src/github/mentions.test.ts +3 -3
  101. package/src/github/mentions.ts +32 -6
  102. package/src/github/templates.ts +398 -0
  103. package/src/github/types.ts +1 -0
  104. package/src/gitlab/auth.ts +63 -0
  105. package/src/gitlab/handlers.ts +368 -0
  106. package/src/gitlab/index.ts +19 -0
  107. package/src/gitlab/reactions.ts +104 -0
  108. package/src/gitlab/templates.ts +140 -0
  109. package/src/gitlab/types.ts +130 -0
  110. package/src/heartbeat/heartbeat.ts +434 -0
  111. package/src/heartbeat/index.ts +1 -0
  112. package/src/heartbeat/templates.ts +30 -0
  113. package/src/hooks/hook.ts +555 -4
  114. package/src/hooks/tool-loop-detection.test.ts +158 -0
  115. package/src/hooks/tool-loop-detection.ts +167 -0
  116. package/src/http/active-sessions.ts +199 -0
  117. package/src/http/agents.ts +328 -0
  118. package/src/http/config.ts +191 -0
  119. package/src/http/core.ts +309 -0
  120. package/src/http/db-query.ts +91 -0
  121. package/src/http/ecosystem.ts +63 -0
  122. package/src/http/epics.ts +460 -0
  123. package/src/http/index.ts +216 -0
  124. package/src/http/mcp.ts +77 -0
  125. package/src/http/memory.ts +168 -0
  126. package/src/http/openapi.ts +109 -0
  127. package/src/http/poll.ts +299 -0
  128. package/src/http/prompt-templates.ts +412 -0
  129. package/src/http/repos.ts +195 -0
  130. package/src/http/route-def.ts +123 -0
  131. package/src/http/schedules.ts +426 -0
  132. package/src/http/session-data.ts +241 -0
  133. package/src/http/stats.ts +174 -0
  134. package/src/http/tasks.ts +468 -0
  135. package/src/http/trackers/index.ts +10 -0
  136. package/src/http/trackers/linear.ts +187 -0
  137. package/src/http/types.ts +12 -0
  138. package/src/http/utils.ts +87 -0
  139. package/src/http/webhooks.ts +432 -0
  140. package/src/http/workflows.ts +530 -0
  141. package/src/http.ts +1 -1890
  142. package/src/linear/README.md +65 -0
  143. package/src/linear/app.ts +48 -0
  144. package/src/linear/client.ts +18 -0
  145. package/src/linear/index.ts +1 -0
  146. package/src/linear/oauth.ts +35 -0
  147. package/src/linear/outbound.ts +212 -0
  148. package/src/linear/sync.ts +567 -0
  149. package/src/linear/templates.ts +47 -0
  150. package/src/linear/types.ts +7 -0
  151. package/src/linear/webhook.ts +104 -0
  152. package/src/oauth/README.md +66 -0
  153. package/src/oauth/index.ts +6 -0
  154. package/src/oauth/wrapper.ts +204 -0
  155. package/src/prompts/base-prompt.ts +150 -265
  156. package/src/prompts/defaults.ts +196 -0
  157. package/src/prompts/registry.ts +57 -0
  158. package/src/prompts/resolver.ts +296 -0
  159. package/src/prompts/session-templates.ts +604 -0
  160. package/src/providers/claude-adapter.ts +442 -0
  161. package/src/providers/index.ts +24 -0
  162. package/src/providers/pi-mono-adapter.ts +442 -0
  163. package/src/providers/pi-mono-extension.ts +624 -0
  164. package/src/providers/pi-mono-mcp-client.ts +124 -0
  165. package/src/providers/types.ts +75 -0
  166. package/src/scheduler/scheduler.test.ts +2 -0
  167. package/src/scheduler/scheduler.ts +231 -40
  168. package/src/server.ts +97 -6
  169. package/src/slack/HEURISTICS.md +105 -0
  170. package/src/slack/actions.ts +133 -0
  171. package/src/slack/app.ts +7 -0
  172. package/src/slack/assistant.ts +118 -0
  173. package/src/slack/blocks.ts +233 -0
  174. package/src/slack/channel-activity.ts +177 -0
  175. package/src/slack/commands.ts +31 -17
  176. package/src/slack/files.ts +1 -1
  177. package/src/slack/handlers.test.ts +114 -1
  178. package/src/slack/handlers.ts +230 -55
  179. package/src/slack/responses.ts +120 -67
  180. package/src/slack/router.ts +17 -99
  181. package/src/slack/templates.ts +55 -0
  182. package/src/slack/thread-buffer.ts +213 -0
  183. package/src/slack/watcher.ts +119 -4
  184. package/src/tests/agent-activity.test.ts +247 -0
  185. package/src/tests/agentmail-filters.test.ts +97 -0
  186. package/src/tests/artifact-sdk.test.ts +800 -0
  187. package/src/tests/base-prompt.test.ts +264 -0
  188. package/src/tests/build-pi-skills.test.ts +127 -0
  189. package/src/tests/channel-activity.test.ts +363 -0
  190. package/src/tests/claude-adapter.test.ts +126 -0
  191. package/src/tests/context-versioning.test.ts +425 -0
  192. package/src/tests/db-queries-oauth.test.ts +197 -0
  193. package/src/tests/db-queries-tracker.test.ts +230 -0
  194. package/src/tests/epics.test.ts +3 -3
  195. package/src/tests/error-tracker.test.ts +368 -0
  196. package/src/tests/fetch-resolved-env.test.ts +167 -0
  197. package/src/tests/generate-default-claude-md.test.ts +9 -1
  198. package/src/tests/generate-identity-templates.test.ts +124 -0
  199. package/src/tests/gitlab-auth.test.ts +109 -0
  200. package/src/tests/gitlab-handlers.test.ts +691 -0
  201. package/src/tests/gitlab-vcs-db.test.ts +177 -0
  202. package/src/tests/heartbeat.test.ts +364 -0
  203. package/src/tests/http-api-integration.test.ts +1698 -0
  204. package/src/tests/linear-outbound-sync.test.ts +200 -0
  205. package/src/tests/linear-webhook.test.ts +406 -0
  206. package/src/tests/match-route.test.ts +187 -0
  207. package/src/tests/memory.test.ts +737 -0
  208. package/src/tests/migration-runner-regressions.test.ts +86 -0
  209. package/src/tests/model-control.test.ts +338 -0
  210. package/src/tests/oauth-wrapper.test.ts +147 -0
  211. package/src/tests/onboard-compose.test.ts +138 -0
  212. package/src/tests/onboard-env.test.ts +174 -0
  213. package/src/tests/onboard-manifest.test.ts +137 -0
  214. package/src/tests/pi-mono-adapter.test.ts +234 -0
  215. package/src/tests/pool-session-logs.test.ts +199 -0
  216. package/src/tests/progress-dedup.test.ts +98 -0
  217. package/src/tests/prompt-template-github.test.ts +682 -0
  218. package/src/tests/prompt-template-remaining.test.ts +504 -0
  219. package/src/tests/prompt-template-resolver.test.ts +621 -0
  220. package/src/tests/prompt-template-session.test.ts +363 -0
  221. package/src/tests/prompt-templates-db.test.ts +616 -0
  222. package/src/tests/provider-adapter.test.ts +122 -0
  223. package/src/tests/provider-command-format.test.ts +98 -0
  224. package/src/tests/reload-config.test.ts +170 -0
  225. package/src/tests/runner-polling-api.test.ts +25 -20
  226. package/src/tests/scheduled-tasks.test.ts +104 -0
  227. package/src/tests/scheduler-backoff.test.ts +166 -0
  228. package/src/tests/self-improvement.test.ts +541 -0
  229. package/src/tests/session-attach.test.ts +536 -0
  230. package/src/tests/session-costs.test.ts +267 -1
  231. package/src/tests/slack-actions.test.ts +133 -0
  232. package/src/tests/slack-assistant.test.ts +136 -0
  233. package/src/tests/slack-blocks.test.ts +246 -0
  234. package/src/tests/slack-metadata-inheritance.test.ts +243 -0
  235. package/src/tests/slack-queue-offline.test.ts +174 -0
  236. package/src/tests/slack-router.test.ts +181 -0
  237. package/src/tests/slack-thread-buffer.test.ts +305 -0
  238. package/src/tests/slack-thread-followups.test.ts +298 -0
  239. package/src/tests/slack-watcher.test.ts +101 -0
  240. package/src/tests/structured-output.test.ts +307 -0
  241. package/src/tests/swarm-repos.test.ts +198 -0
  242. package/src/tests/task-cancellation.test.ts +6 -4
  243. package/src/tests/task-working-dir.test.ts +176 -0
  244. package/src/tests/template-fetch.test.ts +490 -0
  245. package/src/tests/tool-annotations.test.ts +371 -0
  246. package/src/tests/tracker-tools.test.ts +184 -0
  247. package/src/tests/update-profile-agentid.test.ts +248 -0
  248. package/src/tests/update-profile-api.test.ts +143 -3
  249. package/src/tests/update-profile-auth.test.ts +195 -0
  250. package/src/tests/validation-adapters.test.ts +86 -0
  251. package/src/tests/vcs-provider.test.ts +27 -0
  252. package/src/tests/workflow-agent-task.test.ts +196 -0
  253. package/src/tests/workflow-async-v2.test.ts +508 -0
  254. package/src/tests/workflow-convergence.test.ts +541 -0
  255. package/src/tests/workflow-definition-validation.test.ts +366 -0
  256. package/src/tests/workflow-engine-v2.test.ts +691 -0
  257. package/src/tests/workflow-executors.test.ts +736 -0
  258. package/src/tests/workflow-http-v2.test.ts +599 -0
  259. package/src/tests/workflow-integration-io.test.ts +902 -0
  260. package/src/tests/workflow-io-schemas.test.ts +624 -0
  261. package/src/tests/workflow-registry.test.ts +592 -0
  262. package/src/tests/workflow-retry-v2.test.ts +401 -0
  263. package/src/tests/workflow-retry-validation.test.ts +282 -0
  264. package/src/tests/workflow-schedule-trigger.test.ts +104 -0
  265. package/src/tests/workflow-template.test.ts +288 -0
  266. package/src/tests/workflow-trigger-schema.test.ts +359 -0
  267. package/src/tests/workflow-triggers-v2.test.ts +264 -0
  268. package/src/tests/workflow-versions.test.ts +208 -0
  269. package/src/tests/workflow-workspace.test.ts +272 -0
  270. package/src/tests/x402-client.test.ts +117 -0
  271. package/src/tests/x402-config.test.ts +182 -0
  272. package/src/tests/x402-spending-tracker.test.ts +185 -0
  273. package/src/tools/cancel-task.ts +2 -0
  274. package/src/tools/context-diff.ts +171 -0
  275. package/src/tools/context-history.ts +138 -0
  276. package/src/tools/create-channel.ts +1 -0
  277. package/src/tools/db-query.ts +78 -0
  278. package/src/tools/delete-channel.ts +132 -0
  279. package/src/tools/epics/assign-task-to-epic.ts +1 -0
  280. package/src/tools/epics/create-epic.ts +3 -2
  281. package/src/tools/epics/delete-epic.ts +2 -0
  282. package/src/tools/epics/get-epic-details.ts +2 -0
  283. package/src/tools/epics/list-epics.ts +2 -0
  284. package/src/tools/epics/unassign-task-from-epic.ts +1 -0
  285. package/src/tools/epics/update-epic.ts +7 -4
  286. package/src/tools/get-swarm.ts +2 -0
  287. package/src/tools/get-task-details.ts +2 -0
  288. package/src/tools/get-tasks.ts +27 -1
  289. package/src/tools/inject-learning.ts +106 -0
  290. package/src/tools/join-swarm.ts +17 -7
  291. package/src/tools/list-channels.ts +2 -0
  292. package/src/tools/list-services.ts +2 -0
  293. package/src/tools/memory-get.ts +56 -0
  294. package/src/tools/memory-search.ts +131 -0
  295. package/src/tools/my-agent-info.ts +2 -0
  296. package/src/tools/poll-task.ts +2 -20
  297. package/src/tools/post-message.ts +1 -0
  298. package/src/tools/prompt-templates/delete.ts +86 -0
  299. package/src/tools/prompt-templates/get.ts +89 -0
  300. package/src/tools/prompt-templates/index.ts +5 -0
  301. package/src/tools/prompt-templates/list.ts +95 -0
  302. package/src/tools/prompt-templates/preview.ts +84 -0
  303. package/src/tools/prompt-templates/set.ts +117 -0
  304. package/src/tools/read-messages.ts +2 -0
  305. package/src/tools/register-agentmail-inbox.ts +166 -0
  306. package/src/tools/register-service.ts +2 -0
  307. package/src/tools/schedules/create-schedule.ts +134 -24
  308. package/src/tools/schedules/delete-schedule.ts +2 -0
  309. package/src/tools/schedules/list-schedules.ts +20 -4
  310. package/src/tools/schedules/run-schedule-now.ts +1 -0
  311. package/src/tools/schedules/update-schedule.ts +49 -17
  312. package/src/tools/send-task.ts +132 -10
  313. package/src/tools/slack-download-file.ts +4 -2
  314. package/src/tools/slack-list-channels.ts +2 -0
  315. package/src/tools/slack-post.ts +2 -0
  316. package/src/tools/slack-read.ts +2 -0
  317. package/src/tools/slack-reply.ts +2 -0
  318. package/src/tools/slack-upload-file.ts +2 -0
  319. package/src/tools/store-progress.ts +205 -4
  320. package/src/tools/swarm-config/delete-config.ts +87 -0
  321. package/src/tools/swarm-config/get-config.ts +108 -0
  322. package/src/tools/swarm-config/index.ts +4 -0
  323. package/src/tools/swarm-config/list-config.ts +99 -0
  324. package/src/tools/swarm-config/set-config.ts +118 -0
  325. package/src/tools/task-action.ts +50 -5
  326. package/src/tools/task-dedup.ts +97 -0
  327. package/src/tools/templates.ts +53 -0
  328. package/src/tools/tool-config.ts +124 -0
  329. package/src/tools/tracker/index.ts +6 -0
  330. package/src/tools/tracker/tracker-link-epic.ts +64 -0
  331. package/src/tools/tracker/tracker-link-task.ts +64 -0
  332. package/src/tools/tracker/tracker-map-agent.ts +57 -0
  333. package/src/tools/tracker/tracker-status.ts +56 -0
  334. package/src/tools/tracker/tracker-sync-status.ts +42 -0
  335. package/src/tools/tracker/tracker-unlink.ts +41 -0
  336. package/src/tools/unregister-service.ts +2 -0
  337. package/src/tools/update-profile.ts +172 -17
  338. package/src/tools/update-service-status.ts +2 -0
  339. package/src/tools/utils.ts +10 -1
  340. package/src/tools/workflows/create-workflow.ts +129 -0
  341. package/src/tools/workflows/delete-workflow.ts +42 -0
  342. package/src/tools/workflows/get-workflow-run.ts +59 -0
  343. package/src/tools/workflows/get-workflow.ts +53 -0
  344. package/src/tools/workflows/index.ts +9 -0
  345. package/src/tools/workflows/list-workflow-runs.ts +48 -0
  346. package/src/tools/workflows/list-workflows.ts +42 -0
  347. package/src/tools/workflows/retry-workflow-run.ts +40 -0
  348. package/src/tools/workflows/trigger-workflow.ts +96 -0
  349. package/src/tools/workflows/update-workflow.ts +133 -0
  350. package/src/tracker/types.ts +51 -0
  351. package/src/types.ts +530 -14
  352. package/src/utils/credentials.test.ts +156 -0
  353. package/src/utils/credentials.ts +50 -0
  354. package/src/utils/error-tracker.ts +190 -0
  355. package/src/vcs/index.ts +15 -0
  356. package/src/vcs/types.ts +5 -0
  357. package/src/workflows/checkpoint.ts +121 -0
  358. package/src/workflows/cooldown.ts +28 -0
  359. package/src/workflows/definition.ts +235 -0
  360. package/src/workflows/engine.ts +580 -0
  361. package/src/workflows/event-bus.ts +29 -0
  362. package/src/workflows/executors/agent-task.ts +103 -0
  363. package/src/workflows/executors/base.ts +86 -0
  364. package/src/workflows/executors/code-match.ts +88 -0
  365. package/src/workflows/executors/index.ts +16 -0
  366. package/src/workflows/executors/notify.ts +93 -0
  367. package/src/workflows/executors/property-match.ts +104 -0
  368. package/src/workflows/executors/raw-llm.ts +83 -0
  369. package/src/workflows/executors/registry.ts +76 -0
  370. package/src/workflows/executors/script.ts +103 -0
  371. package/src/workflows/executors/validate.ts +215 -0
  372. package/src/workflows/executors/vcs.ts +58 -0
  373. package/src/workflows/index.ts +61 -0
  374. package/src/workflows/input.ts +46 -0
  375. package/src/workflows/json-schema-validator.ts +118 -0
  376. package/src/workflows/recovery.ts +139 -0
  377. package/src/workflows/resume.ts +229 -0
  378. package/src/workflows/retry-poller.ts +216 -0
  379. package/src/workflows/template.ts +74 -0
  380. package/src/workflows/templates.ts +86 -0
  381. package/src/workflows/triggers.ts +124 -0
  382. package/src/workflows/validation.ts +104 -0
  383. package/src/workflows/version.ts +44 -0
  384. package/src/x402/cli.ts +140 -0
  385. package/src/x402/client.ts +192 -0
  386. package/src/x402/config.ts +131 -0
  387. package/src/x402/index.ts +37 -0
  388. package/src/x402/openfort-signer.ts +83 -0
  389. package/src/x402/spending-tracker.ts +109 -0
  390. package/templates/official/coder/CLAUDE.md +49 -0
  391. package/templates/official/coder/IDENTITY.md +28 -0
  392. package/templates/official/coder/SOUL.md +43 -0
  393. package/templates/official/coder/TOOLS.md +40 -0
  394. package/templates/official/coder/config.json +23 -0
  395. package/templates/official/coder/start-up.sh +23 -0
  396. package/templates/official/content-reviewer/CLAUDE.md +68 -0
  397. package/templates/official/content-reviewer/IDENTITY.md +28 -0
  398. package/templates/official/content-reviewer/SOUL.md +44 -0
  399. package/templates/official/content-reviewer/TOOLS.md +37 -0
  400. package/templates/official/content-reviewer/config.json +23 -0
  401. package/templates/official/content-reviewer/start-up.sh +23 -0
  402. package/templates/official/content-strategist/CLAUDE.md +63 -0
  403. package/templates/official/content-strategist/IDENTITY.md +33 -0
  404. package/templates/official/content-strategist/SOUL.md +48 -0
  405. package/templates/official/content-strategist/TOOLS.md +47 -0
  406. package/templates/official/content-strategist/config.json +23 -0
  407. package/templates/official/content-strategist/start-up.sh +23 -0
  408. package/templates/official/content-writer/CLAUDE.md +72 -0
  409. package/templates/official/content-writer/IDENTITY.md +30 -0
  410. package/templates/official/content-writer/SOUL.md +46 -0
  411. package/templates/official/content-writer/TOOLS.md +44 -0
  412. package/templates/official/content-writer/config.json +23 -0
  413. package/templates/official/content-writer/start-up.sh +23 -0
  414. package/templates/official/forward-deployed-engineer/CLAUDE.md +54 -0
  415. package/templates/official/forward-deployed-engineer/IDENTITY.md +37 -0
  416. package/templates/official/forward-deployed-engineer/SOUL.md +55 -0
  417. package/templates/official/forward-deployed-engineer/config.json +21 -0
  418. package/templates/official/lead/CLAUDE.md +33 -0
  419. package/templates/official/lead/IDENTITY.md +36 -0
  420. package/templates/official/lead/SOUL.md +51 -0
  421. package/templates/official/lead/config.json +22 -0
  422. package/templates/official/researcher/CLAUDE.md +46 -0
  423. package/templates/official/researcher/IDENTITY.md +28 -0
  424. package/templates/official/researcher/SOUL.md +43 -0
  425. package/templates/official/researcher/config.json +21 -0
  426. package/templates/official/reviewer/CLAUDE.md +63 -0
  427. package/templates/official/reviewer/IDENTITY.md +28 -0
  428. package/templates/official/reviewer/SOUL.md +45 -0
  429. package/templates/official/reviewer/config.json +21 -0
  430. package/templates/official/tester/CLAUDE.md +53 -0
  431. package/templates/official/tester/IDENTITY.md +28 -0
  432. package/templates/official/tester/SOUL.md +55 -0
  433. package/templates/official/tester/config.json +21 -0
  434. package/templates/schema.ts +35 -0
  435. package/.claude/settings.local.json +0 -115
  436. package/.dockerignore +0 -61
  437. package/.editorconfig +0 -15
  438. package/.env.docker.example +0 -39
  439. package/.env.example +0 -40
  440. package/.github/workflows/ci.yml +0 -76
  441. package/.github/workflows/docker-and-deploy.yml +0 -117
  442. package/.wts-config.json +0 -4
  443. package/.wts-setup.ts +0 -102
  444. package/CLAUDE.md +0 -104
  445. package/CONTRIBUTING.md +0 -270
  446. package/DEPLOYMENT.md +0 -605
  447. package/Dockerfile +0 -57
  448. package/Dockerfile.worker +0 -157
  449. package/FAQ.md +0 -19
  450. package/MCP.md +0 -406
  451. package/UI.md +0 -40
  452. package/assets/agent-swarm-logo-orange.png +0 -0
  453. package/assets/agent-swarm-logo.png +0 -0
  454. package/assets/agent-swarm.mp4 +0 -0
  455. package/assets/agent-swarm.png +0 -0
  456. package/biome.json +0 -39
  457. package/deploy/DEPLOY.md +0 -60
  458. package/deploy/agent-swarm.service +0 -17
  459. package/deploy/docker-push.ts +0 -30
  460. package/deploy/install.ts +0 -85
  461. package/deploy/prod-db.ts +0 -42
  462. package/deploy/uninstall.ts +0 -12
  463. package/deploy/update.ts +0 -21
  464. package/docker-compose.example.yml +0 -159
  465. package/docker-entrypoint.sh +0 -352
  466. package/ecosystem.config.cjs +0 -66
  467. package/plugin/README.md +0 -1
  468. package/plugin/hooks/hooks.json +0 -71
  469. package/pyproject.toml +0 -9
  470. package/scripts/generate-mcp-docs.ts +0 -415
  471. package/slack-manifest.json +0 -71
  472. package/src/tests/get-inbox-message.test.ts +0 -145
  473. package/src/tools/get-inbox-message.ts +0 -89
  474. package/src/tools/inbox-delegate.ts +0 -113
  475. package/thoughts/shared/plans/2025-12-18-slack-integration.md +0 -1195
  476. package/thoughts/shared/plans/2025-12-19-agent-log-streaming.md +0 -732
  477. package/thoughts/shared/plans/2025-12-19-role-based-swarm-plugin.md +0 -361
  478. package/thoughts/shared/plans/2025-12-20-mobile-responsive-ui.md +0 -501
  479. package/thoughts/shared/plans/2025-12-20-startup-team-swarm.md +0 -560
  480. package/thoughts/shared/plans/2025-12-23-runner-level-polling.md +0 -934
  481. package/thoughts/shared/plans/2025-12-23-runner-session-logs.md +0 -1000
  482. package/thoughts/shared/plans/2025-12-23-worker-lead-spawn-triggers.md +0 -568
  483. package/thoughts/shared/plans/2026-01-09-inverse-teleport.md +0 -1516
  484. package/thoughts/shared/plans/2026-01-12-agent-rename-pm2-control.md +0 -1133
  485. package/thoughts/shared/plans/2026-01-12-github-app-integration.md +0 -380
  486. package/thoughts/shared/plans/2026-01-12-lead-inbox-model.md +0 -876
  487. package/thoughts/shared/plans/2026-01-12-ralph-wiggum-integration.md +0 -463
  488. package/thoughts/shared/plans/2026-01-13-agent-concurrency.md +0 -691
  489. package/thoughts/shared/plans/2026-01-13-github-assignment-handling.md +0 -690
  490. package/thoughts/shared/plans/2026-01-13-prevent-duplicate-trigger-processing.md +0 -1071
  491. package/thoughts/shared/plans/2026-01-14-fix-slack-thread-context.md +0 -507
  492. package/thoughts/shared/plans/2026-01-15-scheduled-tasks-implementation.md +0 -565
  493. package/thoughts/shared/plans/2026-01-15-usage-cost-tracking-ui.md +0 -1479
  494. package/thoughts/shared/plans/2026-01-16-epics-feature-implementation.md +0 -1230
  495. package/thoughts/shared/research/.gitkeep +0 -0
  496. package/thoughts/shared/research/2025-01-09-inverse-teleport-plan-review.md +0 -420
  497. package/thoughts/shared/research/2025-12-18-slack-integration.md +0 -442
  498. package/thoughts/shared/research/2025-12-19-agent-log-streaming.md +0 -339
  499. package/thoughts/shared/research/2025-12-19-agent-secrets-cli-research.md +0 -390
  500. package/thoughts/shared/research/2025-12-21-gemini-cli-integration.md +0 -376
  501. package/thoughts/shared/research/2025-12-22-runner-loop-architecture.md +0 -582
  502. package/thoughts/shared/research/2025-12-22-setup-experience-improvements.md +0 -264
  503. package/thoughts/shared/research/2026-01-13-lead-duplicate-trigger-processing.md +0 -223
  504. package/thoughts/shared/research/2026-01-14-lead-slack-thread-context.md +0 -277
  505. package/thoughts/shared/research/2026-01-15-ai-tracker-agent-swarm-integration.md +0 -376
  506. package/thoughts/shared/research/2026-01-15-auto-starting-processes-in-worker-containers.md +0 -787
  507. package/thoughts/shared/research/2026-01-15-scheduled-tasks.md +0 -390
  508. package/thoughts/shared/research/2026-01-16-epics-feature-research.md +0 -437
  509. package/thoughts/taras/plans/2026-01-22-agent-swarm-schemas.md +0 -98
  510. package/thoughts/taras/plans/2026-01-28-per-worker-claude-md.md +0 -617
  511. package/thoughts/taras/plans/2026-01-28-sentry-cli-integration.md +0 -214
  512. package/thoughts/taras/research/2026-01-22-vercel-cli-integration.md +0 -287
  513. package/thoughts/taras/research/2026-01-27-excessive-polling-issue.md +0 -311
  514. package/thoughts/taras/research/2026-01-28-per-worker-claude-md.md +0 -383
  515. package/thoughts/taras/research/2026-01-28-sentry-cli-integration.md +0 -240
  516. package/tsconfig.json +0 -37
  517. package/ui/CLAUDE.md +0 -49
  518. package/ui/bun.lock +0 -771
  519. package/ui/index.html +0 -22
  520. package/ui/package-lock.json +0 -5290
  521. package/ui/package.json +0 -33
  522. package/ui/pnpm-lock.yaml +0 -3341
  523. package/ui/postcss.config.js +0 -6
  524. package/ui/public/logo.png +0 -0
  525. package/ui/src/App.tsx +0 -63
  526. package/ui/src/components/ActivityFeed.tsx +0 -440
  527. package/ui/src/components/AgentDetailPanel.tsx +0 -733
  528. package/ui/src/components/AgentsPanel.tsx +0 -815
  529. package/ui/src/components/ChatPanel.tsx +0 -1920
  530. package/ui/src/components/ConfigModal.tsx +0 -253
  531. package/ui/src/components/Dashboard.tsx +0 -832
  532. package/ui/src/components/EditAgentProfileModal.tsx +0 -433
  533. package/ui/src/components/EpicDetailPage.tsx +0 -741
  534. package/ui/src/components/EpicsPanel.tsx +0 -566
  535. package/ui/src/components/Header.tsx +0 -160
  536. package/ui/src/components/JsonViewer.tsx +0 -171
  537. package/ui/src/components/ScheduledTaskDetailPanel.tsx +0 -517
  538. package/ui/src/components/ScheduledTasksPanel.tsx +0 -639
  539. package/ui/src/components/ServicesPanel.tsx +0 -622
  540. package/ui/src/components/SessionLogPanel.tsx +0 -1219
  541. package/ui/src/components/StatsBar.tsx +0 -321
  542. package/ui/src/components/StatusBadge.tsx +0 -168
  543. package/ui/src/components/TaskDetailPanel.tsx +0 -903
  544. package/ui/src/components/TasksPanel.tsx +0 -614
  545. package/ui/src/components/UsageCharts.tsx +0 -216
  546. package/ui/src/components/UsageTab.tsx +0 -394
  547. package/ui/src/hooks/queries.ts +0 -353
  548. package/ui/src/hooks/useAutoScroll.ts +0 -83
  549. package/ui/src/index.css +0 -257
  550. package/ui/src/lib/api.ts +0 -268
  551. package/ui/src/lib/config.ts +0 -35
  552. package/ui/src/lib/contentPreview.ts +0 -208
  553. package/ui/src/lib/theme.ts +0 -214
  554. package/ui/src/lib/utils.ts +0 -88
  555. package/ui/src/main.tsx +0 -28
  556. package/ui/src/types/api.ts +0 -323
  557. package/ui/src/vite-env.d.ts +0 -1
  558. package/ui/tailwind.config.js +0 -37
  559. package/ui/tsconfig.json +0 -31
  560. package/ui/vite.config.ts +0 -35
  561. /package/{thoughts/shared/plans → templates/community}/.gitkeep +0 -0
@@ -1,691 +0,0 @@
1
- ---
2
- date: 2026-01-13
3
- author: master lord
4
- git_commit: 5ce502b
5
- branch: main
6
- repository: agent-swarm
7
- topic: "Agent Concurrency - Parallel Claude Subprocess Execution"
8
- tags: [plan, concurrency, runner, parallel-execution, capacity-management]
9
- status: complete
10
- last_updated: 2026-01-13T16:20:00Z
11
- ---
12
-
13
- ## Implementation Progress Summary
14
-
15
- **COMPLETE - All implementation and manual verification finished.**
16
-
17
- ### Completed:
18
- - [x] Phase 1: Database and Type Changes
19
- - [x] Phase 2: Task Assignment Capacity Checks
20
- - [x] Phase 3: Runner Parallel Execution
21
- - [x] Phase 4: API and Registration Updates
22
- - [x] Phase 5: Integration Testing (automated tests)
23
-
24
- ### Bug Fixes Applied:
25
- 1. **Poll endpoint marking tasks in_progress** (`src/http.ts:369-380`) - Fixed duplicate task polling by marking tasks as `in_progress` when returned via poll API
26
- 2. **Process completion detection** (`src/commands/runner.ts:684-699`) - Fixed using `task.process.exitCode !== null` instead of broken `Promise.race` pattern
27
- 3. **Poll endpoint capacity check** (`src/http.ts:371-384`) - Added server-side capacity check before returning pending tasks to prevent exceeding maxTasks
28
- 4. **Agent registration maxTasks sync** (`src/http.ts:315-318`, `src/be/db.ts:529-537`) - Added `updateAgentMaxTasks()` function and updated registration endpoint to sync `MAX_CONCURRENT_TASKS` env var to database when agent re-registers
29
-
30
- ### Remaining Manual Verification:
31
- - [x] Phase 2: Capacity enforcement test - VERIFIED (2026-01-13)
32
- - [x] Phase 3: Concurrent execution test - VERIFIED (server-side enforces maxTasks, tasks queue correctly)
33
- - [x] Phase 4: API capacity response - VERIFIED (maxTasks shows in agent responses)
34
- - [x] Phase 5: Full end-to-end test - VERIFIED (tasks queue when at capacity, process when slots free)
35
-
36
- ---
37
-
38
- # Agent Concurrency Implementation Plan
39
-
40
- ## Overview
41
-
42
- Add support for parallel Claude subprocess execution to the agent-swarm system, allowing leads and workers to handle multiple tasks concurrently. Each agent will have a configurable maximum concurrency limit (default: 1 for backwards compatibility).
43
-
44
- ## Current State Analysis
45
-
46
- The current architecture is strictly sequential:
47
-
48
- 1. **Runner loop** (`src/commands/runner.ts:573-661`) polls for one trigger at a time and **blocks until Claude completes** before polling for the next trigger
49
- 2. **Agent status** is binary: `idle`, `busy`, `offline` (`src/types.ts:97`)
50
- 3. **Task assignment** is blocked when agent is not `idle` (`src/tools/send-task.ts:119-125`)
51
- 4. **Status management**: `store-progress.ts:91,99` sets agent to `idle` on task completion
52
-
53
- ### Key Files:
54
- - `src/commands/runner.ts` - Main runner loop (lines 573-661)
55
- - `src/types.ts` - Agent and task schemas
56
- - `src/be/db.ts` - Database operations
57
- - `src/http.ts` - HTTP API including `/api/poll` (lines 316-425)
58
- - `src/tools/send-task.ts` - Task assignment logic
59
- - `src/tools/store-progress.ts` - Task completion handling
60
- - `src/tools/poll-task.ts` - MCP polling tool
61
-
62
- ## Desired End State
63
-
64
- After implementation:
65
- - Agents can run N Claude subprocesses concurrently (configurable via `MAX_CONCURRENT_TASKS` env var)
66
- - Runner spawns Claude without blocking, tracking active processes in a Map
67
- - Capacity is checked before task assignment (not binary idle/busy)
68
- - Tasks queue in `pending` status when agent is at capacity, picked up when slots open
69
- - Status derived from active task count (`idle` = 0 tasks, `busy` = 1+ tasks)
70
- - Default limit is 1 (backwards compatible)
71
-
72
- ### Verification:
73
- 1. Set `MAX_CONCURRENT_TASKS=3` and send 3 tasks to a worker
74
- 2. All 3 Claude processes should run simultaneously
75
- 3. A 4th task should queue in `pending` until one completes
76
- 4. Agent status shows `busy` while any task is running
77
-
78
- ## What We're NOT Doing
79
-
80
- - NOT changing the MCP `poll-task` tool (it's for AI-loop mode, mostly unused)
81
- - NOT adding a formal job queue system (simple Promise tracking is sufficient)
82
- - NOT using PM2 for subprocess management (overkill for this)
83
- - NOT changing the lead inbox model (leads still process inbox triggers)
84
- - NOT implementing task priority-based scheduling (FIFO from pending queue)
85
-
86
- ## Implementation Approach
87
-
88
- **Capacity Model**: Track `maxTasks` per agent in the database, derive active count from `agent_tasks` table where `status = 'in_progress'`. This ensures accuracy without stale state.
89
-
90
- **Process Model**: Track running Claude processes in a `Map<taskId, Promise<number>>` within the runner. Poll for new triggers when under capacity, spawn without blocking.
91
-
92
- **Status Derivation**: Keep `idle/busy/offline` status but derive from active task count. Agent is `idle` when no in-progress tasks, `busy` otherwise.
93
-
94
- ---
95
-
96
- ## Phase 1: Database and Type Changes
97
-
98
- ### Overview
99
- Add capacity tracking fields to the agent schema and database, implement helper functions.
100
-
101
- ### Changes Required:
102
-
103
- #### 1. Update Agent Schema
104
- **File**: `src/types.ts`
105
-
106
- Add `maxTasks` field to `AgentSchema`:
107
-
108
- ```typescript
109
- export const AgentSchema = z.object({
110
- id: z.uuid(),
111
- name: z.string().min(1),
112
- isLead: z.boolean().default(false),
113
- status: AgentStatusSchema,
114
-
115
- // Profile fields
116
- description: z.string().optional(),
117
- role: z.string().max(100).optional(),
118
- capabilities: z.array(z.string()).default([]),
119
-
120
- // NEW: Concurrency limit
121
- maxTasks: z.number().int().min(1).max(20).default(1),
122
-
123
- createdAt: z.iso.datetime().default(() => new Date().toISOString()),
124
- lastUpdatedAt: z.iso.datetime().default(() => new Date().toISOString()),
125
- });
126
- ```
127
-
128
- #### 2. Database Schema Migration
129
- **File**: `src/be/db.ts`
130
-
131
- Add column to agents table in `initDb()` (around line 42):
132
-
133
- ```sql
134
- ALTER TABLE agents ADD COLUMN maxTasks INTEGER DEFAULT 1;
135
- ```
136
-
137
- Handle migration for existing databases by checking if column exists.
138
-
139
- #### 3. Add Capacity Functions
140
- **File**: `src/be/db.ts`
141
-
142
- Add new functions after `updateAgentStatus()` (around line 520):
143
-
144
- ```typescript
145
- export function getActiveTaskCount(agentId: string): number {
146
- const result = getDb()
147
- .prepare<{ count: number }, [string]>(
148
- "SELECT COUNT(*) as count FROM agent_tasks WHERE agentId = ? AND status = 'in_progress'"
149
- )
150
- .get(agentId);
151
- return result?.count ?? 0;
152
- }
153
-
154
- export function hasCapacity(agentId: string): boolean {
155
- const agent = getAgentById(agentId);
156
- if (!agent) return false;
157
- const activeCount = getActiveTaskCount(agentId);
158
- return activeCount < (agent.maxTasks ?? 1);
159
- }
160
-
161
- export function getRemainingCapacity(agentId: string): number {
162
- const agent = getAgentById(agentId);
163
- if (!agent) return 0;
164
- const activeCount = getActiveTaskCount(agentId);
165
- return Math.max(0, (agent.maxTasks ?? 1) - activeCount);
166
- }
167
-
168
- export function updateAgentStatusFromCapacity(agentId: string): void {
169
- const agent = getAgentById(agentId);
170
- if (!agent || agent.status === 'offline') return;
171
-
172
- const activeCount = getActiveTaskCount(agentId);
173
- const newStatus = activeCount > 0 ? 'busy' : 'idle';
174
-
175
- if (agent.status !== newStatus) {
176
- updateAgentStatus(agentId, newStatus);
177
- }
178
- }
179
- ```
180
-
181
- #### 4. Update Agent Registration
182
- **File**: `src/be/db.ts`
183
-
184
- Modify `createAgent()` to accept `maxTasks` parameter.
185
-
186
- ### Success Criteria:
187
-
188
- #### Automated Verification:
189
- - [x] Type checks pass: `bun run typecheck` (if script exists) or no TS errors
190
- - [x] Database migration runs: start server and verify `maxTasks` column exists
191
- - [x] Unit test for capacity functions: `bun test src/tests/db-capacity.test.ts`
192
-
193
- #### Manual Verification:
194
- - [x] Query `SELECT * FROM agents` shows `maxTasks` column
195
- - [x] New agents get `maxTasks = 1` by default
196
-
197
- **Implementation Note**: After completing this phase and all automated verification passes, pause here for manual confirmation before proceeding to the next phase.
198
-
199
- ---
200
-
201
- ## Phase 2: Task Assignment Capacity Checks
202
-
203
- ### Overview
204
- Replace binary `idle` checks with capacity-based checks in task assignment logic.
205
-
206
- ### Changes Required:
207
-
208
- #### 1. Update send-task Tool
209
- **File**: `src/tools/send-task.ts`
210
-
211
- Replace lines 119-125:
212
-
213
- ```typescript
214
- // OLD:
215
- if (!offerMode && agent.status !== "idle") {
216
- return {
217
- success: false,
218
- message: `Agent "${agent.name}" is not idle (status: ${agent.status}). Cannot assign task directly.`,
219
- };
220
- }
221
-
222
- // NEW:
223
- if (!offerMode && !hasCapacity(agentId)) {
224
- const activeCount = getActiveTaskCount(agentId);
225
- return {
226
- success: false,
227
- message: `Agent "${agent.name}" is at capacity (${activeCount}/${agent.maxTasks} tasks). Use offerMode: true to offer the task instead, or wait for a task to complete.`,
228
- };
229
- }
230
- ```
231
-
232
- Import the new functions at the top.
233
-
234
- #### 2. Update store-progress Tool
235
- **File**: `src/tools/store-progress.ts`
236
-
237
- Replace lines 86-107:
238
-
239
- ```typescript
240
- // Handle status change
241
- if (status === "completed") {
242
- const result = completeTask(taskId, output);
243
- if (result) {
244
- updatedTask = result;
245
- if (existingTask.agentId) {
246
- // NEW: Derive status from capacity instead of always setting idle
247
- updateAgentStatusFromCapacity(existingTask.agentId);
248
- }
249
- }
250
- } else if (status === "failed") {
251
- const result = failTask(taskId, failureReason ?? "Unknown failure");
252
- if (result) {
253
- updatedTask = result;
254
- if (existingTask.agentId) {
255
- updateAgentStatusFromCapacity(existingTask.agentId);
256
- }
257
- }
258
- } else {
259
- // Progress update - ensure status reflects current load
260
- if (existingTask.agentId) {
261
- updateAgentStatusFromCapacity(existingTask.agentId);
262
- }
263
- }
264
- ```
265
-
266
- #### 3. Update task-action Tool
267
- **File**: `src/tools/task-action.ts`
268
-
269
- Add capacity check for `claim` action:
270
-
271
- ```typescript
272
- case "claim": {
273
- if (!hasCapacity(agentId)) {
274
- const activeCount = getActiveTaskCount(agentId);
275
- const agent = getAgentById(agentId);
276
- return {
277
- success: false,
278
- message: `You have no capacity (${activeCount}/${agent?.maxTasks ?? 1} tasks). Complete a task first.`
279
- };
280
- }
281
- // ... existing claim logic
282
- }
283
- ```
284
-
285
- ### Success Criteria:
286
-
287
- #### Automated Verification:
288
- - [x] Type checks pass
289
- - [x] Existing tests still pass: `bun test`
290
- - [x] New test: assign task to agent at capacity, verify rejection message
291
-
292
- #### Manual Verification:
293
- - [ ] Set agent `maxTasks = 2`, assign 2 tasks, try to assign 3rd - should get capacity error
294
- - [ ] Complete one task, agent should allow 3rd assignment
295
-
296
- **Implementation Note**: After completing this phase and all automated verification passes, pause here for manual confirmation before proceeding to the next phase.
297
-
298
- ---
299
-
300
- ## Phase 3: Runner Parallel Execution
301
-
302
- ### Overview
303
- Transform the runner loop from blocking sequential execution to parallel subprocess management.
304
-
305
- **IMPORTANT FIX REQUIRED**: The poll endpoint (`src/http.ts`) must mark tasks as `in_progress` when returning them to prevent duplicate polling. Add `startTask(pendingTask.id)` before returning the `task_assigned` trigger.
306
-
307
- ### Changes Required:
308
-
309
- #### 1. Add Runner State Type
310
- **File**: `src/commands/runner.ts`
311
-
312
- Add new interfaces after line 100:
313
-
314
- ```typescript
315
- interface RunningTask {
316
- taskId: string;
317
- process: ReturnType<typeof Bun.spawn>;
318
- logFile: string;
319
- startTime: Date;
320
- promise: Promise<number>;
321
- }
322
-
323
- interface RunnerState {
324
- activeTasks: Map<string, RunningTask>;
325
- maxConcurrent: number;
326
- }
327
- ```
328
-
329
- #### 2. Create Non-Blocking Claude Spawner
330
- **File**: `src/commands/runner.ts`
331
-
332
- Add new function after `runClaudeIteration()`:
333
-
334
- ```typescript
335
- function spawnClaudeProcess(opts: RunClaudeIterationOptions): RunningTask {
336
- const { role, logFile } = opts;
337
- const Cmd = [
338
- "claude",
339
- "--model", "opus",
340
- "--verbose",
341
- "--output-format", "stream-json",
342
- "--dangerously-skip-permissions",
343
- "--allow-dangerously-skip-permissions",
344
- "--permission-mode", "bypassPermissions",
345
- "-p", opts.prompt,
346
- ];
347
-
348
- if (opts.additionalArgs?.length) {
349
- Cmd.push(...opts.additionalArgs);
350
- }
351
-
352
- if (opts.systemPrompt) {
353
- Cmd.push("--append-system-prompt", opts.systemPrompt);
354
- }
355
-
356
- console.log(`[${role}] Spawning Claude for task ${opts.taskId || 'unknown'}`);
357
-
358
- const logFileHandle = Bun.file(logFile).writer();
359
-
360
- const proc = Bun.spawn(Cmd, {
361
- env: process.env,
362
- stdout: "pipe",
363
- stderr: "pipe",
364
- });
365
-
366
- // Create promise that resolves when process completes
367
- const promise = (async () => {
368
- // Stream stdout and stderr (existing logic from runClaudeIteration)
369
- const stdoutPromise = streamStdout(proc, logFileHandle, opts);
370
- const stderrPromise = streamStderr(proc, logFileHandle, role);
371
-
372
- await Promise.all([stdoutPromise, stderrPromise]);
373
- await logFileHandle.end();
374
- return await proc.exited ?? 1;
375
- })();
376
-
377
- return {
378
- taskId: opts.taskId || crypto.randomUUID(),
379
- process: proc,
380
- logFile,
381
- startTime: new Date(),
382
- promise,
383
- };
384
- }
385
- ```
386
-
387
- #### 3. Refactor Main Loop
388
- **File**: `src/commands/runner.ts`
389
-
390
- Replace the `while (true)` loop (lines 573-661) in non-AI-loop mode:
391
-
392
- ```typescript
393
- // Initialize runner state
394
- const state: RunnerState = {
395
- activeTasks: new Map(),
396
- maxConcurrent: parseInt(process.env.MAX_CONCURRENT_TASKS || "1", 10),
397
- };
398
-
399
- console.log(`[${role}] Max concurrent tasks: ${state.maxConcurrent}`);
400
-
401
- while (true) {
402
- await pingServer(apiConfig, role);
403
-
404
- // Check for completed processes
405
- await checkCompletedProcesses(state, role);
406
-
407
- // Only poll if we have capacity
408
- if (state.activeTasks.size < state.maxConcurrent) {
409
- console.log(`[${role}] Polling for triggers (${state.activeTasks.size}/${state.maxConcurrent} active)...`);
410
-
411
- const trigger = await pollForTrigger({
412
- apiUrl,
413
- apiKey,
414
- agentId,
415
- pollInterval: PollIntervalMs,
416
- pollTimeout: state.activeTasks.size > 0 ? 5000 : PollTimeoutMs, // Short timeout if tasks running
417
- since: lastFinishedTaskCheck,
418
- });
419
-
420
- if (trigger) {
421
- if (trigger.type === "tasks_finished") {
422
- lastFinishedTaskCheck = new Date().toISOString();
423
- }
424
-
425
- console.log(`[${role}] Trigger received: ${trigger.type}`);
426
-
427
- const triggerPrompt = buildPromptForTrigger(trigger, prompt);
428
- iteration++;
429
- const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
430
- const logFile = `${logDir}/${timestamp}-${trigger.taskId?.slice(0, 8) || 'notask'}.jsonl`;
431
-
432
- // Spawn without blocking
433
- const runningTask = spawnClaudeProcess({
434
- prompt: triggerPrompt,
435
- logFile,
436
- systemPrompt: resolvedSystemPrompt,
437
- additionalArgs: opts.additionalArgs,
438
- role,
439
- apiUrl,
440
- apiKey,
441
- agentId,
442
- sessionId,
443
- iteration,
444
- taskId: trigger.taskId,
445
- });
446
-
447
- state.activeTasks.set(runningTask.taskId, runningTask);
448
- console.log(`[${role}] Started task ${runningTask.taskId} (${state.activeTasks.size}/${state.maxConcurrent} active)`);
449
- }
450
- } else {
451
- console.log(`[${role}] At capacity (${state.activeTasks.size}/${state.maxConcurrent}), waiting for completion...`);
452
- await Bun.sleep(1000);
453
- }
454
- }
455
- ```
456
-
457
- #### 4. Add Process Completion Handler
458
- **File**: `src/commands/runner.ts`
459
-
460
- **NOTE**: The original `Promise.race` pattern doesn't work because `Promise.resolve()` always wins the race even against already-resolved promises. Use Bun's native `process.exitCode` check instead:
461
-
462
- ```typescript
463
- async function checkCompletedProcesses(state: RunnerState, role: string): Promise<void> {
464
- const completedTasks: string[] = [];
465
-
466
- for (const [taskId, task] of state.activeTasks) {
467
- // Check if the Bun subprocess has exited (non-blocking)
468
- if (task.process.exitCode !== null) {
469
- console.log(`[${role}] Task ${taskId.slice(0, 8)} completed with exit code ${task.process.exitCode}`);
470
- completedTasks.push(taskId);
471
- }
472
- }
473
-
474
- // Remove completed tasks from the map
475
- for (const taskId of completedTasks) {
476
- state.activeTasks.delete(taskId);
477
- }
478
- }
479
- ```
480
-
481
- #### 5. Update Graceful Shutdown
482
- **File**: `src/commands/runner.ts`
483
-
484
- Modify `shutdown` function (around line 65):
485
-
486
- ```typescript
487
- const shutdown = async (signal: string) => {
488
- console.log(`\n[${role}] Received ${signal}, shutting down...`);
489
-
490
- // Wait for active tasks with timeout
491
- if (state && state.activeTasks.size > 0) {
492
- console.log(`[${role}] Waiting for ${state.activeTasks.size} active tasks to complete (30s timeout)...`);
493
- const deadline = Date.now() + 30000;
494
-
495
- while (state.activeTasks.size > 0 && Date.now() < deadline) {
496
- await checkCompletedProcesses(state, role);
497
- if (state.activeTasks.size > 0) {
498
- await Bun.sleep(500);
499
- }
500
- }
501
-
502
- // Force kill remaining
503
- for (const [taskId, task] of state.activeTasks) {
504
- console.log(`[${role}] Force stopping task ${taskId}`);
505
- task.process.kill("SIGTERM");
506
- }
507
- }
508
-
509
- if (apiConfig) {
510
- await closeAgent(apiConfig, role);
511
- }
512
- await savePm2State(role);
513
- process.exit(0);
514
- };
515
- ```
516
-
517
- ### Success Criteria:
518
-
519
- #### Automated Verification:
520
- - [x] Type checks pass
521
- - [x] Existing tests pass: `bun test`
522
- - [ ] New test: spawn agent with `MAX_CONCURRENT_TASKS=2`, assign 2 tasks, verify both run
523
-
524
- #### Manual Verification:
525
- - [ ] Start worker with `MAX_CONCURRENT_TASKS=3`
526
- - [ ] Assign 3 tasks rapidly
527
- - [ ] Verify 3 Claude processes are running simultaneously (`ps aux | grep claude`)
528
- - [ ] Verify all 3 complete successfully
529
- - [ ] Test graceful shutdown with active tasks
530
-
531
- **Implementation Note**: After completing this phase and all automated verification passes, pause here for manual confirmation before proceeding to the next phase.
532
-
533
- ---
534
-
535
- ## Phase 4: API and Registration Updates
536
-
537
- ### Overview
538
- Update HTTP endpoints and agent registration to support capacity configuration.
539
-
540
- ### Changes Required:
541
-
542
- #### 1. Update Agent Registration
543
- **File**: `src/http.ts`
544
-
545
- In `POST /api/agents` handler (around line 280), accept `maxTasks`:
546
-
547
- ```typescript
548
- const agent = createAgent({
549
- id: agentId,
550
- name: body.name,
551
- isLead: body.isLead ?? false,
552
- status: "idle",
553
- description: body.description,
554
- role: body.role,
555
- capabilities: body.capabilities,
556
- maxTasks: body.maxTasks ?? parseInt(process.env.MAX_CONCURRENT_TASKS || "1", 10),
557
- });
558
- ```
559
-
560
- #### 2. Include Capacity in Agent Responses
561
- **File**: `src/http.ts`
562
-
563
- Add capacity info to agent responses:
564
-
565
- ```typescript
566
- function agentWithCapacity(agent: Agent) {
567
- const activeCount = getActiveTaskCount(agent.id);
568
- return {
569
- ...agent,
570
- capacity: {
571
- current: activeCount,
572
- max: agent.maxTasks ?? 1,
573
- available: Math.max(0, (agent.maxTasks ?? 1) - activeCount),
574
- },
575
- };
576
- }
577
- ```
578
-
579
- Apply this to `/me`, `GET /api/agents`, and poll responses.
580
-
581
- #### 3. Update Runner Registration
582
- **File**: `src/commands/runner.ts`
583
-
584
- Update `registerAgent()` to send `maxTasks`:
585
-
586
- ```typescript
587
- await registerAgent({
588
- apiUrl,
589
- apiKey,
590
- agentId,
591
- name: agentName,
592
- isLead: role === "lead",
593
- capabilities: config.capabilities,
594
- maxTasks: parseInt(process.env.MAX_CONCURRENT_TASKS || "1", 10),
595
- });
596
- ```
597
-
598
- ### Success Criteria:
599
-
600
- #### Automated Verification:
601
- - [x] API tests pass: `bun test src/tests/rest-api.test.ts`
602
- - [x] Agent registration includes `maxTasks`
603
-
604
- #### Manual Verification:
605
- - [ ] `GET /me` response includes `capacity` object
606
- - [ ] Start agent with `MAX_CONCURRENT_TASKS=5`, verify API shows `max: 5`
607
-
608
- **Implementation Note**: After completing this phase and all automated verification passes, pause here for manual confirmation before proceeding to the next phase.
609
-
610
- ---
611
-
612
- ## Phase 5: Integration Testing
613
-
614
- ### Overview
615
- Comprehensive end-to-end testing of the concurrency feature.
616
-
617
- ### Test Cases:
618
-
619
- 1. **Backwards Compatibility**
620
- - Start agent without `MAX_CONCURRENT_TASKS` env var
621
- - Verify default `maxTasks = 1`
622
- - Verify sequential execution (only 1 Claude at a time)
623
-
624
- 2. **Concurrent Execution**
625
- - Start worker with `MAX_CONCURRENT_TASKS=3`
626
- - Assign 5 tasks rapidly
627
- - Verify 3 Claude processes running
628
- - Verify 2 tasks queued in `pending`
629
- - As tasks complete, queued tasks start
630
-
631
- 3. **Capacity Enforcement**
632
- - Agent at capacity
633
- - Try to assign directly -> should get capacity error
634
- - Offer mode should still work
635
-
636
- 4. **Graceful Shutdown**
637
- - Start 3 concurrent tasks
638
- - Send SIGTERM
639
- - Verify tasks complete before exit (up to 30s)
640
-
641
- 5. **Status Accuracy**
642
- - Agent with 2/3 tasks running -> `status: busy`
643
- - All tasks complete -> `status: idle`
644
- - New task starts -> `status: busy`
645
-
646
- ### Success Criteria:
647
-
648
- #### Automated Verification:
649
- - [x] All unit tests pass: `bun test`
650
- - [x] New integration test file passes: `bun test src/tests/concurrency.test.ts`
651
-
652
- #### Manual Verification:
653
- - [ ] Run through all 5 test cases above
654
- - [ ] Monitor with `ps aux | grep claude` to verify concurrent processes
655
- - [ ] Check UI shows correct capacity info
656
-
657
- ---
658
-
659
- ## Testing Strategy
660
-
661
- ### Unit Tests:
662
- - `getActiveTaskCount()` returns correct count
663
- - `hasCapacity()` returns true/false correctly
664
- - `updateAgentStatusFromCapacity()` sets correct status
665
- - `send-task` rejects at capacity, allows with capacity
666
-
667
- ### Integration Tests:
668
- - Full flow: register -> assign tasks -> complete -> verify status
669
- - Concurrent spawn verification
670
- - Graceful shutdown with active tasks
671
-
672
- ### Manual Testing Steps:
673
- 1. Start swarm server: `bun run src/server.ts`
674
- 2. Start worker with concurrency: `MAX_CONCURRENT_TASKS=3 bun run src/cli.tsx worker`
675
- 3. Send 5 tasks via API or lead agent
676
- 4. Watch console output for concurrent spawn logs
677
- 5. Verify with `ps aux | grep claude` shows 3 processes
678
- 6. Wait for completion, verify all tasks marked complete
679
-
680
- ## Configuration Summary
681
-
682
- | Variable | Default | Description |
683
- |----------|---------|-------------|
684
- | `MAX_CONCURRENT_TASKS` | 1 | Maximum concurrent Claude subprocesses per agent |
685
- | `SHUTDOWN_TIMEOUT` | 30000 | Milliseconds to wait for tasks on shutdown |
686
-
687
- ## References
688
-
689
- - Existing runner architecture: `thoughts/shared/research/2025-12-22-runner-loop-architecture.md`
690
- - Runner-level polling plan: `thoughts/shared/plans/2025-12-23-runner-level-polling.md`
691
- - Current implementation: `src/commands/runner.ts:573-661`