@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,103 @@
1
+ import { z } from "zod";
2
+ import type { ExecutorMeta } from "../../types";
3
+ import { BaseExecutor, type ExecutorResult } from "./base";
4
+
5
+ // ─── Schemas ────────────────────────────────────────────────
6
+
7
+ export const ScriptConfigSchema = z.object({
8
+ runtime: z.enum(["bash", "ts", "python"]),
9
+ script: z.string(),
10
+ args: z.array(z.string()).optional(),
11
+ timeout: z.number().int().min(1000).default(30_000),
12
+ cwd: z.string().optional(),
13
+ });
14
+
15
+ export const ScriptOutputSchema = z.object({
16
+ exitCode: z.number(),
17
+ stdout: z.string(),
18
+ stderr: z.string(),
19
+ });
20
+
21
+ // ─── Executor ───────────────────────────────────────────────
22
+
23
+ const DEFAULT_TIMEOUT = 30_000;
24
+
25
+ export class ScriptExecutor extends BaseExecutor<
26
+ typeof ScriptConfigSchema,
27
+ typeof ScriptOutputSchema
28
+ > {
29
+ readonly type = "script";
30
+ readonly mode = "instant" as const;
31
+ readonly configSchema = ScriptConfigSchema;
32
+ readonly outputSchema = ScriptOutputSchema;
33
+
34
+ protected async execute(
35
+ config: z.infer<typeof ScriptConfigSchema>,
36
+ _context: Readonly<Record<string, unknown>>,
37
+ _meta: ExecutorMeta,
38
+ ): Promise<ExecutorResult<z.infer<typeof ScriptOutputSchema>>> {
39
+ const timeoutMs = config.timeout ?? DEFAULT_TIMEOUT;
40
+
41
+ try {
42
+ const result = await Promise.race([this.runScript(config), this.timeoutPromise(timeoutMs)]);
43
+
44
+ return {
45
+ status: "success",
46
+ output: result,
47
+ nextPort: result.exitCode === 0 ? "success" : "failure",
48
+ };
49
+ } catch (err) {
50
+ return {
51
+ status: "failed",
52
+ error: `Script execution error: ${err instanceof Error ? err.message : String(err)}`,
53
+ };
54
+ }
55
+ }
56
+
57
+ private async runScript(config: z.infer<typeof ScriptConfigSchema>): Promise<{
58
+ exitCode: number;
59
+ stdout: string;
60
+ stderr: string;
61
+ }> {
62
+ const { runtime, script, args = [], cwd } = config;
63
+ let cmd: string[];
64
+
65
+ switch (runtime) {
66
+ case "bash":
67
+ cmd = ["bash", "-c", script, ...args];
68
+ break;
69
+ case "ts":
70
+ cmd = ["bun", "-e", script, ...args];
71
+ break;
72
+ case "python":
73
+ cmd = ["python3", "-c", script, ...args];
74
+ break;
75
+ }
76
+
77
+ const proc = Bun.spawn(cmd, {
78
+ stdout: "pipe",
79
+ stderr: "pipe",
80
+ cwd: cwd ?? undefined,
81
+ });
82
+
83
+ const [stdout, stderr, exitCode] = await Promise.all([
84
+ new Response(proc.stdout).text(),
85
+ new Response(proc.stderr).text(),
86
+ proc.exited,
87
+ ]);
88
+
89
+ return { exitCode, stdout: stdout.trimEnd(), stderr: stderr.trimEnd() };
90
+ }
91
+
92
+ private timeoutPromise(ms: number): Promise<never> {
93
+ return new Promise((_resolve, reject) => {
94
+ const id = globalThis.setTimeout(() => {
95
+ reject(new Error(`Script timed out after ${ms}ms`));
96
+ }, ms);
97
+ // Ensure the timer doesn't keep the process alive
98
+ if (typeof id === "object" && "unref" in id) {
99
+ (id as NodeJS.Timeout).unref();
100
+ }
101
+ });
102
+ }
103
+ }
@@ -0,0 +1,215 @@
1
+ import { z } from "zod";
2
+ import type { ExecutorMeta } from "../../types";
3
+ import { BaseExecutor, type ExecutorResult } from "./base";
4
+
5
+ // ─── Schemas ────────────────────────────────────────────────
6
+
7
+ export const ValidateConfigSchema = z.object({
8
+ targetNodeId: z.string(),
9
+ prompt: z.string().optional(),
10
+ schema: z.record(z.string(), z.unknown()).optional(),
11
+ });
12
+
13
+ export const ValidateOutputSchema = z.object({
14
+ pass: z.boolean(),
15
+ reasoning: z.string(),
16
+ confidence: z.number().min(0).max(1),
17
+ });
18
+
19
+ // ─── Executor ───────────────────────────────────────────────
20
+
21
+ export class ValidateExecutor extends BaseExecutor<
22
+ typeof ValidateConfigSchema,
23
+ typeof ValidateOutputSchema
24
+ > {
25
+ readonly type = "validate";
26
+ readonly mode = "instant" as const;
27
+ readonly configSchema = ValidateConfigSchema;
28
+ readonly outputSchema = ValidateOutputSchema;
29
+
30
+ protected async execute(
31
+ config: z.infer<typeof ValidateConfigSchema>,
32
+ context: Readonly<Record<string, unknown>>,
33
+ _meta: ExecutorMeta,
34
+ ): Promise<ExecutorResult<z.infer<typeof ValidateOutputSchema>>> {
35
+ const targetOutput = context[config.targetNodeId];
36
+ if (targetOutput === undefined) {
37
+ return {
38
+ status: "success",
39
+ output: {
40
+ pass: false,
41
+ reasoning: `Target node "${config.targetNodeId}" has no output in context`,
42
+ confidence: 1,
43
+ },
44
+ nextPort: "fail",
45
+ };
46
+ }
47
+
48
+ // Schema-based validation (no LLM call needed)
49
+ if (config.schema) {
50
+ return this.validateWithSchema(targetOutput, config.schema);
51
+ }
52
+
53
+ // Prompt-based validation (uses LLM)
54
+ if (config.prompt) {
55
+ return this.validateWithLlm(targetOutput, config.prompt, context);
56
+ }
57
+
58
+ // Neither schema nor prompt — just check that output exists
59
+ return {
60
+ status: "success",
61
+ output: { pass: true, reasoning: "Target node output exists", confidence: 1 },
62
+ nextPort: "pass",
63
+ };
64
+ }
65
+
66
+ private validateWithSchema(
67
+ targetOutput: unknown,
68
+ schema: Record<string, unknown>,
69
+ ): ExecutorResult<z.infer<typeof ValidateOutputSchema>> {
70
+ try {
71
+ // Use JSON Schema validation via Zod's loose parsing:
72
+ // Convert the JSON Schema to a basic check. For full JSON Schema support
73
+ // we'd need ajv, but for now we do structural matching.
74
+ const errors = validateJsonSchemaBasic(targetOutput, schema);
75
+ if (errors.length === 0) {
76
+ return {
77
+ status: "success",
78
+ output: { pass: true, reasoning: "Output matches schema", confidence: 1 },
79
+ nextPort: "pass",
80
+ };
81
+ }
82
+ return {
83
+ status: "success",
84
+ output: {
85
+ pass: false,
86
+ reasoning: `Schema validation failed: ${errors.join("; ")}`,
87
+ confidence: 1,
88
+ },
89
+ nextPort: "fail",
90
+ };
91
+ } catch (err) {
92
+ return {
93
+ status: "success",
94
+ output: {
95
+ pass: false,
96
+ reasoning: `Schema validation error: ${err instanceof Error ? err.message : String(err)}`,
97
+ confidence: 0.5,
98
+ },
99
+ nextPort: "fail",
100
+ };
101
+ }
102
+ }
103
+
104
+ private async validateWithLlm(
105
+ targetOutput: unknown,
106
+ prompt: string,
107
+ context: Readonly<Record<string, unknown>>,
108
+ ): Promise<ExecutorResult<z.infer<typeof ValidateOutputSchema>>> {
109
+ const interpolatedPrompt = this.deps.interpolate(prompt, context as Record<string, unknown>);
110
+ const outputStr =
111
+ typeof targetOutput === "string" ? targetOutput : JSON.stringify(targetOutput);
112
+
113
+ try {
114
+ const { createOpenAI } = await import("@ai-sdk/openai");
115
+ const { generateObject, jsonSchema } = await import("ai");
116
+
117
+ const openrouter = createOpenAI({
118
+ baseURL: "https://openrouter.ai/api/v1",
119
+ apiKey: process.env.OPENROUTER_API_KEY,
120
+ });
121
+
122
+ const { object } = await generateObject({
123
+ model: openrouter("google/gemini-2.0-flash-001"),
124
+ schema: jsonSchema({
125
+ type: "object",
126
+ properties: {
127
+ pass: { type: "boolean" },
128
+ reasoning: { type: "string" },
129
+ confidence: { type: "number", minimum: 0, maximum: 1 },
130
+ },
131
+ required: ["pass", "reasoning", "confidence"],
132
+ }),
133
+ prompt: `Evaluate the following output against the validation criteria.
134
+
135
+ Criteria: ${interpolatedPrompt}
136
+
137
+ Output to validate:
138
+ ${outputStr}
139
+
140
+ Respond with pass (boolean), reasoning (string), and confidence (0-1).`,
141
+ });
142
+
143
+ const result = object as { pass: boolean; reasoning: string; confidence: number };
144
+ return {
145
+ status: "success",
146
+ output: result,
147
+ nextPort: result.pass ? "pass" : "fail",
148
+ };
149
+ } catch (err) {
150
+ return {
151
+ status: "success",
152
+ output: {
153
+ pass: false,
154
+ reasoning: `LLM validation failed: ${err instanceof Error ? err.message : String(err)}`,
155
+ confidence: 0,
156
+ },
157
+ nextPort: "fail",
158
+ };
159
+ }
160
+ }
161
+ }
162
+
163
+ // ─── Basic JSON Schema Validator ────────────────────────────
164
+
165
+ function validateJsonSchemaBasic(value: unknown, schema: Record<string, unknown>): string[] {
166
+ const errors: string[] = [];
167
+
168
+ if (schema.type) {
169
+ const expectedType = schema.type as string;
170
+ if (expectedType === "object") {
171
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
172
+ errors.push(`Expected object, got ${Array.isArray(value) ? "array" : typeof value}`);
173
+ return errors;
174
+ }
175
+ // Check properties with const/enum constraints
176
+ if (schema.properties && typeof schema.properties === "object") {
177
+ const props = schema.properties as Record<string, Record<string, unknown>>;
178
+ const obj = value as Record<string, unknown>;
179
+ for (const [key, propSchema] of Object.entries(props)) {
180
+ if ("const" in propSchema && obj[key] !== propSchema.const) {
181
+ errors.push(
182
+ `Property "${key}": expected const ${JSON.stringify(propSchema.const)}, got ${JSON.stringify(obj[key])}`,
183
+ );
184
+ }
185
+ if ("enum" in propSchema && Array.isArray(propSchema.enum)) {
186
+ if (!propSchema.enum.includes(obj[key])) {
187
+ errors.push(
188
+ `Property "${key}": expected one of ${JSON.stringify(propSchema.enum)}, got ${JSON.stringify(obj[key])}`,
189
+ );
190
+ }
191
+ }
192
+ }
193
+ }
194
+ // Check required fields
195
+ if (Array.isArray(schema.required)) {
196
+ const obj = value as Record<string, unknown>;
197
+ for (const key of schema.required as string[]) {
198
+ if (!(key in obj)) {
199
+ errors.push(`Missing required property "${key}"`);
200
+ }
201
+ }
202
+ }
203
+ } else if (expectedType === "string" && typeof value !== "string") {
204
+ errors.push(`Expected string, got ${typeof value}`);
205
+ } else if (expectedType === "number" && typeof value !== "number") {
206
+ errors.push(`Expected number, got ${typeof value}`);
207
+ } else if (expectedType === "boolean" && typeof value !== "boolean") {
208
+ errors.push(`Expected boolean, got ${typeof value}`);
209
+ } else if (expectedType === "array" && !Array.isArray(value)) {
210
+ errors.push(`Expected array, got ${typeof value}`);
211
+ }
212
+ }
213
+
214
+ return errors;
215
+ }
@@ -0,0 +1,58 @@
1
+ import { z } from "zod";
2
+ import type { ExecutorMeta } from "../../types";
3
+ import { BaseExecutor, type ExecutorResult } from "./base";
4
+
5
+ // ─── Schemas ────────────────────────────────────────────────
6
+
7
+ export const VcsConfigSchema = z.object({
8
+ action: z.enum(["create-issue", "create-pr", "comment"]),
9
+ provider: z.enum(["github", "gitlab"]),
10
+ repo: z.string(),
11
+ title: z.string().optional(),
12
+ body: z.string().optional(),
13
+ branch: z.string().optional(),
14
+ baseBranch: z.string().optional(),
15
+ issueNumber: z.number().optional(),
16
+ prNumber: z.number().optional(),
17
+ });
18
+
19
+ export const VcsOutputSchema = z.object({
20
+ url: z.string(),
21
+ id: z.union([z.string(), z.number()]),
22
+ });
23
+
24
+ // ─── Executor ───────────────────────────────────────────────
25
+
26
+ export class VcsExecutor extends BaseExecutor<typeof VcsConfigSchema, typeof VcsOutputSchema> {
27
+ readonly type = "vcs";
28
+ readonly mode = "instant" as const;
29
+ readonly configSchema = VcsConfigSchema;
30
+ readonly outputSchema = VcsOutputSchema;
31
+
32
+ protected async execute(
33
+ config: z.infer<typeof VcsConfigSchema>,
34
+ context: Readonly<Record<string, unknown>>,
35
+ _meta: ExecutorMeta,
36
+ ): Promise<ExecutorResult<z.infer<typeof VcsOutputSchema>>> {
37
+ // Stub implementation — validate config and return mock output.
38
+ // Real GitHub/GitLab integration will be added in a follow-up.
39
+ const title = config.title
40
+ ? this.deps.interpolate(config.title, context as Record<string, unknown>)
41
+ : "";
42
+ const body = config.body
43
+ ? this.deps.interpolate(config.body, context as Record<string, unknown>)
44
+ : "";
45
+
46
+ console.log(
47
+ `[vcs] Stub — ${config.action} on ${config.provider}/${config.repo}: title="${title}" body="${body.slice(0, 80)}"`,
48
+ );
49
+
50
+ const mockId = `stub-${Date.now()}`;
51
+ const mockUrl = `https://${config.provider}.com/${config.repo}/${config.action}/${mockId}`;
52
+
53
+ return {
54
+ status: "success",
55
+ output: { url: mockUrl, id: mockId },
56
+ };
57
+ }
58
+ }
@@ -0,0 +1,61 @@
1
+ export { findEntryNodes, getSuccessors } from "./definition";
2
+ export { startWorkflowExecution } from "./engine";
3
+ export { workflowEventBus } from "./event-bus";
4
+ export { recoverIncompleteRuns } from "./recovery";
5
+ export { retryFailedRun, setupWorkflowResumeListener } from "./resume";
6
+ export { startRetryPoller, stopRetryPoller } from "./retry-poller";
7
+ export { interpolate } from "./template";
8
+ export { instantiateTemplate, validateTemplateVariables } from "./templates";
9
+ export { handleScheduleTrigger, handleWebhookTrigger } from "./triggers";
10
+ export { snapshotWorkflow } from "./version";
11
+
12
+ import * as db from "../be/db";
13
+ import { workflowEventBus } from "./event-bus";
14
+ import type { ExecutorRegistry } from "./executors/registry";
15
+ import { createExecutorRegistry } from "./executors/registry";
16
+ import { recoverIncompleteRuns } from "./recovery";
17
+ import { setupWorkflowResumeListener } from "./resume";
18
+ import { startRetryPoller } from "./retry-poller";
19
+ import { interpolate } from "./template";
20
+
21
+ // ─── Module-level singleton ────────────────────────────────
22
+
23
+ let _registry: ExecutorRegistry | null = null;
24
+
25
+ /**
26
+ * Get the executor registry singleton.
27
+ * Throws if called before `initWorkflows()`.
28
+ */
29
+ export function getExecutorRegistry(): ExecutorRegistry {
30
+ if (!_registry) {
31
+ throw new Error("Workflow engine not initialized — call initWorkflows() first");
32
+ }
33
+ return _registry;
34
+ }
35
+
36
+ /**
37
+ * Initialize the workflow engine:
38
+ * 1. Create executor registry with all built-in executors
39
+ * 2. Wire up event bus listeners for task lifecycle resume
40
+ * 3. Recover incomplete runs from previous server lifecycle
41
+ * 4. Start the retry poller for failed steps with pending retries
42
+ */
43
+ export function initWorkflows(): void {
44
+ // 1. Create the executor registry singleton
45
+ _registry = createExecutorRegistry({
46
+ db,
47
+ eventBus: workflowEventBus,
48
+ interpolate: (template, ctx) => interpolate(template, ctx).result,
49
+ });
50
+
51
+ // 2. Wire up resume listener (task.completed / task.failed / task.cancelled)
52
+ setupWorkflowResumeListener(workflowEventBus, _registry);
53
+
54
+ // 3. Recover incomplete runs (running + waiting) from previous lifecycle
55
+ recoverIncompleteRuns(_registry).catch((err) => {
56
+ console.error("[workflows] Failed to recover incomplete runs on startup:", err);
57
+ });
58
+
59
+ // 4. Start retry poller for failed steps with nextRetryAt
60
+ startRetryPoller(_registry);
61
+ }
@@ -0,0 +1,46 @@
1
+ import { getSwarmConfigs } from "../be/db";
2
+
3
+ /**
4
+ * Resolve workflow input values.
5
+ *
6
+ * Patterns:
7
+ * - `${ENV_VAR}` -> process.env[ENV_VAR]
8
+ * - `secret.NAME` -> look up in DB config store (global scope, isSecret=true)
9
+ * - literal string -> pass through
10
+ */
11
+ export function resolveInputs(input: Record<string, string>): Record<string, string> {
12
+ const resolved: Record<string, string> = {};
13
+
14
+ for (const [key, value] of Object.entries(input)) {
15
+ resolved[key] = resolveValue(value);
16
+ }
17
+
18
+ return resolved;
19
+ }
20
+
21
+ function resolveValue(value: string): string {
22
+ // Env var reference: ${MY_VAR}
23
+ const envMatch = /^\$\{(.+)\}$/.exec(value);
24
+ if (envMatch?.[1]) {
25
+ const envName = envMatch[1];
26
+ const envValue = process.env[envName];
27
+ if (envValue === undefined) {
28
+ throw new Error(`Environment variable "${envName}" is not set`);
29
+ }
30
+ return envValue;
31
+ }
32
+
33
+ // Secret reference: secret.NAME
34
+ if (value.startsWith("secret.")) {
35
+ const secretName = value.slice("secret.".length);
36
+ const configs = getSwarmConfigs({ scope: "global", key: secretName });
37
+ const secretConfig = configs.find((c) => c.isSecret);
38
+ if (!secretConfig) {
39
+ throw new Error(`Secret "${secretName}" not found in config store`);
40
+ }
41
+ return secretConfig.value;
42
+ }
43
+
44
+ // Literal
45
+ return value;
46
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Minimal hand-rolled JSON Schema validator.
3
+ *
4
+ * Supports the subset needed for workflow I/O schemas:
5
+ * - `type`: "object", "string", "number", "boolean", "array"
6
+ * - `required`: array of required property names
7
+ * - `properties`: map of property name → schema (recursive)
8
+ *
9
+ * Returns an array of validation error strings (empty = valid).
10
+ */
11
+ export function validateJsonSchema(schema: Record<string, unknown>, data: unknown): string[] {
12
+ const errors: string[] = [];
13
+ validate(schema, data, "", errors);
14
+ return errors;
15
+ }
16
+
17
+ function validate(
18
+ schema: Record<string, unknown>,
19
+ data: unknown,
20
+ path: string,
21
+ errors: string[],
22
+ ): void {
23
+ const prefix = path || "root";
24
+
25
+ // Type check
26
+ if (schema.type !== undefined) {
27
+ const expected = schema.type as string;
28
+ if (!matchesType(expected, data)) {
29
+ errors.push(`${prefix}: expected type "${expected}", got ${typeOf(data)}`);
30
+ return; // No point checking properties of wrong type
31
+ }
32
+ }
33
+
34
+ // Required fields (only for objects)
35
+ if (Array.isArray(schema.required) && typeof data === "object" && data !== null) {
36
+ const obj = data as Record<string, unknown>;
37
+ for (const key of schema.required as string[]) {
38
+ if (!(key in obj)) {
39
+ errors.push(`${prefix}: missing required property "${key}"`);
40
+ }
41
+ }
42
+ }
43
+
44
+ // Enum check
45
+ if (Array.isArray(schema.enum)) {
46
+ const allowed = schema.enum as unknown[];
47
+ if (!allowed.some((v) => JSON.stringify(v) === JSON.stringify(data))) {
48
+ errors.push(
49
+ `${prefix}: value ${JSON.stringify(data)} not in enum [${allowed.map((v) => JSON.stringify(v)).join(", ")}]`,
50
+ );
51
+ return;
52
+ }
53
+ }
54
+
55
+ // Const check
56
+ if ("const" in schema) {
57
+ if (JSON.stringify(data) !== JSON.stringify(schema.const)) {
58
+ errors.push(
59
+ `${prefix}: value ${JSON.stringify(data)} does not match const ${JSON.stringify(schema.const)}`,
60
+ );
61
+ return;
62
+ }
63
+ }
64
+
65
+ // Recursive property validation (only for objects)
66
+ if (
67
+ schema.properties !== undefined &&
68
+ typeof schema.properties === "object" &&
69
+ schema.properties !== null &&
70
+ typeof data === "object" &&
71
+ data !== null
72
+ ) {
73
+ const props = schema.properties as Record<string, Record<string, unknown>>;
74
+ const obj = data as Record<string, unknown>;
75
+ for (const [key, subSchema] of Object.entries(props)) {
76
+ if (key in obj) {
77
+ validate(subSchema, obj[key], path ? `${path}.${key}` : key, errors);
78
+ }
79
+ }
80
+ }
81
+
82
+ // Items validation (for arrays)
83
+ if (
84
+ schema.items !== undefined &&
85
+ typeof schema.items === "object" &&
86
+ schema.items !== null &&
87
+ Array.isArray(data)
88
+ ) {
89
+ const itemSchema = schema.items as Record<string, unknown>;
90
+ for (let i = 0; i < data.length; i++) {
91
+ validate(itemSchema, data[i], `${prefix}[${i}]`, errors);
92
+ }
93
+ }
94
+ }
95
+
96
+ function matchesType(expected: string, data: unknown): boolean {
97
+ switch (expected) {
98
+ case "string":
99
+ return typeof data === "string";
100
+ case "number":
101
+ return typeof data === "number";
102
+ case "boolean":
103
+ return typeof data === "boolean";
104
+ case "array":
105
+ return Array.isArray(data);
106
+ case "object":
107
+ return typeof data === "object" && data !== null && !Array.isArray(data);
108
+ default:
109
+ return true; // Unknown type — don't block
110
+ }
111
+ }
112
+
113
+ function typeOf(data: unknown): string {
114
+ if (data === null) return "null";
115
+ if (data === undefined) return "undefined";
116
+ if (Array.isArray(data)) return "array";
117
+ return typeof data;
118
+ }