@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
@@ -0,0 +1,368 @@
1
+ /**
2
+ * GitLab Webhook Event Handlers
3
+ *
4
+ * Mirrors the pattern from src/github/handlers.ts:
5
+ * - Parses GitLab webhook payloads
6
+ * - Creates agent tasks via createTaskExtended()
7
+ * - Deduplicates events via in-memory TTL map
8
+ * - Detects bot mentions
9
+ */
10
+
11
+ import { createTaskExtended, failTask, findTaskByVcs, getAllAgents } from "../be/db";
12
+ import { resolveTemplate } from "../prompts/resolver";
13
+ import { GITLAB_BOT_NAME } from "./auth";
14
+ import { addGitLabNoteReaction, addGitLabReaction } from "./reactions";
15
+ // Side-effect import: registers all GitLab event templates in the in-memory registry
16
+ import "./templates";
17
+ import type { IssueEvent, MergeRequestEvent, NoteEvent, PipelineEvent } from "./types";
18
+
19
+ // ── Dedup cache (same pattern as GitHub) ──
20
+ const processedEvents = new Map<string, number>();
21
+ const DEDUP_TTL_MS = 60_000;
22
+
23
+ function isDuplicate(key: string): boolean {
24
+ const now = Date.now();
25
+ // Cleanup expired
26
+ for (const [k, ts] of processedEvents) {
27
+ if (now - ts > DEDUP_TTL_MS) processedEvents.delete(k);
28
+ }
29
+ if (processedEvents.has(key)) return true;
30
+ processedEvents.set(key, now);
31
+ return false;
32
+ }
33
+
34
+ // ── Helpers ──
35
+
36
+ function detectMention(text: string | null | undefined): boolean {
37
+ if (!text) return false;
38
+ return new RegExp(`@${GITLAB_BOT_NAME}\\b`, "i").test(text);
39
+ }
40
+
41
+ function extractMentionContext(text: string): string {
42
+ return text.replace(new RegExp(`@${GITLAB_BOT_NAME}\\b`, "gi"), "").trim();
43
+ }
44
+
45
+ function findLeadAgent() {
46
+ const agents = getAllAgents();
47
+ return (
48
+ agents.find((a) => a.role === "lead" && a.status === "idle") ??
49
+ agents.find((a) => a.role === "lead") ??
50
+ null
51
+ );
52
+ }
53
+
54
+ // ── Event Handlers ──
55
+
56
+ export async function handleMergeRequest(
57
+ event: MergeRequestEvent,
58
+ ): Promise<{ created: boolean; taskId?: string }> {
59
+ const { user, project, object_attributes: mr } = event;
60
+ const action = mr.action;
61
+ const repo = project.path_with_namespace;
62
+
63
+ console.log(`[GitLab] MR #${mr.iid} ${action} by ${user.username} in ${repo}`);
64
+
65
+ const dedupKey = `gitlab-mr-${repo}-${mr.iid}-${action}-${user.username}`;
66
+ if (isDuplicate(dedupKey)) {
67
+ console.log(`[GitLab] Skipping duplicate MR event`);
68
+ return { created: false };
69
+ }
70
+
71
+ const lead = findLeadAgent();
72
+
73
+ switch (action) {
74
+ case "open": {
75
+ // Check for bot mention in description
76
+ const hasMention = detectMention(mr.description);
77
+ if (!hasMention) {
78
+ console.log(`[GitLab] MR opened without bot mention, skipping`);
79
+ return { created: false };
80
+ }
81
+
82
+ const context = mr.description ? extractMentionContext(mr.description) : "";
83
+ const contextSection = context ? `Context: ${context}\n\n` : "";
84
+ const result = resolveTemplate("gitlab.merge_request.opened", {
85
+ mr_iid: mr.iid,
86
+ mr_title: mr.title,
87
+ repo,
88
+ username: user.username,
89
+ source_branch: mr.source_branch,
90
+ target_branch: mr.target_branch,
91
+ mr_url: mr.url,
92
+ context_section: contextSection,
93
+ });
94
+
95
+ if (result.skipped) {
96
+ return { created: false };
97
+ }
98
+
99
+ const task = createTaskExtended(result.text, {
100
+ agentId: lead?.id ?? null,
101
+ source: "gitlab",
102
+ vcsProvider: "gitlab",
103
+ taskType: "gitlab-mr",
104
+ vcsRepo: repo,
105
+ vcsEventType: "merge_request",
106
+ vcsNumber: mr.iid,
107
+ vcsAuthor: user.username,
108
+ vcsUrl: mr.url,
109
+ });
110
+
111
+ try {
112
+ await addGitLabReaction(repo, "mr", mr.iid, "eyes");
113
+ } catch {}
114
+
115
+ return { created: true, taskId: task.id };
116
+ }
117
+
118
+ case "close":
119
+ case "merge": {
120
+ // Cancel existing tasks for this MR
121
+ const existingTask = findTaskByVcs(repo, mr.iid);
122
+ if (existingTask) {
123
+ const reason = action === "merge" ? "MR was merged" : "MR was closed";
124
+ console.log(`[GitLab] Cancelling task ${existingTask.id} — ${reason}`);
125
+ failTask(existingTask.id, reason);
126
+ }
127
+ return { created: false };
128
+ }
129
+
130
+ case "update": {
131
+ // Check if there's an active task for this MR — if so, notify about the update
132
+ const task = findTaskByVcs(repo, mr.iid);
133
+ if (task) {
134
+ console.log(`[GitLab] MR #${mr.iid} updated, active task exists: ${task.id}`);
135
+ // Don't create a new task — the worker will see the changes
136
+ return { created: false };
137
+ }
138
+ return { created: false };
139
+ }
140
+
141
+ default:
142
+ console.log(`[GitLab] Ignoring MR action: ${action}`);
143
+ return { created: false };
144
+ }
145
+ }
146
+
147
+ export async function handleIssue(
148
+ event: IssueEvent,
149
+ ): Promise<{ created: boolean; taskId?: string }> {
150
+ const { user, project, object_attributes: issue } = event;
151
+ const action = issue.action;
152
+ const repo = project.path_with_namespace;
153
+
154
+ console.log(`[GitLab] Issue #${issue.iid} ${action} by ${user.username} in ${repo}`);
155
+
156
+ const dedupKey = `gitlab-issue-${repo}-${issue.iid}-${action}-${user.username}`;
157
+ if (isDuplicate(dedupKey)) {
158
+ return { created: false };
159
+ }
160
+
161
+ const lead = findLeadAgent();
162
+
163
+ switch (action) {
164
+ case "open": {
165
+ const hasMention = detectMention(issue.description);
166
+ if (!hasMention) {
167
+ // Check if bot is in assignees
168
+ const isBotAssigned = event.assignees?.some(
169
+ (a) => a.username.toLowerCase() === GITLAB_BOT_NAME.toLowerCase(),
170
+ );
171
+ if (!isBotAssigned) {
172
+ console.log(`[GitLab] Issue opened without bot mention/assignment, skipping`);
173
+ return { created: false };
174
+ }
175
+ }
176
+
177
+ const context = issue.description ? extractMentionContext(issue.description) : "";
178
+ const contextSection = context ? `Context: ${context}\n\n` : "";
179
+ const result = resolveTemplate("gitlab.issue.assigned", {
180
+ issue_iid: issue.iid,
181
+ issue_title: issue.title,
182
+ repo,
183
+ username: user.username,
184
+ issue_url: issue.url,
185
+ context_section: contextSection,
186
+ });
187
+
188
+ if (result.skipped) {
189
+ return { created: false };
190
+ }
191
+
192
+ const task = createTaskExtended(result.text, {
193
+ agentId: lead?.id ?? null,
194
+ source: "gitlab",
195
+ vcsProvider: "gitlab",
196
+ taskType: "gitlab-issue",
197
+ vcsRepo: repo,
198
+ vcsEventType: "issue",
199
+ vcsNumber: issue.iid,
200
+ vcsAuthor: user.username,
201
+ vcsUrl: issue.url,
202
+ });
203
+
204
+ try {
205
+ await addGitLabReaction(repo, "issue", issue.iid, "eyes");
206
+ } catch {}
207
+
208
+ return { created: true, taskId: task.id };
209
+ }
210
+
211
+ case "close": {
212
+ const existingTask = findTaskByVcs(repo, issue.iid);
213
+ if (existingTask) {
214
+ console.log(`[GitLab] Cancelling task ${existingTask.id} — issue closed`);
215
+ failTask(existingTask.id, "Issue was closed");
216
+ }
217
+ return { created: false };
218
+ }
219
+
220
+ default:
221
+ return { created: false };
222
+ }
223
+ }
224
+
225
+ export async function handleNote(event: NoteEvent): Promise<{ created: boolean; taskId?: string }> {
226
+ const { user, project, object_attributes: note } = event;
227
+ const repo = project.path_with_namespace;
228
+
229
+ // Only handle comments with bot mentions
230
+ if (!detectMention(note.note)) {
231
+ return { created: false };
232
+ }
233
+
234
+ console.log(`[GitLab] Note by ${user.username} in ${repo} (${note.noteable_type})`);
235
+
236
+ const dedupKey = `gitlab-note-${note.id}`;
237
+ if (isDuplicate(dedupKey)) {
238
+ return { created: false };
239
+ }
240
+
241
+ const lead = findLeadAgent();
242
+ const context = extractMentionContext(note.note);
243
+
244
+ // Determine the target entity (MR or issue)
245
+ let targetNumber: number | undefined;
246
+ let targetUrl: string;
247
+ let eventType: string;
248
+ let entityLabel: string;
249
+
250
+ if (note.noteable_type === "MergeRequest" && event.merge_request) {
251
+ targetNumber = event.merge_request.iid;
252
+ targetUrl = event.merge_request.url ?? note.url;
253
+ eventType = "note_on_mr";
254
+ entityLabel = `MR #${targetNumber}`;
255
+ } else if (note.noteable_type === "Issue" && event.issue) {
256
+ targetNumber = event.issue.iid;
257
+ targetUrl = event.issue.url ?? note.url;
258
+ eventType = "note_on_issue";
259
+ entityLabel = `Issue #${targetNumber}`;
260
+ } else {
261
+ console.log(`[GitLab] Ignoring note on ${note.noteable_type}`);
262
+ return { created: false };
263
+ }
264
+
265
+ // Check if there's already an active task for this entity
266
+ const existingTask = targetNumber ? findTaskByVcs(repo, targetNumber) : null;
267
+
268
+ const existingTaskNote = existingTask
269
+ ? `\n\n_Note: There's an active task (${existingTask.id}) for this ${entityLabel}._`
270
+ : "";
271
+
272
+ const noteResult = resolveTemplate("gitlab.comment.mentioned", {
273
+ entity_label: entityLabel,
274
+ username: user.username,
275
+ repo,
276
+ target_url: targetUrl,
277
+ context,
278
+ existing_task_note: existingTaskNote,
279
+ });
280
+
281
+ if (noteResult.skipped) {
282
+ return { created: false };
283
+ }
284
+
285
+ const task = createTaskExtended(noteResult.text, {
286
+ agentId: lead?.id ?? null,
287
+ source: "gitlab",
288
+ vcsProvider: "gitlab",
289
+ taskType: "gitlab-comment",
290
+ vcsRepo: repo,
291
+ vcsEventType: eventType,
292
+ vcsNumber: targetNumber,
293
+ vcsCommentId: note.id,
294
+ vcsAuthor: user.username,
295
+ vcsUrl: targetUrl,
296
+ parentTaskId: existingTask?.id,
297
+ });
298
+
299
+ try {
300
+ await addGitLabNoteReaction(
301
+ repo,
302
+ note.noteable_type === "MergeRequest" ? "mr" : "issue",
303
+ targetNumber!,
304
+ note.id,
305
+ "eyes",
306
+ );
307
+ } catch {}
308
+
309
+ return { created: true, taskId: task.id };
310
+ }
311
+
312
+ export async function handlePipeline(
313
+ event: PipelineEvent,
314
+ ): Promise<{ created: boolean; taskId?: string }> {
315
+ const { project, object_attributes: pipeline } = event;
316
+ const repo = project.path_with_namespace;
317
+
318
+ // Only handle failed pipelines that are associated with a merge request
319
+ if (pipeline.status !== "failed") {
320
+ return { created: false };
321
+ }
322
+
323
+ if (!event.merge_request) {
324
+ console.log(`[GitLab] Pipeline failed but no associated MR, skipping`);
325
+ return { created: false };
326
+ }
327
+
328
+ const mrIid = event.merge_request.iid;
329
+ const dedupKey = `gitlab-pipeline-${pipeline.id}`;
330
+ if (isDuplicate(dedupKey)) {
331
+ return { created: false };
332
+ }
333
+
334
+ // Only create task if there's already an active task for this MR
335
+ const existingTask = findTaskByVcs(repo, mrIid);
336
+ if (!existingTask) {
337
+ return { created: false };
338
+ }
339
+
340
+ const lead = findLeadAgent();
341
+ const pipelineResult = resolveTemplate("gitlab.pipeline.failed", {
342
+ pipeline_id: pipeline.id,
343
+ mr_iid: mrIid,
344
+ repo,
345
+ mr_title: event.merge_request.title,
346
+ mr_url: event.merge_request.url,
347
+ source_branch: event.merge_request.source_branch,
348
+ });
349
+
350
+ if (pipelineResult.skipped) {
351
+ return { created: false };
352
+ }
353
+
354
+ const task = createTaskExtended(pipelineResult.text, {
355
+ agentId: lead?.id ?? null,
356
+ source: "gitlab",
357
+ vcsProvider: "gitlab",
358
+ taskType: "gitlab-ci",
359
+ vcsRepo: repo,
360
+ vcsEventType: "pipeline",
361
+ vcsNumber: mrIid,
362
+ vcsAuthor: "",
363
+ vcsUrl: event.merge_request.url,
364
+ parentTaskId: existingTask.id,
365
+ });
366
+
367
+ return { created: true, taskId: task.id };
368
+ }
@@ -0,0 +1,19 @@
1
+ // GitLab Integration
2
+ export {
3
+ GITLAB_BOT_NAME,
4
+ getGitLabToken,
5
+ getGitLabUrl,
6
+ initGitLab,
7
+ isGitLabEnabled,
8
+ resetGitLab,
9
+ verifyGitLabWebhook,
10
+ } from "./auth";
11
+ export { handleIssue, handleMergeRequest, handleNote, handlePipeline } from "./handlers";
12
+ export { addGitLabNoteReaction, addGitLabReaction, postGitLabComment } from "./reactions";
13
+ export type {
14
+ GitLabWebhookEvent,
15
+ IssueEvent,
16
+ MergeRequestEvent,
17
+ NoteEvent,
18
+ PipelineEvent,
19
+ } from "./types";
@@ -0,0 +1,104 @@
1
+ /**
2
+ * GitLab API interactions — reactions (award emoji) and comments (notes).
3
+ * Uses raw fetch, no SDK.
4
+ */
5
+
6
+ import { getGitLabToken, getGitLabUrl } from "./auth";
7
+
8
+ function headers(): Record<string, string> {
9
+ const token = getGitLabToken();
10
+ if (!token) throw new Error("[GitLab] No API token configured");
11
+ return {
12
+ "PRIVATE-TOKEN": token,
13
+ "Content-Type": "application/json",
14
+ };
15
+ }
16
+
17
+ function apiBase(): string {
18
+ return `${getGitLabUrl()}/api/v4`;
19
+ }
20
+
21
+ /** Encode a project path (e.g. "group/project") for use in API URLs. */
22
+ function encodeProject(pathWithNamespace: string): string {
23
+ return encodeURIComponent(pathWithNamespace);
24
+ }
25
+
26
+ /**
27
+ * Add an award emoji (reaction) to a merge request or issue.
28
+ * GitLab calls reactions "award emoji".
29
+ * @see https://docs.gitlab.com/ee/api/award_emoji.html
30
+ */
31
+ export async function addGitLabReaction(
32
+ project: string,
33
+ entityType: "issue" | "mr",
34
+ iid: number,
35
+ emojiName: string,
36
+ ): Promise<void> {
37
+ const resourceType = entityType === "mr" ? "merge_requests" : "issues";
38
+ const url = `${apiBase()}/projects/${encodeProject(project)}/${resourceType}/${iid}/award_emoji`;
39
+ try {
40
+ const resp = await fetch(url, {
41
+ method: "POST",
42
+ headers: headers(),
43
+ body: JSON.stringify({ name: emojiName }),
44
+ });
45
+ if (!resp.ok) {
46
+ console.error(`[GitLab] Failed to add reaction: ${resp.status} ${await resp.text()}`);
47
+ }
48
+ } catch (err) {
49
+ console.error(`[GitLab] Error adding reaction:`, err);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Add an award emoji (reaction) to a specific note (comment).
55
+ * @see https://docs.gitlab.com/ee/api/award_emoji.html#award-a-new-emoji-on-a-comment
56
+ */
57
+ export async function addGitLabNoteReaction(
58
+ project: string,
59
+ entityType: "issue" | "mr",
60
+ iid: number,
61
+ noteId: number,
62
+ emojiName: string,
63
+ ): Promise<void> {
64
+ const resourceType = entityType === "mr" ? "merge_requests" : "issues";
65
+ const url = `${apiBase()}/projects/${encodeProject(project)}/${resourceType}/${iid}/notes/${noteId}/award_emoji`;
66
+ try {
67
+ const resp = await fetch(url, {
68
+ method: "POST",
69
+ headers: headers(),
70
+ body: JSON.stringify({ name: emojiName }),
71
+ });
72
+ if (!resp.ok) {
73
+ console.error(`[GitLab] Failed to add note reaction: ${resp.status} ${await resp.text()}`);
74
+ }
75
+ } catch (err) {
76
+ console.error(`[GitLab] Error adding note reaction:`, err);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Post a comment (note) on a merge request or issue.
82
+ * @see https://docs.gitlab.com/ee/api/notes.html
83
+ */
84
+ export async function postGitLabComment(
85
+ project: string,
86
+ entityType: "issue" | "mr",
87
+ iid: number,
88
+ body: string,
89
+ ): Promise<void> {
90
+ const resourceType = entityType === "mr" ? "merge_requests" : "issues";
91
+ const url = `${apiBase()}/projects/${encodeProject(project)}/${resourceType}/${iid}/notes`;
92
+ try {
93
+ const resp = await fetch(url, {
94
+ method: "POST",
95
+ headers: headers(),
96
+ body: JSON.stringify({ body }),
97
+ });
98
+ if (!resp.ok) {
99
+ console.error(`[GitLab] Failed to post comment: ${resp.status} ${await resp.text()}`);
100
+ }
101
+ } catch (err) {
102
+ console.error(`[GitLab] Error posting comment:`, err);
103
+ }
104
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * GitLab event prompt template definitions.
3
+ *
4
+ * Each template is registered at module load time via registerTemplate().
5
+ * Handlers import this module for the side-effect of registration.
6
+ *
7
+ * Template text uses {{variable}} syntax. The resolver interpolates variables
8
+ * and expands {{@template[id]}} references before returning the final text.
9
+ */
10
+
11
+ import { registerTemplate } from "../prompts/registry";
12
+
13
+ // ============================================================================
14
+ // Common building blocks (GitLab-specific)
15
+ // ============================================================================
16
+
17
+ registerTemplate({
18
+ eventType: "common.delegation_instruction.gitlab",
19
+ header: "",
20
+ defaultBody:
21
+ "\n\n**Delegation instruction:** As the lead agent, analyze this and decide whether to handle it yourself or delegate to a worker agent. Use `send-task` to delegate with clear instructions.",
22
+ variables: [],
23
+ category: "common",
24
+ });
25
+
26
+ registerTemplate({
27
+ eventType: "common.command_suggestions.gitlab_mr",
28
+ header: "",
29
+ defaultBody:
30
+ "Suggested commands: `/review-pr` to review the MR, `/implement-issue` to implement changes.",
31
+ variables: [],
32
+ category: "common",
33
+ });
34
+
35
+ registerTemplate({
36
+ eventType: "common.command_suggestions.gitlab_issue",
37
+ header: "",
38
+ defaultBody: "Suggested commands: `/implement-issue` to implement, `/close-issue` to close.",
39
+ variables: [],
40
+ category: "common",
41
+ });
42
+
43
+ // ============================================================================
44
+ // Merge Request events
45
+ // ============================================================================
46
+
47
+ registerTemplate({
48
+ eventType: "gitlab.merge_request.opened",
49
+ header: "[GitLab MR #{{mr_iid}}] {{mr_title}}",
50
+ defaultBody: `Repo: {{repo}}
51
+ Author: @{{username}}
52
+ Branch: {{source_branch}} \u2192 {{target_branch}}
53
+ URL: {{mr_url}}
54
+
55
+ {{context_section}}{{@template[common.command_suggestions.gitlab_mr]}}{{@template[common.delegation_instruction.gitlab]}}`,
56
+ variables: [
57
+ { name: "mr_iid", description: "Merge request IID" },
58
+ { name: "mr_title", description: "Merge request title" },
59
+ { name: "repo", description: "Project path with namespace" },
60
+ { name: "username", description: "Event sender username" },
61
+ { name: "source_branch", description: "Source branch name" },
62
+ { name: "target_branch", description: "Target branch name" },
63
+ { name: "mr_url", description: "Merge request URL" },
64
+ { name: "context_section", description: "Context section with description or empty string" },
65
+ ],
66
+ category: "event",
67
+ });
68
+
69
+ // ============================================================================
70
+ // Issue events
71
+ // ============================================================================
72
+
73
+ registerTemplate({
74
+ eventType: "gitlab.issue.assigned",
75
+ header: "[GitLab Issue #{{issue_iid}}] {{issue_title}}",
76
+ defaultBody: `Repo: {{repo}}
77
+ Author: @{{username}}
78
+ URL: {{issue_url}}
79
+
80
+ {{context_section}}{{@template[common.command_suggestions.gitlab_issue]}}{{@template[common.delegation_instruction.gitlab]}}`,
81
+ variables: [
82
+ { name: "issue_iid", description: "Issue IID" },
83
+ { name: "issue_title", description: "Issue title" },
84
+ { name: "repo", description: "Project path with namespace" },
85
+ { name: "username", description: "Event sender username" },
86
+ { name: "issue_url", description: "Issue URL" },
87
+ { name: "context_section", description: "Context section with description or empty string" },
88
+ ],
89
+ category: "event",
90
+ });
91
+
92
+ // ============================================================================
93
+ // Comment (Note) events
94
+ // ============================================================================
95
+
96
+ registerTemplate({
97
+ eventType: "gitlab.comment.mentioned",
98
+ header: "[GitLab Comment on {{entity_label}}] @{{username}} mentioned bot",
99
+ defaultBody: `Repo: {{repo}}
100
+ URL: {{target_url}}
101
+
102
+ Comment:
103
+ {{context}}{{existing_task_note}}{{@template[common.delegation_instruction.gitlab]}}`,
104
+ variables: [
105
+ { name: "entity_label", description: "Entity label (e.g. 'MR #1' or 'Issue #2')" },
106
+ { name: "username", description: "Comment author username" },
107
+ { name: "repo", description: "Project path with namespace" },
108
+ { name: "target_url", description: "Target entity URL" },
109
+ { name: "context", description: "Extracted mention context from comment" },
110
+ {
111
+ name: "existing_task_note",
112
+ description: "Note about existing active task, or empty string",
113
+ },
114
+ ],
115
+ category: "event",
116
+ });
117
+
118
+ // ============================================================================
119
+ // Pipeline events
120
+ // ============================================================================
121
+
122
+ registerTemplate({
123
+ eventType: "gitlab.pipeline.failed",
124
+ header: "[GitLab CI Failed] Pipeline #{{pipeline_id}} failed for MR #{{mr_iid}}",
125
+ defaultBody: `Repo: {{repo}}
126
+ MR: {{mr_title}}
127
+ URL: {{mr_url}}
128
+ Branch: {{source_branch}}
129
+
130
+ The CI pipeline has failed. Please investigate and fix the issues.{{@template[common.delegation_instruction.gitlab]}}`,
131
+ variables: [
132
+ { name: "pipeline_id", description: "Pipeline ID" },
133
+ { name: "mr_iid", description: "Merge request IID" },
134
+ { name: "repo", description: "Project path with namespace" },
135
+ { name: "mr_title", description: "Merge request title" },
136
+ { name: "mr_url", description: "Merge request URL" },
137
+ { name: "source_branch", description: "Source branch name" },
138
+ ],
139
+ category: "event",
140
+ });