@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
package/src/server.ts CHANGED
@@ -2,7 +2,11 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import pkg from "../package.json";
3
3
  import { initDb } from "./be/db";
4
4
  import { registerCancelTaskTool } from "./tools/cancel-task";
5
+ import { registerContextDiffTool } from "./tools/context-diff";
6
+ import { registerContextHistoryTool } from "./tools/context-history";
5
7
  import { registerCreateChannelTool } from "./tools/create-channel";
8
+ import { registerDbQueryTool } from "./tools/db-query";
9
+ import { registerDeleteChannelTool } from "./tools/delete-channel";
6
10
  // Epics capability
7
11
  import {
8
12
  registerAssignTaskToEpicTool,
@@ -13,20 +17,30 @@ import {
13
17
  registerUnassignTaskFromEpicTool,
14
18
  registerUpdateEpicTool,
15
19
  } from "./tools/epics";
16
- // Lead inbox tools
17
- import { registerGetInboxMessageTool } from "./tools/get-inbox-message";
18
20
  import { registerGetSwarmTool } from "./tools/get-swarm";
19
21
  import { registerGetTaskDetailsTool } from "./tools/get-task-details";
20
22
  import { registerGetTasksTool } from "./tools/get-tasks";
21
- import { registerInboxDelegateTool } from "./tools/inbox-delegate";
23
+ import { registerInjectLearningTool } from "./tools/inject-learning";
22
24
  import { registerJoinSwarmTool } from "./tools/join-swarm";
23
25
  // Messaging capability
24
26
  import { registerListChannelsTool } from "./tools/list-channels";
25
27
  import { registerListServicesTool } from "./tools/list-services";
28
+ // Memory capability
29
+ import { registerMemoryGetTool } from "./tools/memory-get";
30
+ import { registerMemorySearchTool } from "./tools/memory-search";
26
31
  import { registerMyAgentInfoTool } from "./tools/my-agent-info";
27
32
  import { registerPollTaskTool } from "./tools/poll-task";
28
33
  import { registerPostMessageTool } from "./tools/post-message";
34
+ // Prompt template tools
35
+ import {
36
+ registerDeletePromptTemplateTool,
37
+ registerGetPromptTemplateTool,
38
+ registerListPromptTemplatesTool,
39
+ registerPreviewPromptTemplateTool,
40
+ registerSetPromptTemplateTool,
41
+ } from "./tools/prompt-templates";
29
42
  import { registerReadMessagesTool } from "./tools/read-messages";
43
+ import { registerRegisterAgentMailInboxTool } from "./tools/register-agentmail-inbox";
30
44
  // Services capability
31
45
  import { registerRegisterServiceTool } from "./tools/register-service";
32
46
  // Scheduling capability
@@ -45,16 +59,45 @@ import { registerSlackReadTool } from "./tools/slack-read";
45
59
  import { registerSlackReplyTool } from "./tools/slack-reply";
46
60
  import { registerSlackUploadFileTool } from "./tools/slack-upload-file";
47
61
  import { registerStoreProgressTool } from "./tools/store-progress";
62
+ // Swarm config tools
63
+ import {
64
+ registerDeleteConfigTool,
65
+ registerGetConfigTool,
66
+ registerListConfigTool,
67
+ registerSetConfigTool,
68
+ } from "./tools/swarm-config";
48
69
  // Task pool capability
49
70
  import { registerTaskActionTool } from "./tools/task-action";
71
+ // Tracker capability
72
+ import {
73
+ registerTrackerLinkEpicTool,
74
+ registerTrackerLinkTaskTool,
75
+ registerTrackerMapAgentTool,
76
+ registerTrackerStatusTool,
77
+ registerTrackerSyncStatusTool,
78
+ registerTrackerUnlinkTool,
79
+ } from "./tools/tracker";
50
80
  import { registerUnregisterServiceTool } from "./tools/unregister-service";
51
81
  // Profiles capability
52
82
  import { registerUpdateProfileTool } from "./tools/update-profile";
53
83
  import { registerUpdateServiceStatusTool } from "./tools/update-service-status";
84
+ // Workflows capability
85
+ import {
86
+ registerCreateWorkflowTool,
87
+ registerDeleteWorkflowTool,
88
+ registerGetWorkflowRunTool,
89
+ registerGetWorkflowTool,
90
+ registerListWorkflowRunsTool,
91
+ registerListWorkflowsTool,
92
+ registerRetryWorkflowRunTool,
93
+ registerTriggerWorkflowTool,
94
+ registerUpdateWorkflowTool,
95
+ } from "./tools/workflows";
54
96
 
55
97
  // Capability-based feature flags
56
98
  // Default: all capabilities enabled
57
- const DEFAULT_CAPABILITIES = "core,task-pool,messaging,profiles,services,scheduling,epics";
99
+ const DEFAULT_CAPABILITIES =
100
+ "core,task-pool,messaging,profiles,services,scheduling,epics,memory,workflows";
58
101
  const CAPABILITIES = new Set(
59
102
  (process.env.CAPABILITIES || DEFAULT_CAPABILITIES).split(",").map((s) => s.trim()),
60
103
  );
@@ -96,6 +139,22 @@ export function createServer() {
96
139
  registerMyAgentInfoTool(server);
97
140
  registerCancelTaskTool(server);
98
141
 
142
+ // Debug tools - always registered (self-guards with lead check)
143
+ registerDbQueryTool(server);
144
+
145
+ // Swarm config tools - always registered (config management is fundamental)
146
+ registerSetConfigTool(server);
147
+ registerGetConfigTool(server);
148
+ registerListConfigTool(server);
149
+ registerDeleteConfigTool(server);
150
+
151
+ // Prompt template tools - always registered (prompt management is fundamental)
152
+ registerListPromptTemplatesTool(server);
153
+ registerGetPromptTemplateTool(server);
154
+ registerSetPromptTemplateTool(server);
155
+ registerDeletePromptTemplateTool(server);
156
+ registerPreviewPromptTemplateTool(server);
157
+
99
158
  // Slack integration tools (always registered, will no-op if Slack not configured)
100
159
  registerSlackReplyTool(server);
101
160
  registerSlackReadTool(server);
@@ -103,8 +162,9 @@ export function createServer() {
103
162
  registerSlackListChannelsTool(server);
104
163
  registerSlackUploadFileTool(server);
105
164
  registerSlackDownloadFileTool(server);
106
- registerInboxDelegateTool(server);
107
- registerGetInboxMessageTool(server);
165
+
166
+ // AgentMail integration tool (always registered, self-service inbox mapping)
167
+ registerRegisterAgentMailInboxTool(server);
108
168
 
109
169
  // Task pool capability - task pool operations (create unassigned, claim, release, accept, reject)
110
170
  if (hasCapability("task-pool")) {
@@ -115,6 +175,7 @@ export function createServer() {
115
175
  if (hasCapability("messaging")) {
116
176
  registerListChannelsTool(server);
117
177
  registerCreateChannelTool(server);
178
+ registerDeleteChannelTool(server);
118
179
  registerPostMessageTool(server);
119
180
  registerReadMessagesTool(server);
120
181
  }
@@ -122,6 +183,8 @@ export function createServer() {
122
183
  // Profiles capability - agent profile management
123
184
  if (hasCapability("profiles")) {
124
185
  registerUpdateProfileTool(server);
186
+ registerContextHistoryTool(server);
187
+ registerContextDiffTool(server);
125
188
  }
126
189
 
127
190
  // Services capability - PM2/background service registry
@@ -152,5 +215,33 @@ export function createServer() {
152
215
  registerUnassignTaskFromEpicTool(server);
153
216
  }
154
217
 
218
+ // Memory capability - persistent memory with vector search
219
+ if (hasCapability("memory")) {
220
+ registerMemorySearchTool(server);
221
+ registerMemoryGetTool(server);
222
+ registerInjectLearningTool(server);
223
+ }
224
+
225
+ // Tracker capability - external issue tracker integration
226
+ registerTrackerStatusTool(server);
227
+ registerTrackerLinkTaskTool(server);
228
+ registerTrackerLinkEpicTool(server);
229
+ registerTrackerUnlinkTool(server);
230
+ registerTrackerSyncStatusTool(server);
231
+ registerTrackerMapAgentTool(server);
232
+
233
+ // Workflows capability - DAG-based automation workflows
234
+ if (hasCapability("workflows")) {
235
+ registerCreateWorkflowTool(server);
236
+ registerListWorkflowsTool(server);
237
+ registerGetWorkflowTool(server);
238
+ registerUpdateWorkflowTool(server);
239
+ registerDeleteWorkflowTool(server);
240
+ registerTriggerWorkflowTool(server);
241
+ registerListWorkflowRunsTool(server);
242
+ registerGetWorkflowRunTool(server);
243
+ registerRetryWorkflowRunTool(server);
244
+ }
245
+
155
246
  return server;
156
247
  }
@@ -0,0 +1,105 @@
1
+ # Slack Routing & Buffering Heuristics
2
+
3
+ This document covers all heuristics used by the Slack integration for message routing, buffering, and task creation.
4
+
5
+ ## Thread Follow-up Routing
6
+
7
+ When someone @mentions the bot in a thread, the router checks whether a worker agent is already active in that thread before falling back to the lead agent.
8
+
9
+ **Routing priority (in order):**
10
+
11
+ 1. `swarm#<uuid>` — explicit agent targeting (always wins)
12
+ 2. `swarm#all` — broadcast to all workers
13
+ 3. **Thread follow-up** — if in a thread and a worker is actively working there, route to that worker
14
+ 4. **Lead fallback** — if the bot was @mentioned and no other match, route to lead agent
15
+
16
+ **Thread follow-up conditions:**
17
+ - Message must be in a thread (`thread_ts` present)
18
+ - An agent must have an active task (`in_progress` or `pending`) linked to that thread via `slackChannelId` + `slackThreadTs`
19
+ - The matched agent must not be `offline`
20
+
21
+ **Why this matters:** Without thread follow-up routing, every @mention in a thread goes to the lead, who then has to re-delegate. This shortcut sends the message directly to the worker already handling that conversation.
22
+
23
+ ---
24
+
25
+ ## Additive Slack Buffer
26
+
27
+ **Feature flag:** `ADDITIVE_SLACK=true` (disabled by default)
28
+
29
+ When enabled, thread replies that do NOT @mention the bot are captured, buffered, and batched into a single follow-up task. This allows humans to give multi-message feedback in a thread without needing to @mention the bot each time.
30
+
31
+ ### How it works
32
+
33
+ 1. A human sends a non-@mention message in a thread where the swarm is already active (has existing tasks)
34
+ 2. The message enters an in-memory buffer keyed by `channelId:threadTs`
35
+ 3. A debounce timer starts (default 10 seconds)
36
+ 4. Additional messages within the window are appended to the buffer, resetting the timer each time
37
+ 5. When the timer expires, all buffered messages are flushed into a single task
38
+
39
+ ### Buffer flush behavior
40
+
41
+ - All buffered messages are concatenated with `---` separators
42
+ - The task is created as `pending` status
43
+ - If there is an active task in the thread, the new task gets `dependsOn` set to it (dependency chaining)
44
+ - If there is no active task, the new task has no dependency and is immediately pickable
45
+
46
+ ### Important: Initial @mentions are never buffered
47
+
48
+ The first @mention in a thread always creates a task instantly. Only subsequent non-mention replies enter the buffer. This ensures responsiveness for explicit requests.
49
+
50
+ ### In-memory tradeoffs
51
+
52
+ - Buffer is lost on server restart (acceptable since the 10s window is tiny)
53
+ - No persistence across process restarts
54
+ - Single-process only (no clustering support)
55
+
56
+ ---
57
+
58
+ ## `!now` Command
59
+
60
+ **Syntax:** `/now [optional message]`
61
+
62
+ Used inside a thread with an active buffer to flush immediately, bypassing the debounce timer and dependency chain.
63
+
64
+ **Behavior:**
65
+ - If text follows `!now`, it is appended to the buffer before flushing
66
+ - The buffer is flushed with `immediate=true`, meaning **no `dependsOn`** is set
67
+ - The resulting task is immediately pickable by any available agent
68
+ - Works only when `ADDITIVE_SLACK=true` and in a thread with swarm activity
69
+
70
+ **Use case:** When you have been adding context to a thread and want the swarm to pick it up right now, rather than waiting for the debounce or for the current task to finish.
71
+
72
+ ---
73
+
74
+ ## Dependency Chaining
75
+
76
+ When the additive buffer flushes normally (not via `!now`), the created task uses `dependsOn` to chain to the latest active task in the thread.
77
+
78
+ **Query:** Finds the most recent `in_progress` or `pending` task matching the thread's `slackChannelId` + `slackThreadTs`, ordered by `createdAt DESC`.
79
+
80
+ **Effect:** The follow-up task stays in `pending` until the depended-on task completes. This prevents workers from picking up follow-up context before the original task is done.
81
+
82
+ **`!now` override:** Using `!now` creates the task without any `dependsOn`, making it immediately available regardless of other active tasks.
83
+
84
+ ---
85
+
86
+ ## Feature Flags
87
+
88
+ | Flag | Default | Description |
89
+ |------|---------|-------------|
90
+ | `ADDITIVE_SLACK` | `false` | Enables non-mention thread message buffering and batching |
91
+ | `ADDITIVE_SLACK_BUFFER_MS` | `10000` (10s) | Debounce window in milliseconds for the thread buffer |
92
+
93
+ Both are read from environment variables. `ADDITIVE_SLACK` must be exactly `"true"` to enable. `ADDITIVE_SLACK_BUFFER_MS` is parsed as a number with fallback to 10000.
94
+
95
+ ---
96
+
97
+ ## Feedback Reactions Reference
98
+
99
+ | Event | Slack Feedback | Description |
100
+ |-------|---------------|-------------|
101
+ | First non-mention message buffered | :eyes: reaction | Acknowledges the message was captured |
102
+ | Additional message appended to buffer | :heavy_plus_sign: reaction | Indicates the message was added to existing buffer |
103
+ | `!now` command used | :zap: reaction | Confirms instant flush was triggered |
104
+ | Buffer flushed (with dependency) | :satellite: thread message | "N follow-up message(s) queued pending completion of current task" |
105
+ | Buffer flushed (no dependency / `!now`) | :satellite: thread message | "N follow-up message(s) batched into task" |
@@ -0,0 +1,133 @@
1
+ import type { App } from "@slack/bolt";
2
+ import { cancelTask, createTaskExtended, getAgentById, getLeadAgent, getTaskById } from "../be/db";
3
+ import { buildCancelledBlocks, getTaskLink } from "./blocks";
4
+
5
+ export function registerActionHandlers(app: App): void {
6
+ // "View Full Logs" — URL button, just ack (Slack opens the link automatically)
7
+ app.action("view_task_logs", async ({ ack }) => {
8
+ await ack();
9
+ });
10
+
11
+ // "Follow-up" — open a modal to send a follow-up message to the same agent
12
+ app.action("follow_up_task", async ({ ack, action, body, client }) => {
13
+ await ack();
14
+
15
+ if (action.type !== "button") return;
16
+ const taskId = action.value;
17
+ if (!taskId) return;
18
+
19
+ const triggerId = "trigger_id" in body ? body.trigger_id : undefined;
20
+ if (!triggerId) return;
21
+
22
+ try {
23
+ await client.views.open({
24
+ trigger_id: triggerId,
25
+ view: {
26
+ type: "modal",
27
+ callback_id: "follow_up_submit",
28
+ private_metadata: taskId,
29
+ title: { type: "plain_text", text: "Follow-up" },
30
+ submit: { type: "plain_text", text: "Send" },
31
+ close: { type: "plain_text", text: "Cancel" },
32
+ blocks: [
33
+ {
34
+ type: "input",
35
+ block_id: "follow_up_input",
36
+ label: { type: "plain_text", text: "Follow-up message" },
37
+ element: {
38
+ type: "plain_text_input",
39
+ action_id: "follow_up_text",
40
+ multiline: true,
41
+ placeholder: {
42
+ type: "plain_text",
43
+ text: "What would you like the agent to do next?",
44
+ },
45
+ },
46
+ },
47
+ ],
48
+ },
49
+ });
50
+ } catch (error) {
51
+ console.error("[Slack] Failed to open follow-up modal:", error);
52
+ }
53
+ });
54
+
55
+ // Handle follow-up modal submission
56
+ app.view("follow_up_submit", async ({ ack, view, body, client }) => {
57
+ await ack();
58
+
59
+ const taskId = view.private_metadata;
60
+ const followUpText = view.state.values.follow_up_input?.follow_up_text?.value || "";
61
+
62
+ if (!taskId || !followUpText) return;
63
+
64
+ const originalTask = getTaskById(taskId);
65
+ if (!originalTask || !originalTask.slackChannelId) return;
66
+
67
+ const lead = getLeadAgent();
68
+ const followUpTask = createTaskExtended(followUpText, {
69
+ agentId: lead?.id,
70
+ source: "slack",
71
+ parentTaskId: taskId,
72
+ slackChannelId: originalTask.slackChannelId,
73
+ slackThreadTs: originalTask.slackThreadTs,
74
+ slackUserId: body.user.id,
75
+ });
76
+
77
+ const taskLink = getTaskLink(followUpTask.id);
78
+ const agentName = lead ? lead.name : "queue";
79
+ const threadTs = originalTask.slackThreadTs;
80
+
81
+ try {
82
+ await client.chat.postMessage({
83
+ channel: originalTask.slackChannelId,
84
+ thread_ts: threadTs,
85
+ text: `💬 Follow-up sent to *${agentName}* (${taskLink})`,
86
+ });
87
+ } catch (error) {
88
+ console.error("[Slack] Failed to post follow-up confirmation:", error);
89
+ }
90
+ });
91
+
92
+ // "Cancel" — cancel the task and update the message
93
+ app.action("cancel_task", async ({ ack, action, client, body }) => {
94
+ await ack();
95
+
96
+ if (action.type !== "button") return;
97
+ const taskId = action.value;
98
+ if (!taskId) return;
99
+
100
+ const task = getTaskById(taskId);
101
+ if (!task) return;
102
+
103
+ // Cancel the task in DB
104
+ const cancelled = cancelTask(taskId, "Cancelled via Slack");
105
+ if (!cancelled) {
106
+ // Task was already in a terminal state
107
+ return;
108
+ }
109
+
110
+ // Update the message to show cancelled state
111
+ if (task.slackChannelId && task.agentId) {
112
+ const agent = getAgentById(task.agentId);
113
+ const agentName = agent?.name || "Unknown";
114
+ const blocks = buildCancelledBlocks({ agentName, taskId: task.id });
115
+
116
+ try {
117
+ // body.message?.ts is the message where the button was clicked
118
+ const messageTs = "message" in body && body.message?.ts;
119
+ if (messageTs && typeof messageTs === "string") {
120
+ await client.chat.update({
121
+ channel: task.slackChannelId,
122
+ ts: messageTs,
123
+ text: "Task cancelled",
124
+ // biome-ignore lint/suspicious/noExplicitAny: Block Kit objects
125
+ blocks: blocks as any,
126
+ });
127
+ }
128
+ } catch (error) {
129
+ console.error("[Slack] Failed to update cancelled message:", error);
130
+ }
131
+ }
132
+ });
133
+ }
package/src/slack/app.ts CHANGED
@@ -41,9 +41,15 @@ export async function initSlackApp(): Promise<App | null> {
41
41
  // Register handlers
42
42
  const { registerMessageHandler } = await import("./handlers");
43
43
  const { registerCommandHandler } = await import("./commands");
44
+ const { registerActionHandlers } = await import("./actions");
44
45
 
45
46
  registerMessageHandler(app);
46
47
  registerCommandHandler(app);
48
+ registerActionHandlers(app);
49
+
50
+ // Register assistant thread handler (safe even if "Agents & AI Apps" isn't enabled)
51
+ const { createAssistant } = await import("./assistant");
52
+ app.assistant(createAssistant());
47
53
 
48
54
  return app;
49
55
  }
@@ -70,4 +76,5 @@ export async function stopSlackApp(): Promise<void> {
70
76
  app = null;
71
77
  console.log("[Slack] Bot disconnected");
72
78
  }
79
+ initialized = false;
73
80
  }
@@ -0,0 +1,118 @@
1
+ import { Assistant } from "@slack/bolt";
2
+ import {
3
+ createTaskExtended,
4
+ getAgentWorkingOnThread,
5
+ getLeadAgent,
6
+ getMostRecentTaskInThread,
7
+ } from "../be/db";
8
+ import { resolveTemplate } from "../prompts/resolver";
9
+ import { bufferThreadMessage } from "./thread-buffer";
10
+ // Side-effect import: registers all Slack event templates in the in-memory registry
11
+ import "./templates";
12
+
13
+ const additiveSlack = process.env.ADDITIVE_SLACK === "true";
14
+
15
+ export function createAssistant(): Assistant {
16
+ return new Assistant({
17
+ threadStarted: async ({ say, setSuggestedPrompts, saveThreadContext }) => {
18
+ try {
19
+ await saveThreadContext();
20
+
21
+ const greetingResult = resolveTemplate("slack.assistant.greeting", {});
22
+ await say(greetingResult.text);
23
+
24
+ await setSuggestedPrompts({
25
+ title: "Try these:",
26
+ prompts: [
27
+ { title: "Check status", message: "What's the current status of all agents?" },
28
+ { title: "Assign a task", message: "Can you help me with..." },
29
+ { title: "List recent tasks", message: "Show me the most recent tasks" },
30
+ ],
31
+ });
32
+ } catch (error) {
33
+ console.error("[Slack] Assistant threadStarted error:", error);
34
+ }
35
+ },
36
+
37
+ threadContextChanged: async ({ saveThreadContext }) => {
38
+ await saveThreadContext();
39
+ },
40
+
41
+ userMessage: async ({ message, say, setStatus, setTitle, getThreadContext }) => {
42
+ try {
43
+ // Cast to access fields — Bolt's message union type is complex
44
+ const msg = message as unknown as Record<string, unknown>;
45
+ const threadTs = (msg.thread_ts as string) || message.ts;
46
+ const channelId = message.channel;
47
+ const messageText = (msg.text as string) || "";
48
+ const userId = (msg.user as string) || "";
49
+
50
+ // 1. Check if an agent is already working in this thread
51
+ const workingAgent = getAgentWorkingOnThread(channelId, threadTs);
52
+
53
+ if (workingAgent && workingAgent.status !== "offline") {
54
+ // Follow-up message → route to the same agent
55
+ if (additiveSlack) {
56
+ bufferThreadMessage(channelId, threadTs, messageText, userId, message.ts);
57
+ await setStatus("Queuing follow-up...");
58
+ return;
59
+ }
60
+
61
+ // Otherwise, create a follow-up task for the working agent
62
+ const latestTask = getMostRecentTaskInThread(channelId, threadTs);
63
+ createTaskExtended(messageText, {
64
+ agentId: workingAgent.id,
65
+ source: "slack",
66
+ slackChannelId: channelId,
67
+ slackThreadTs: threadTs,
68
+ slackUserId: userId,
69
+ parentTaskId: latestTask?.id,
70
+ });
71
+
72
+ await setStatus("Processing follow-up...");
73
+ return;
74
+ }
75
+
76
+ // 2. First message in thread — create new task for lead
77
+ await setStatus("Processing your request...");
78
+
79
+ if (messageText) {
80
+ const title = messageText.length > 50 ? `${messageText.slice(0, 47)}...` : messageText;
81
+ await setTitle(title);
82
+ }
83
+
84
+ // Optionally enrich with channel context
85
+ const ctx = await getThreadContext();
86
+ const channelContext =
87
+ ctx && typeof ctx === "object" && "channel_id" in ctx && ctx.channel_id
88
+ ? `\n\n[User is viewing channel <#${ctx.channel_id}>]`
89
+ : "";
90
+
91
+ const lead = getLeadAgent();
92
+ if (!lead) {
93
+ // No lead — still queue the task
94
+ createTaskExtended(messageText + channelContext, {
95
+ source: "slack",
96
+ slackChannelId: channelId,
97
+ slackThreadTs: threadTs,
98
+ slackUserId: userId,
99
+ });
100
+ const offlineResult = resolveTemplate("slack.assistant.offline", {});
101
+ await say(offlineResult.text);
102
+ return;
103
+ }
104
+
105
+ createTaskExtended(messageText + channelContext, {
106
+ agentId: lead.id,
107
+ source: "slack",
108
+ slackChannelId: channelId,
109
+ slackThreadTs: threadTs,
110
+ slackUserId: userId,
111
+ });
112
+ // setStatus shows typing indicator — watcher will post final result when done
113
+ } catch (error) {
114
+ console.error("[Slack] Assistant userMessage error:", error);
115
+ }
116
+ },
117
+ });
118
+ }