@desplega.ai/agent-swarm 1.20.0 → 1.49.0

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 (810) hide show
  1. package/.claude/settings.json +84 -0
  2. package/.claude/settings.local.json +3 -1
  3. package/.entire/settings.json +4 -0
  4. package/.env.docker.example +40 -23
  5. package/.env.example +39 -1
  6. package/.github/ISSUE_TEMPLATE/bug_report.yml +78 -0
  7. package/.github/ISSUE_TEMPLATE/community-template.yml +77 -0
  8. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  9. package/.github/ISSUE_TEMPLATE/feature_request.yml +60 -0
  10. package/.github/PULL_REQUEST_TEMPLATE/community-template.md +29 -0
  11. package/.github/workflows/ci.yml +3 -27
  12. package/.github/workflows/docker-and-deploy.yml +20 -5
  13. package/.github/workflows/merge-gate.yml +233 -0
  14. package/.opencode/plugins/entire.ts +133 -0
  15. package/.superset/config.json +6 -0
  16. package/.wts-setup.ts +103 -34
  17. package/CHANGELOG.md +447 -0
  18. package/CLAUDE.md +422 -5
  19. package/CONTRIBUTING.md +46 -1
  20. package/DEPLOYMENT.md +26 -9
  21. package/Dockerfile +15 -7
  22. package/Dockerfile.worker +99 -67
  23. package/MCP.md +452 -17
  24. package/README.md +271 -169
  25. package/api-entrypoint.sh +56 -0
  26. package/depot.json +1 -0
  27. package/docker-compose.example.yml +194 -3
  28. package/docker-compose.local.yml +119 -0
  29. package/docker-entrypoint.sh +393 -113
  30. package/docs-site/app/api/search/route.ts +4 -0
  31. package/docs-site/app/docs/[[...slug]]/page.tsx +87 -0
  32. package/docs-site/app/docs/layout.tsx +12 -0
  33. package/docs-site/app/globals.css +24 -0
  34. package/docs-site/app/layout.config.tsx +34 -0
  35. package/docs-site/app/layout.tsx +119 -0
  36. package/docs-site/app/llms-full.txt/route.ts +11 -0
  37. package/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts +24 -0
  38. package/docs-site/app/llms.txt/route.ts +8 -0
  39. package/docs-site/app/page.tsx +5 -0
  40. package/docs-site/app/robots.ts +13 -0
  41. package/docs-site/app/sitemap.ts +37 -0
  42. package/docs-site/components/api-page.client.tsx +4 -0
  43. package/docs-site/components/api-page.tsx +7 -0
  44. package/docs-site/components/mdx/mermaid.tsx +55 -0
  45. package/docs-site/content/docs/(documentation)/architecture/agents.mdx +117 -0
  46. package/docs-site/content/docs/(documentation)/architecture/hooks.mdx +77 -0
  47. package/docs-site/content/docs/(documentation)/architecture/memory.mdx +96 -0
  48. package/docs-site/content/docs/(documentation)/architecture/meta.json +4 -0
  49. package/docs-site/content/docs/(documentation)/architecture/overview.mdx +172 -0
  50. package/docs-site/content/docs/(documentation)/concepts/epics.mdx +98 -0
  51. package/docs-site/content/docs/(documentation)/concepts/meta.json +4 -0
  52. package/docs-site/content/docs/(documentation)/concepts/scheduling.mdx +136 -0
  53. package/docs-site/content/docs/(documentation)/concepts/services.mdx +104 -0
  54. package/docs-site/content/docs/(documentation)/concepts/task-lifecycle.mdx +148 -0
  55. package/docs-site/content/docs/(documentation)/concepts/workflows.mdx +209 -0
  56. package/docs-site/content/docs/(documentation)/contributing.mdx +158 -0
  57. package/docs-site/content/docs/(documentation)/getting-started.mdx +157 -0
  58. package/docs-site/content/docs/(documentation)/guides/agentmail-integration.mdx +79 -0
  59. package/docs-site/content/docs/(documentation)/guides/deployment.mdx +171 -0
  60. package/docs-site/content/docs/(documentation)/guides/github-integration.mdx +81 -0
  61. package/docs-site/content/docs/(documentation)/guides/gitlab-integration.mdx +93 -0
  62. package/docs-site/content/docs/(documentation)/guides/linear-integration.mdx +98 -0
  63. package/docs-site/content/docs/(documentation)/guides/meta.json +13 -0
  64. package/docs-site/content/docs/(documentation)/guides/sentry-integration.mdx +52 -0
  65. package/docs-site/content/docs/(documentation)/guides/slack-integration.mdx +179 -0
  66. package/docs-site/content/docs/(documentation)/guides/x402-payments.mdx +154 -0
  67. package/docs-site/content/docs/(documentation)/index.mdx +65 -0
  68. package/docs-site/content/docs/(documentation)/meta.json +19 -0
  69. package/docs-site/content/docs/(documentation)/reference/cli.mdx +241 -0
  70. package/docs-site/content/docs/(documentation)/reference/environment-variables.mdx +205 -0
  71. package/docs-site/content/docs/(documentation)/reference/mcp-tools.mdx +449 -0
  72. package/docs-site/content/docs/(documentation)/reference/meta.json +4 -0
  73. package/docs-site/content/docs/api-reference/active-sessions.mdx +9 -0
  74. package/docs-site/content/docs/api-reference/agents.mdx +9 -0
  75. package/docs-site/content/docs/api-reference/channels.mdx +9 -0
  76. package/docs-site/content/docs/api-reference/config.mdx +9 -0
  77. package/docs-site/content/docs/api-reference/debug.mdx +9 -0
  78. package/docs-site/content/docs/api-reference/ecosystem.mdx +9 -0
  79. package/docs-site/content/docs/api-reference/epics.mdx +9 -0
  80. package/docs-site/content/docs/api-reference/index.mdx +32 -0
  81. package/docs-site/content/docs/api-reference/memory.mdx +9 -0
  82. package/docs-site/content/docs/api-reference/meta.json +25 -0
  83. package/docs-site/content/docs/api-reference/poll.mdx +9 -0
  84. package/docs-site/content/docs/api-reference/repos.mdx +9 -0
  85. package/docs-site/content/docs/api-reference/schedules.mdx +9 -0
  86. package/docs-site/content/docs/api-reference/session-data.mdx +9 -0
  87. package/docs-site/content/docs/api-reference/stats.mdx +9 -0
  88. package/docs-site/content/docs/api-reference/tasks.mdx +9 -0
  89. package/docs-site/content/docs/api-reference/trackers.mdx +9 -0
  90. package/docs-site/content/docs/api-reference/webhooks.mdx +9 -0
  91. package/docs-site/content/docs/api-reference/workflows.mdx +9 -0
  92. package/docs-site/content/docs/meta.json +3 -0
  93. package/docs-site/lib/get-llm-text.ts +10 -0
  94. package/docs-site/lib/openapi.ts +23 -0
  95. package/docs-site/lib/source.ts +8 -0
  96. package/docs-site/mdx-components.tsx +13 -0
  97. package/docs-site/next.config.mjs +29 -0
  98. package/docs-site/package.json +35 -0
  99. package/docs-site/pnpm-lock.yaml +5407 -0
  100. package/docs-site/postcss.config.mjs +8 -0
  101. package/docs-site/scripts/generate-docs.ts +171 -0
  102. package/docs-site/source.config.ts +17 -0
  103. package/docs-site/tsconfig.json +46 -0
  104. package/ecosystem.config.cjs +4 -4
  105. package/landing/next.config.ts +14 -0
  106. package/landing/package.json +31 -0
  107. package/landing/pnpm-lock.yaml +1091 -0
  108. package/landing/postcss.config.mjs +8 -0
  109. package/landing/public/apple-touch-icon.png +0 -0
  110. package/landing/public/favicon.ico +0 -0
  111. package/landing/public/logo.png +0 -0
  112. package/landing/public/og-image.png +0 -0
  113. package/landing/public/omghost-desplega.svg +30 -0
  114. package/landing/public/omghost-openfort.svg +9 -0
  115. package/landing/src/app/actions/waitlist.ts +25 -0
  116. package/landing/src/app/blog/openfort-hackathon/page.tsx +863 -0
  117. package/landing/src/app/blog/page.tsx +162 -0
  118. package/landing/src/app/blog/swarm-metrics/page.tsx +685 -0
  119. package/landing/src/app/examples/page.tsx +174 -0
  120. package/landing/src/app/examples/x402/page.tsx +456 -0
  121. package/landing/src/app/globals.css +122 -0
  122. package/landing/src/app/layout.tsx +134 -0
  123. package/landing/src/app/page.tsx +27 -0
  124. package/landing/src/app/robots.ts +13 -0
  125. package/landing/src/app/sitemap.ts +44 -0
  126. package/landing/src/components/architecture.tsx +163 -0
  127. package/landing/src/components/cta.tsx +52 -0
  128. package/landing/src/components/features.tsx +160 -0
  129. package/landing/src/components/footer.tsx +100 -0
  130. package/landing/src/components/hero.tsx +217 -0
  131. package/landing/src/components/how-it-works.tsx +165 -0
  132. package/landing/src/components/navbar.tsx +147 -0
  133. package/landing/src/components/waitlist.tsx +110 -0
  134. package/landing/src/components/why-choose.tsx +149 -0
  135. package/landing/src/components/workshops.tsx +328 -0
  136. package/landing/src/lib/utils.ts +6 -0
  137. package/landing/tsconfig.json +41 -0
  138. package/misc/transcripts/2026-03-09-pi-mono-e2e-verification.md +154 -0
  139. package/new-ui/CLAUDE.md +92 -0
  140. package/new-ui/README.md +73 -0
  141. package/new-ui/biome.json +42 -0
  142. package/new-ui/components.json +21 -0
  143. package/new-ui/index.html +25 -0
  144. package/new-ui/package.json +49 -0
  145. package/new-ui/pnpm-lock.yaml +4845 -0
  146. package/new-ui/public/logo.png +0 -0
  147. package/new-ui/src/api/client.ts +814 -0
  148. package/new-ui/src/api/hooks/index.ts +64 -0
  149. package/new-ui/src/api/hooks/use-agents.ts +58 -0
  150. package/new-ui/src/api/hooks/use-channels.ts +115 -0
  151. package/new-ui/src/api/hooks/use-config-api.ts +46 -0
  152. package/new-ui/src/api/hooks/use-costs.ts +122 -0
  153. package/new-ui/src/api/hooks/use-db-query.ts +29 -0
  154. package/new-ui/src/api/hooks/use-epics.ts +75 -0
  155. package/new-ui/src/api/hooks/use-repos.ts +61 -0
  156. package/new-ui/src/api/hooks/use-schedules.ts +81 -0
  157. package/new-ui/src/api/hooks/use-services.ts +16 -0
  158. package/new-ui/src/api/hooks/use-stats.ts +27 -0
  159. package/new-ui/src/api/hooks/use-tasks.ts +89 -0
  160. package/new-ui/src/api/hooks/use-workflows.ts +109 -0
  161. package/{ui/src/types/api.ts → new-ui/src/api/types.ts} +236 -10
  162. package/new-ui/src/app/App.tsx +13 -0
  163. package/new-ui/src/app/providers.tsx +32 -0
  164. package/new-ui/src/app/router.tsx +52 -0
  165. package/new-ui/src/components/layout/app-header.tsx +47 -0
  166. package/new-ui/src/components/layout/app-sidebar.tsx +128 -0
  167. package/new-ui/src/components/layout/breadcrumbs.tsx +57 -0
  168. package/new-ui/src/components/layout/config-guard.tsx +22 -0
  169. package/new-ui/src/components/layout/root-layout.tsx +40 -0
  170. package/new-ui/src/components/layout/swarm-switcher.tsx +85 -0
  171. package/new-ui/src/components/shared/command-menu.tsx +131 -0
  172. package/new-ui/src/components/shared/data-grid.tsx +141 -0
  173. package/new-ui/src/components/shared/empty-state.tsx +24 -0
  174. package/new-ui/src/components/shared/error-boundary.tsx +72 -0
  175. package/new-ui/src/components/shared/json-viewer.tsx +47 -0
  176. package/new-ui/src/components/shared/name-connection-modal.tsx +99 -0
  177. package/new-ui/src/components/shared/page-skeleton.tsx +16 -0
  178. package/new-ui/src/components/shared/session-log-viewer.tsx +364 -0
  179. package/new-ui/src/components/shared/stats-bar.tsx +132 -0
  180. package/new-ui/src/components/shared/status-badge.tsx +131 -0
  181. package/new-ui/src/components/shared/usage-summary.tsx +179 -0
  182. package/new-ui/src/components/ui/alert-dialog.tsx +176 -0
  183. package/new-ui/src/components/ui/alert.tsx +60 -0
  184. package/new-ui/src/components/ui/avatar.tsx +96 -0
  185. package/new-ui/src/components/ui/badge.tsx +46 -0
  186. package/new-ui/src/components/ui/button.tsx +62 -0
  187. package/new-ui/src/components/ui/card.tsx +75 -0
  188. package/new-ui/src/components/ui/command.tsx +160 -0
  189. package/new-ui/src/components/ui/dialog.tsx +143 -0
  190. package/new-ui/src/components/ui/dropdown-menu.tsx +226 -0
  191. package/new-ui/src/components/ui/input.tsx +21 -0
  192. package/new-ui/src/components/ui/label.tsx +19 -0
  193. package/new-ui/src/components/ui/progress.tsx +26 -0
  194. package/new-ui/src/components/ui/scroll-area.tsx +54 -0
  195. package/new-ui/src/components/ui/select.tsx +175 -0
  196. package/new-ui/src/components/ui/separator.tsx +28 -0
  197. package/new-ui/src/components/ui/sheet.tsx +132 -0
  198. package/new-ui/src/components/ui/sidebar.tsx +691 -0
  199. package/new-ui/src/components/ui/skeleton.tsx +13 -0
  200. package/new-ui/src/components/ui/sonner.tsx +35 -0
  201. package/new-ui/src/components/ui/switch.tsx +33 -0
  202. package/new-ui/src/components/ui/table.tsx +92 -0
  203. package/new-ui/src/components/ui/tabs.tsx +79 -0
  204. package/new-ui/src/components/ui/textarea.tsx +18 -0
  205. package/new-ui/src/components/ui/tooltip.tsx +51 -0
  206. package/new-ui/src/components/workflows/action-node.tsx +53 -0
  207. package/new-ui/src/components/workflows/condition-node.tsx +50 -0
  208. package/new-ui/src/components/workflows/graph-utils.ts +124 -0
  209. package/new-ui/src/components/workflows/json-tree.tsx +189 -0
  210. package/new-ui/src/components/workflows/node-styles.ts +10 -0
  211. package/new-ui/src/components/workflows/step-detail-sheet.tsx +87 -0
  212. package/new-ui/src/components/workflows/trigger-node.tsx +41 -0
  213. package/new-ui/src/components/workflows/workflow-graph.tsx +65 -0
  214. package/{ui/src/hooks/useAutoScroll.ts → new-ui/src/hooks/use-auto-scroll.ts} +0 -1
  215. package/new-ui/src/hooks/use-config.ts +203 -0
  216. package/new-ui/src/hooks/use-keyboard-shortcuts.ts +41 -0
  217. package/new-ui/src/hooks/use-mobile.ts +19 -0
  218. package/new-ui/src/hooks/use-theme.ts +60 -0
  219. package/new-ui/src/lib/config.ts +188 -0
  220. package/new-ui/src/lib/slugs.ts +71 -0
  221. package/{ui → new-ui}/src/lib/utils.ts +32 -0
  222. package/new-ui/src/main.tsx +11 -0
  223. package/new-ui/src/pages/agents/[id]/page.tsx +492 -0
  224. package/new-ui/src/pages/agents/page.tsx +134 -0
  225. package/new-ui/src/pages/chat/page.tsx +674 -0
  226. package/new-ui/src/pages/config/page.tsx +1109 -0
  227. package/new-ui/src/pages/dashboard/page.tsx +454 -0
  228. package/new-ui/src/pages/debug/page.tsx +275 -0
  229. package/new-ui/src/pages/epics/[id]/page.tsx +809 -0
  230. package/new-ui/src/pages/epics/page.tsx +321 -0
  231. package/new-ui/src/pages/not-found/page.tsx +18 -0
  232. package/new-ui/src/pages/repos/page.tsx +369 -0
  233. package/new-ui/src/pages/schedules/[id]/page.tsx +664 -0
  234. package/new-ui/src/pages/schedules/page.tsx +477 -0
  235. package/new-ui/src/pages/services/page.tsx +128 -0
  236. package/new-ui/src/pages/tasks/[id]/page.tsx +670 -0
  237. package/new-ui/src/pages/tasks/page.tsx +592 -0
  238. package/new-ui/src/pages/usage/page.tsx +195 -0
  239. package/new-ui/src/pages/workflow-runs/[id]/page.tsx +363 -0
  240. package/new-ui/src/pages/workflows/[id]/page.tsx +417 -0
  241. package/new-ui/src/pages/workflows/page.tsx +266 -0
  242. package/new-ui/src/styles/ag-grid.css +36 -0
  243. package/new-ui/src/styles/globals.css +213 -0
  244. package/new-ui/test-results/.last-run.json +4 -0
  245. package/{ui/tsconfig.json → new-ui/tsconfig.app.json} +7 -4
  246. package/new-ui/tsconfig.json +4 -0
  247. package/new-ui/tsconfig.node.json +26 -0
  248. package/new-ui/vercel.json +4 -0
  249. package/new-ui/vite.config.ts +28 -0
  250. package/openapi.json +4436 -0
  251. package/package.json +31 -7
  252. package/plugin/build-pi-skills.ts +233 -0
  253. package/plugin/commands/close-issue.md +7 -3
  254. package/plugin/commands/create-pr.md +18 -12
  255. package/plugin/commands/implement-issue.md +7 -3
  256. package/plugin/commands/respond-github.md +8 -4
  257. package/plugin/commands/review-pr.md +44 -10
  258. package/plugin/commands/start-leader.md +1 -3
  259. package/plugin/commands/start-worker.md +1 -3
  260. package/plugin/commands/work-on-task.md +22 -3
  261. package/plugin/pi-skills/close-issue/SKILL.md +90 -0
  262. package/plugin/pi-skills/create-pr/SKILL.md +99 -0
  263. package/plugin/pi-skills/implement-issue/SKILL.md +135 -0
  264. package/plugin/pi-skills/investigate-sentry-issue/SKILL.md +138 -0
  265. package/plugin/pi-skills/respond-github/SKILL.md +98 -0
  266. package/plugin/pi-skills/review-offered-task/SKILL.md +45 -0
  267. package/plugin/pi-skills/review-pr/SKILL.md +261 -0
  268. package/plugin/pi-skills/start-leader/SKILL.md +121 -0
  269. package/plugin/pi-skills/start-worker/SKILL.md +60 -0
  270. package/plugin/pi-skills/swarm-chat/SKILL.md +82 -0
  271. package/plugin/pi-skills/todos/SKILL.md +66 -0
  272. package/plugin/pi-skills/work-on-task/SKILL.md +65 -0
  273. package/plugin/skills/artifacts/examples/approval-flow.ts +34 -0
  274. package/plugin/skills/artifacts/examples/hono-dashboard.ts +31 -0
  275. package/plugin/skills/artifacts/examples/multi-artifact.ts +20 -0
  276. package/plugin/skills/artifacts/examples/static-report.sh +17 -0
  277. package/plugin/skills/artifacts/skill.md +71 -0
  278. package/prek.toml +75 -0
  279. package/scripts/check-db-boundary.sh +60 -0
  280. package/scripts/e2e-docker-provider.ts +820 -0
  281. package/scripts/e2e-io-schemas-test.ts +807 -0
  282. package/scripts/e2e-provider-test.ts +220 -0
  283. package/scripts/e2e-workflow-redesign.sh +229 -0
  284. package/scripts/e2e-workflow-test.sh +285 -0
  285. package/scripts/e2e-workflow-test.ts +857 -0
  286. package/scripts/generate-openapi.ts +26 -0
  287. package/scripts/measure-tool-tokens.ts +118 -0
  288. package/scripts/x402-e2e-test.ts +195 -0
  289. package/scripts/x402-test-server.ts +236 -0
  290. package/scripts/x402-testnet-e2e.ts +668 -0
  291. package/slack-manifest.json +17 -0
  292. package/src/agentmail/app.ts +65 -0
  293. package/src/agentmail/handlers.ts +207 -0
  294. package/src/agentmail/index.ts +9 -0
  295. package/src/agentmail/types.ts +51 -0
  296. package/src/artifact-sdk/browser-sdk.ts +30 -0
  297. package/src/artifact-sdk/index.ts +2 -0
  298. package/src/artifact-sdk/localtunnel.d.ts +20 -0
  299. package/src/artifact-sdk/port.ts +12 -0
  300. package/src/artifact-sdk/server.ts +156 -0
  301. package/src/artifact-sdk/tunnel.ts +19 -0
  302. package/src/be/chunking.ts +193 -0
  303. package/src/be/db-queries/oauth.ts +90 -0
  304. package/src/be/db-queries/tracker.ts +182 -0
  305. package/src/be/db.ts +2729 -770
  306. package/src/be/embedding.ts +80 -0
  307. package/src/be/migrations/001_initial.sql +409 -0
  308. package/src/be/migrations/002_one_time_schedules.sql +59 -0
  309. package/src/be/migrations/003_workflows.sql +51 -0
  310. package/src/be/migrations/004_workflow_source.sql +81 -0
  311. package/src/be/migrations/005_epic_next_steps.sql +2 -0
  312. package/src/be/migrations/006_vcs_provider.sql +94 -0
  313. package/src/be/migrations/007_task_dir.sql +2 -0
  314. package/src/be/migrations/008_workflow_redesign.sql +85 -0
  315. package/src/be/migrations/009_tracker_integration.sql +144 -0
  316. package/src/be/migrations/010_step_diagnostics.sql +1 -0
  317. package/src/be/migrations/011_step_next_port.sql +1 -0
  318. package/src/be/migrations/012_trigger_schema.sql +1 -0
  319. package/src/be/migrations/013_task_output_schema.sql +2 -0
  320. package/src/be/migrations/runner.ts +188 -0
  321. package/src/cli.tsx +231 -299
  322. package/src/commands/artifact.ts +241 -0
  323. package/src/commands/onboard/compose-generator.ts +169 -0
  324. package/src/commands/onboard/env-generator.ts +79 -0
  325. package/src/commands/onboard/manifest.ts +37 -0
  326. package/src/commands/onboard/presets.ts +85 -0
  327. package/src/commands/onboard/service-names.ts +47 -0
  328. package/src/commands/onboard/steps/core-credentials.tsx +111 -0
  329. package/src/commands/onboard/steps/custom-templates.tsx +168 -0
  330. package/src/commands/onboard/steps/generate.tsx +154 -0
  331. package/src/commands/onboard/steps/harness-credentials.tsx +195 -0
  332. package/src/commands/onboard/steps/harness.tsx +21 -0
  333. package/src/commands/onboard/steps/health-check.tsx +171 -0
  334. package/src/commands/onboard/steps/integration-github.tsx +105 -0
  335. package/src/commands/onboard/steps/integration-gitlab.tsx +79 -0
  336. package/src/commands/onboard/steps/integration-menu.tsx +58 -0
  337. package/src/commands/onboard/steps/integration-sentry.tsx +79 -0
  338. package/src/commands/onboard/steps/integration-slack.tsx +165 -0
  339. package/src/commands/onboard/steps/post-connect.tsx +145 -0
  340. package/src/commands/onboard/steps/post-dashboard.tsx +34 -0
  341. package/src/commands/onboard/steps/post-task.tsx +103 -0
  342. package/src/commands/onboard/steps/prereq-check.tsx +178 -0
  343. package/src/commands/onboard/steps/review.tsx +82 -0
  344. package/src/commands/onboard/steps/start.tsx +97 -0
  345. package/src/commands/onboard/templates.ts +34 -0
  346. package/src/commands/onboard/types.ts +259 -0
  347. package/src/commands/onboard.tsx +425 -0
  348. package/src/commands/runner.ts +1376 -559
  349. package/src/commands/setup.tsx +23 -38
  350. package/src/commands/shared/client-config.ts +41 -0
  351. package/src/github/app.ts +8 -0
  352. package/src/github/handlers.ts +93 -75
  353. package/src/github/index.ts +1 -0
  354. package/src/github/types.ts +1 -0
  355. package/src/gitlab/auth.ts +63 -0
  356. package/src/gitlab/handlers.ts +327 -0
  357. package/src/gitlab/index.ts +19 -0
  358. package/src/gitlab/reactions.ts +104 -0
  359. package/src/gitlab/types.ts +130 -0
  360. package/src/heartbeat/heartbeat.ts +425 -0
  361. package/src/heartbeat/index.ts +1 -0
  362. package/src/hooks/hook.ts +555 -4
  363. package/src/hooks/tool-loop-detection.test.ts +158 -0
  364. package/src/hooks/tool-loop-detection.ts +167 -0
  365. package/src/http/active-sessions.ts +172 -0
  366. package/src/http/agents.ts +328 -0
  367. package/src/http/config.ts +191 -0
  368. package/src/http/core.ts +309 -0
  369. package/src/http/db-query.ts +91 -0
  370. package/src/http/ecosystem.ts +63 -0
  371. package/src/http/epics.ts +460 -0
  372. package/src/http/index.ts +213 -0
  373. package/src/http/mcp.ts +77 -0
  374. package/src/http/memory.ts +168 -0
  375. package/src/http/openapi.ts +109 -0
  376. package/src/http/poll.ts +178 -0
  377. package/src/http/repos.ts +195 -0
  378. package/src/http/route-def.ts +123 -0
  379. package/src/http/schedules.ts +391 -0
  380. package/src/http/session-data.ts +241 -0
  381. package/src/http/stats.ts +174 -0
  382. package/src/http/tasks.ts +468 -0
  383. package/src/http/trackers/index.ts +10 -0
  384. package/src/http/trackers/linear.ts +187 -0
  385. package/src/http/types.ts +12 -0
  386. package/src/http/utils.ts +87 -0
  387. package/src/http/webhooks.ts +432 -0
  388. package/src/http/workflows.ts +522 -0
  389. package/src/http.ts +1 -1890
  390. package/src/linear/README.md +65 -0
  391. package/src/linear/app.ts +48 -0
  392. package/src/linear/client.ts +18 -0
  393. package/src/linear/index.ts +1 -0
  394. package/src/linear/oauth.ts +35 -0
  395. package/src/linear/outbound.ts +212 -0
  396. package/src/linear/sync.ts +543 -0
  397. package/src/linear/types.ts +7 -0
  398. package/src/linear/webhook.ts +104 -0
  399. package/src/oauth/README.md +66 -0
  400. package/src/oauth/index.ts +6 -0
  401. package/src/oauth/wrapper.ts +204 -0
  402. package/src/prompts/base-prompt.ts +366 -24
  403. package/src/prompts/defaults.ts +196 -0
  404. package/src/providers/claude-adapter.ts +429 -0
  405. package/src/providers/index.ts +24 -0
  406. package/src/providers/pi-mono-adapter.ts +442 -0
  407. package/src/providers/pi-mono-extension.ts +620 -0
  408. package/src/providers/pi-mono-mcp-client.ts +124 -0
  409. package/src/providers/types.ts +75 -0
  410. package/src/scheduler/scheduler.test.ts +2 -0
  411. package/src/scheduler/scheduler.ts +186 -29
  412. package/src/server.ts +82 -6
  413. package/src/slack/HEURISTICS.md +105 -0
  414. package/src/slack/actions.ts +133 -0
  415. package/src/slack/app.ts +7 -0
  416. package/src/slack/assistant.ts +115 -0
  417. package/src/slack/blocks.ts +233 -0
  418. package/src/slack/commands.ts +31 -17
  419. package/src/slack/files.ts +1 -1
  420. package/src/slack/handlers.test.ts +114 -1
  421. package/src/slack/handlers.ts +212 -52
  422. package/src/slack/responses.ts +120 -67
  423. package/src/slack/router.ts +17 -99
  424. package/src/slack/thread-buffer.ts +213 -0
  425. package/src/slack/watcher.ts +119 -4
  426. package/src/tests/agent-activity.test.ts +247 -0
  427. package/src/tests/agentmail-filters.test.ts +97 -0
  428. package/src/tests/artifact-sdk.test.ts +800 -0
  429. package/src/tests/base-prompt.test.ts +264 -0
  430. package/src/tests/build-pi-skills.test.ts +127 -0
  431. package/src/tests/claude-adapter.test.ts +126 -0
  432. package/src/tests/context-versioning.test.ts +425 -0
  433. package/src/tests/db-queries-oauth.test.ts +197 -0
  434. package/src/tests/db-queries-tracker.test.ts +230 -0
  435. package/src/tests/epics.test.ts +3 -3
  436. package/src/tests/error-tracker.test.ts +368 -0
  437. package/src/tests/fetch-resolved-env.test.ts +167 -0
  438. package/src/tests/generate-default-claude-md.test.ts +9 -1
  439. package/src/tests/generate-identity-templates.test.ts +124 -0
  440. package/src/tests/gitlab-auth.test.ts +109 -0
  441. package/src/tests/gitlab-handlers.test.ts +691 -0
  442. package/src/tests/gitlab-vcs-db.test.ts +177 -0
  443. package/src/tests/heartbeat.test.ts +363 -0
  444. package/src/tests/http-api-integration.test.ts +1698 -0
  445. package/src/tests/linear-outbound-sync.test.ts +200 -0
  446. package/src/tests/linear-webhook.test.ts +402 -0
  447. package/src/tests/match-route.test.ts +187 -0
  448. package/src/tests/memory.test.ts +737 -0
  449. package/src/tests/migration-runner-regressions.test.ts +86 -0
  450. package/src/tests/model-control.test.ts +338 -0
  451. package/src/tests/oauth-wrapper.test.ts +147 -0
  452. package/src/tests/onboard-compose.test.ts +138 -0
  453. package/src/tests/onboard-env.test.ts +174 -0
  454. package/src/tests/onboard-manifest.test.ts +137 -0
  455. package/src/tests/pi-mono-adapter.test.ts +234 -0
  456. package/src/tests/progress-dedup.test.ts +98 -0
  457. package/src/tests/provider-adapter.test.ts +122 -0
  458. package/src/tests/provider-command-format.test.ts +98 -0
  459. package/src/tests/reload-config.test.ts +170 -0
  460. package/src/tests/runner-polling-api.test.ts +25 -20
  461. package/src/tests/scheduled-tasks.test.ts +104 -0
  462. package/src/tests/scheduler-backoff.test.ts +166 -0
  463. package/src/tests/self-improvement.test.ts +540 -0
  464. package/src/tests/session-attach.test.ts +536 -0
  465. package/src/tests/session-costs.test.ts +267 -1
  466. package/src/tests/slack-actions.test.ts +133 -0
  467. package/src/tests/slack-assistant.test.ts +136 -0
  468. package/src/tests/slack-blocks.test.ts +246 -0
  469. package/src/tests/slack-metadata-inheritance.test.ts +243 -0
  470. package/src/tests/slack-queue-offline.test.ts +174 -0
  471. package/src/tests/slack-router.test.ts +181 -0
  472. package/src/tests/slack-thread-buffer.test.ts +305 -0
  473. package/src/tests/slack-thread-followups.test.ts +298 -0
  474. package/src/tests/slack-watcher.test.ts +101 -0
  475. package/src/tests/structured-output.test.ts +311 -0
  476. package/src/tests/swarm-repos.test.ts +198 -0
  477. package/src/tests/task-cancellation.test.ts +6 -4
  478. package/src/tests/task-working-dir.test.ts +176 -0
  479. package/src/tests/template-fetch.test.ts +490 -0
  480. package/src/tests/tool-annotations.test.ts +371 -0
  481. package/src/tests/tracker-tools.test.ts +184 -0
  482. package/src/tests/update-profile-api.test.ts +143 -3
  483. package/src/tests/validation-adapters.test.ts +86 -0
  484. package/src/tests/vcs-provider.test.ts +27 -0
  485. package/src/tests/workflow-agent-task.test.ts +196 -0
  486. package/src/tests/workflow-async-v2.test.ts +386 -0
  487. package/src/tests/workflow-convergence.test.ts +541 -0
  488. package/src/tests/workflow-definition-validation.test.ts +290 -0
  489. package/src/tests/workflow-engine-v2.test.ts +691 -0
  490. package/src/tests/workflow-executors.test.ts +736 -0
  491. package/src/tests/workflow-http-v2.test.ts +599 -0
  492. package/src/tests/workflow-integration-io.test.ts +902 -0
  493. package/src/tests/workflow-io-schemas.test.ts +624 -0
  494. package/src/tests/workflow-registry.test.ts +592 -0
  495. package/src/tests/workflow-retry-v2.test.ts +401 -0
  496. package/src/tests/workflow-retry-validation.test.ts +282 -0
  497. package/src/tests/workflow-template.test.ts +288 -0
  498. package/src/tests/workflow-trigger-schema.test.ts +359 -0
  499. package/src/tests/workflow-triggers-v2.test.ts +264 -0
  500. package/src/tests/workflow-versions.test.ts +208 -0
  501. package/src/tests/x402-client.test.ts +117 -0
  502. package/src/tests/x402-config.test.ts +182 -0
  503. package/src/tests/x402-spending-tracker.test.ts +185 -0
  504. package/src/tools/cancel-task.ts +2 -0
  505. package/src/tools/context-diff.ts +171 -0
  506. package/src/tools/context-history.ts +138 -0
  507. package/src/tools/create-channel.ts +1 -0
  508. package/src/tools/db-query.ts +78 -0
  509. package/src/tools/delete-channel.ts +132 -0
  510. package/src/tools/epics/assign-task-to-epic.ts +1 -0
  511. package/src/tools/epics/create-epic.ts +3 -2
  512. package/src/tools/epics/delete-epic.ts +2 -0
  513. package/src/tools/epics/get-epic-details.ts +2 -0
  514. package/src/tools/epics/list-epics.ts +2 -0
  515. package/src/tools/epics/unassign-task-from-epic.ts +1 -0
  516. package/src/tools/epics/update-epic.ts +7 -4
  517. package/src/tools/get-swarm.ts +2 -0
  518. package/src/tools/get-task-details.ts +2 -0
  519. package/src/tools/get-tasks.ts +27 -1
  520. package/src/tools/inject-learning.ts +106 -0
  521. package/src/tools/join-swarm.ts +17 -7
  522. package/src/tools/list-channels.ts +2 -0
  523. package/src/tools/list-services.ts +2 -0
  524. package/src/tools/memory-get.ts +56 -0
  525. package/src/tools/memory-search.ts +131 -0
  526. package/src/tools/my-agent-info.ts +2 -0
  527. package/src/tools/poll-task.ts +2 -20
  528. package/src/tools/post-message.ts +1 -0
  529. package/src/tools/read-messages.ts +2 -0
  530. package/src/tools/register-agentmail-inbox.ts +166 -0
  531. package/src/tools/register-service.ts +2 -0
  532. package/src/tools/schedules/create-schedule.ts +134 -24
  533. package/src/tools/schedules/delete-schedule.ts +2 -0
  534. package/src/tools/schedules/list-schedules.ts +20 -4
  535. package/src/tools/schedules/run-schedule-now.ts +1 -0
  536. package/src/tools/schedules/update-schedule.ts +49 -17
  537. package/src/tools/send-task.ts +132 -10
  538. package/src/tools/slack-download-file.ts +4 -2
  539. package/src/tools/slack-list-channels.ts +2 -0
  540. package/src/tools/slack-post.ts +2 -0
  541. package/src/tools/slack-read.ts +2 -0
  542. package/src/tools/slack-reply.ts +2 -0
  543. package/src/tools/slack-upload-file.ts +2 -0
  544. package/src/tools/store-progress.ts +187 -4
  545. package/src/tools/swarm-config/delete-config.ts +87 -0
  546. package/src/tools/swarm-config/get-config.ts +108 -0
  547. package/src/tools/swarm-config/index.ts +4 -0
  548. package/src/tools/swarm-config/list-config.ts +99 -0
  549. package/src/tools/swarm-config/set-config.ts +118 -0
  550. package/src/tools/task-action.ts +30 -5
  551. package/src/tools/task-dedup.ts +97 -0
  552. package/src/tools/tool-config.ts +117 -0
  553. package/src/tools/tracker/index.ts +6 -0
  554. package/src/tools/tracker/tracker-link-epic.ts +64 -0
  555. package/src/tools/tracker/tracker-link-task.ts +64 -0
  556. package/src/tools/tracker/tracker-map-agent.ts +57 -0
  557. package/src/tools/tracker/tracker-status.ts +56 -0
  558. package/src/tools/tracker/tracker-sync-status.ts +42 -0
  559. package/src/tools/tracker/tracker-unlink.ts +41 -0
  560. package/src/tools/unregister-service.ts +2 -0
  561. package/src/tools/update-profile.ts +93 -10
  562. package/src/tools/update-service-status.ts +2 -0
  563. package/src/tools/utils.ts +10 -1
  564. package/src/tools/workflows/create-workflow.ts +111 -0
  565. package/src/tools/workflows/delete-workflow.ts +42 -0
  566. package/src/tools/workflows/get-workflow-run.ts +59 -0
  567. package/src/tools/workflows/get-workflow.ts +53 -0
  568. package/src/tools/workflows/index.ts +9 -0
  569. package/src/tools/workflows/list-workflow-runs.ts +48 -0
  570. package/src/tools/workflows/list-workflows.ts +42 -0
  571. package/src/tools/workflows/retry-workflow-run.ts +40 -0
  572. package/src/tools/workflows/trigger-workflow.ts +96 -0
  573. package/src/tools/workflows/update-workflow.ts +118 -0
  574. package/src/tracker/types.ts +51 -0
  575. package/src/types.ts +477 -14
  576. package/src/utils/credentials.test.ts +156 -0
  577. package/src/utils/credentials.ts +50 -0
  578. package/src/utils/error-tracker.ts +190 -0
  579. package/src/vcs/index.ts +15 -0
  580. package/src/vcs/types.ts +5 -0
  581. package/src/workflows/checkpoint.ts +121 -0
  582. package/src/workflows/cooldown.ts +28 -0
  583. package/src/workflows/definition.ts +217 -0
  584. package/src/workflows/engine.ts +554 -0
  585. package/src/workflows/event-bus.ts +29 -0
  586. package/src/workflows/executors/agent-task.ts +92 -0
  587. package/src/workflows/executors/base.ts +86 -0
  588. package/src/workflows/executors/code-match.ts +88 -0
  589. package/src/workflows/executors/index.ts +16 -0
  590. package/src/workflows/executors/notify.ts +93 -0
  591. package/src/workflows/executors/property-match.ts +104 -0
  592. package/src/workflows/executors/raw-llm.ts +83 -0
  593. package/src/workflows/executors/registry.ts +76 -0
  594. package/src/workflows/executors/script.ts +103 -0
  595. package/src/workflows/executors/validate.ts +215 -0
  596. package/src/workflows/executors/vcs.ts +58 -0
  597. package/src/workflows/index.ts +61 -0
  598. package/src/workflows/input.ts +46 -0
  599. package/src/workflows/json-schema-validator.ts +118 -0
  600. package/src/workflows/recovery.ts +139 -0
  601. package/src/workflows/resume.ts +143 -0
  602. package/src/workflows/retry-poller.ts +216 -0
  603. package/src/workflows/template.ts +74 -0
  604. package/src/workflows/templates.ts +86 -0
  605. package/src/workflows/triggers.ts +95 -0
  606. package/src/workflows/validation.ts +104 -0
  607. package/src/workflows/version.ts +42 -0
  608. package/src/x402/cli.ts +140 -0
  609. package/src/x402/client.ts +192 -0
  610. package/src/x402/config.ts +131 -0
  611. package/src/x402/index.ts +37 -0
  612. package/src/x402/openfort-signer.ts +83 -0
  613. package/src/x402/spending-tracker.ts +109 -0
  614. package/templates/community/.gitkeep +0 -0
  615. package/templates/official/coder/CLAUDE.md +49 -0
  616. package/templates/official/coder/IDENTITY.md +28 -0
  617. package/templates/official/coder/SOUL.md +43 -0
  618. package/templates/official/coder/TOOLS.md +40 -0
  619. package/templates/official/coder/config.json +23 -0
  620. package/templates/official/coder/start-up.sh +23 -0
  621. package/templates/official/content-reviewer/CLAUDE.md +68 -0
  622. package/templates/official/content-reviewer/IDENTITY.md +28 -0
  623. package/templates/official/content-reviewer/SOUL.md +44 -0
  624. package/templates/official/content-reviewer/TOOLS.md +37 -0
  625. package/templates/official/content-reviewer/config.json +23 -0
  626. package/templates/official/content-reviewer/start-up.sh +23 -0
  627. package/templates/official/content-strategist/CLAUDE.md +63 -0
  628. package/templates/official/content-strategist/IDENTITY.md +33 -0
  629. package/templates/official/content-strategist/SOUL.md +48 -0
  630. package/templates/official/content-strategist/TOOLS.md +47 -0
  631. package/templates/official/content-strategist/config.json +23 -0
  632. package/templates/official/content-strategist/start-up.sh +23 -0
  633. package/templates/official/content-writer/CLAUDE.md +72 -0
  634. package/templates/official/content-writer/IDENTITY.md +30 -0
  635. package/templates/official/content-writer/SOUL.md +46 -0
  636. package/templates/official/content-writer/TOOLS.md +44 -0
  637. package/templates/official/content-writer/config.json +23 -0
  638. package/templates/official/content-writer/start-up.sh +23 -0
  639. package/templates/official/forward-deployed-engineer/CLAUDE.md +54 -0
  640. package/templates/official/forward-deployed-engineer/IDENTITY.md +37 -0
  641. package/templates/official/forward-deployed-engineer/SOUL.md +55 -0
  642. package/templates/official/forward-deployed-engineer/config.json +21 -0
  643. package/templates/official/lead/CLAUDE.md +33 -0
  644. package/templates/official/lead/IDENTITY.md +36 -0
  645. package/templates/official/lead/SOUL.md +51 -0
  646. package/templates/official/lead/config.json +22 -0
  647. package/templates/official/researcher/CLAUDE.md +46 -0
  648. package/templates/official/researcher/IDENTITY.md +28 -0
  649. package/templates/official/researcher/SOUL.md +43 -0
  650. package/templates/official/researcher/config.json +21 -0
  651. package/templates/official/reviewer/CLAUDE.md +63 -0
  652. package/templates/official/reviewer/IDENTITY.md +28 -0
  653. package/templates/official/reviewer/SOUL.md +45 -0
  654. package/templates/official/reviewer/config.json +21 -0
  655. package/templates/official/tester/CLAUDE.md +53 -0
  656. package/templates/official/tester/IDENTITY.md +28 -0
  657. package/templates/official/tester/SOUL.md +55 -0
  658. package/templates/official/tester/config.json +21 -0
  659. package/templates/schema.ts +35 -0
  660. package/templates-ui/README.md +46 -0
  661. package/templates-ui/components.json +17 -0
  662. package/templates-ui/eslint.config.mjs +18 -0
  663. package/templates-ui/next.config.ts +7 -0
  664. package/templates-ui/package.json +35 -0
  665. package/templates-ui/pnpm-lock.yaml +4571 -0
  666. package/templates-ui/postcss.config.mjs +7 -0
  667. package/templates-ui/public/file.svg +1 -0
  668. package/templates-ui/public/globe.svg +1 -0
  669. package/templates-ui/public/logo.png +0 -0
  670. package/templates-ui/public/next.svg +1 -0
  671. package/templates-ui/public/vercel.svg +1 -0
  672. package/templates-ui/public/window.svg +1 -0
  673. package/templates-ui/src/app/[category]/[name]/page.tsx +89 -0
  674. package/templates-ui/src/app/api/templates/[...slug]/route.ts +52 -0
  675. package/templates-ui/src/app/api/templates/route.ts +18 -0
  676. package/templates-ui/src/app/builder/page.tsx +37 -0
  677. package/templates-ui/src/app/globals.css +94 -0
  678. package/templates-ui/src/app/layout.tsx +79 -0
  679. package/templates-ui/src/app/page.tsx +38 -0
  680. package/templates-ui/src/app/robots.ts +11 -0
  681. package/templates-ui/src/app/sitemap.ts +31 -0
  682. package/templates-ui/src/components/compose-builder.tsx +442 -0
  683. package/templates-ui/src/components/compose-preview.tsx +117 -0
  684. package/templates-ui/src/components/file-preview.tsx +77 -0
  685. package/templates-ui/src/components/footer.tsx +40 -0
  686. package/templates-ui/src/components/header.tsx +41 -0
  687. package/templates-ui/src/components/template-card.tsx +87 -0
  688. package/templates-ui/src/components/template-detail.tsx +125 -0
  689. package/templates-ui/src/components/template-gallery.tsx +263 -0
  690. package/templates-ui/src/components/ui/badge.tsx +36 -0
  691. package/templates-ui/src/components/ui/button.tsx +57 -0
  692. package/templates-ui/src/components/ui/card.tsx +76 -0
  693. package/templates-ui/src/components/ui/separator.tsx +31 -0
  694. package/templates-ui/src/components/ui/tooltip.tsx +32 -0
  695. package/templates-ui/src/lib/compose-generator.ts +241 -0
  696. package/templates-ui/src/lib/templates.ts +137 -0
  697. package/templates-ui/src/lib/utils.ts +6 -0
  698. package/templates-ui/tsconfig.json +34 -0
  699. package/thoughts/research/2026-02-28-openfort-viem-x402-research.md +679 -0
  700. package/thoughts/research/2026-02-28-x402-payments-research.md +686 -0
  701. package/thoughts/researcher/plans/2026-02-20-agent-self-improvement-plan.md +282 -0
  702. package/thoughts/researcher/research/2026-02-20-agent-self-improvement.md +492 -0
  703. package/thoughts/shared/plans/2026-02-26-mcp-tool-context-reduction.md +282 -0
  704. package/thoughts/shared/plans/2026-03-02-claude-context-mode-integration.md +328 -0
  705. package/thoughts/shared/plans/2026-03-02-code-level-heartbeat.md +224 -0
  706. package/thoughts/shared/research/2026-02-26-cliffy-mcp-tools.md +159 -0
  707. package/thoughts/shared/research/2026-03-03-database-migration-system-refactor.md +337 -0
  708. package/thoughts/swarm-researcher/plans/2026-02-23-openclaw-improvements-plan.md +778 -0
  709. package/thoughts/swarm-researcher/plans/2026-02-26-artifacts-localtunnel-plan.md +1269 -0
  710. package/thoughts/swarm-researcher/research/2026-02-23-openclaw-vs-agent-swarm-comparison.md +411 -0
  711. package/thoughts/swarm-researcher/research/2026-02-26-artifacts-localtunnel.md +724 -0
  712. package/thoughts/taras/brainstorms/2026-03-20-prompt-template-registry.md +443 -0
  713. package/thoughts/taras/brainstorms/2026-03-20-setup-cli-onboarding.md +307 -0
  714. package/thoughts/taras/plans/2026-02-20-auto-improvement.md +803 -0
  715. package/thoughts/taras/plans/2026-02-20-env-management.md +538 -0
  716. package/thoughts/taras/plans/2026-02-20-memory-system.md +882 -0
  717. package/thoughts/taras/plans/2026-02-20-repos-knowledge.md +806 -0
  718. package/thoughts/taras/plans/2026-02-20-session-attach.md +647 -0
  719. package/thoughts/taras/plans/2026-02-20-worker-identity.md +820 -0
  720. package/thoughts/taras/plans/2026-02-25-feat-new-ui-visual-redesign-plan.md +768 -0
  721. package/thoughts/taras/plans/2026-03-04-fix-buildSystemPrompt-missing-fields.md +77 -0
  722. package/thoughts/taras/plans/2026-03-04-new-ui-missing-actions.md +543 -0
  723. package/thoughts/taras/plans/2026-03-06-one-time-scheduled-tasks.md +373 -0
  724. package/thoughts/taras/plans/2026-03-08-memory-self-improvement-enhancements.md +512 -0
  725. package/thoughts/taras/plans/2026-03-08-pi-mono-provider-implementation.md +919 -0
  726. package/thoughts/taras/plans/2026-03-09-templates-registry.md +723 -0
  727. package/thoughts/taras/plans/2026-03-10-task-working-directory.md +371 -0
  728. package/thoughts/taras/plans/2026-03-11-archil-per-agent-write-strategy.md +621 -0
  729. package/thoughts/taras/plans/2026-03-12-eliminate-inbox-route-to-tasks.md +61 -0
  730. package/thoughts/taras/plans/2026-03-12-slack-thread-followup-additive.md +488 -0
  731. package/thoughts/taras/plans/2026-03-13-slack-ai-improvements.md +644 -0
  732. package/thoughts/taras/plans/2026-03-16-route-wrapper-openapi.md +636 -0
  733. package/thoughts/taras/plans/2026-03-17-multi-api-config.md +444 -0
  734. package/thoughts/taras/plans/2026-03-18-agent-fs-integration.md +591 -0
  735. package/thoughts/taras/plans/2026-03-18-debug-db-explorer.md +446 -0
  736. package/thoughts/taras/plans/2026-03-18-workflow-redesign.md +987 -0
  737. package/thoughts/taras/plans/2026-03-19-compound-learnings.md +403 -0
  738. package/thoughts/taras/plans/2026-03-19-ticket-tracker-linear-integration.md +860 -0
  739. package/thoughts/taras/plans/2026-03-19-workflow-io-schemas-and-bugs.md +899 -0
  740. package/thoughts/taras/plans/2026-03-20-setup-cli-onboarding.md +874 -0
  741. package/thoughts/taras/plans/2026-03-20-workflow-structured-output-validation-workspace.md +723 -0
  742. package/thoughts/taras/research/2026-02-19-agent-native-swarm-architecture.md +390 -0
  743. package/thoughts/taras/research/2026-02-19-swarm-gaps-implementation.md +594 -0
  744. package/thoughts/taras/research/2026-02-25-dashboard-ui-design-best-practices.md +825 -0
  745. package/thoughts/taras/research/2026-02-26-task-detail-page-redesign.md +393 -0
  746. package/thoughts/taras/research/2026-03-03-new-ui-missing-actions.md +168 -0
  747. package/thoughts/taras/research/2026-03-05-pi-mono-provider-research.md +230 -0
  748. package/thoughts/taras/research/2026-03-06-workflow-engine-design.md +445 -0
  749. package/thoughts/taras/research/2026-03-08-drive-loop-concept.md +375 -0
  750. package/thoughts/taras/research/2026-03-08-pi-mono-deep-dive.md +869 -0
  751. package/thoughts/taras/research/2026-03-09-templates-registry.md +373 -0
  752. package/thoughts/taras/research/2026-03-10-agent-working-directory.md +223 -0
  753. package/thoughts/taras/research/2026-03-10-configurable-event-prompts.md +339 -0
  754. package/thoughts/taras/research/2026-03-11-archil-production-setup.md +181 -0
  755. package/thoughts/taras/research/2026-03-11-archil-shared-disk-write-strategies.md +437 -0
  756. package/thoughts/taras/research/2026-03-13-slack-ai-features.md +258 -0
  757. package/thoughts/taras/research/2026-03-16-openapi-docs-generation.md +335 -0
  758. package/thoughts/taras/research/2026-03-16-route-wrapper-openapi.md +670 -0
  759. package/thoughts/taras/research/2026-03-16-slack-thread-followups-e2e.md +54 -0
  760. package/thoughts/taras/research/2026-03-18-agent-fs-integration.md +558 -0
  761. package/thoughts/taras/research/2026-03-18-linear-integration-finalization.md +526 -0
  762. package/thoughts/taras/research/2026-03-18-workflow-redesign.md +797 -0
  763. package/thoughts/taras/research/2026-03-19-workflow-node-io-schemas-and-bugs.md +563 -0
  764. package/thoughts/taras/research/2026-03-19-workflow-structured-output-validation-workspace.md +486 -0
  765. package/thoughts/taras/research/2026-03-20-prompt-template-registry.md +469 -0
  766. package/tsconfig.json +1 -1
  767. package/FAQ.md +0 -19
  768. package/src/tests/get-inbox-message.test.ts +0 -145
  769. package/src/tools/get-inbox-message.ts +0 -89
  770. package/src/tools/inbox-delegate.ts +0 -113
  771. package/ui/CLAUDE.md +0 -49
  772. package/ui/bun.lock +0 -771
  773. package/ui/index.html +0 -22
  774. package/ui/package-lock.json +0 -5290
  775. package/ui/package.json +0 -33
  776. package/ui/pnpm-lock.yaml +0 -3341
  777. package/ui/postcss.config.js +0 -6
  778. package/ui/src/App.tsx +0 -63
  779. package/ui/src/components/ActivityFeed.tsx +0 -440
  780. package/ui/src/components/AgentDetailPanel.tsx +0 -733
  781. package/ui/src/components/AgentsPanel.tsx +0 -815
  782. package/ui/src/components/ChatPanel.tsx +0 -1920
  783. package/ui/src/components/ConfigModal.tsx +0 -253
  784. package/ui/src/components/Dashboard.tsx +0 -832
  785. package/ui/src/components/EditAgentProfileModal.tsx +0 -433
  786. package/ui/src/components/EpicDetailPage.tsx +0 -741
  787. package/ui/src/components/EpicsPanel.tsx +0 -566
  788. package/ui/src/components/Header.tsx +0 -160
  789. package/ui/src/components/JsonViewer.tsx +0 -171
  790. package/ui/src/components/ScheduledTaskDetailPanel.tsx +0 -517
  791. package/ui/src/components/ScheduledTasksPanel.tsx +0 -639
  792. package/ui/src/components/ServicesPanel.tsx +0 -622
  793. package/ui/src/components/SessionLogPanel.tsx +0 -1219
  794. package/ui/src/components/StatsBar.tsx +0 -321
  795. package/ui/src/components/StatusBadge.tsx +0 -168
  796. package/ui/src/components/TaskDetailPanel.tsx +0 -903
  797. package/ui/src/components/TasksPanel.tsx +0 -614
  798. package/ui/src/components/UsageCharts.tsx +0 -216
  799. package/ui/src/components/UsageTab.tsx +0 -394
  800. package/ui/src/hooks/queries.ts +0 -353
  801. package/ui/src/index.css +0 -257
  802. package/ui/src/lib/api.ts +0 -268
  803. package/ui/src/lib/config.ts +0 -35
  804. package/ui/src/lib/contentPreview.ts +0 -208
  805. package/ui/src/lib/theme.ts +0 -214
  806. package/ui/src/main.tsx +0 -28
  807. package/ui/src/vite-env.d.ts +0 -1
  808. package/ui/tailwind.config.js +0 -37
  809. package/ui/vite.config.ts +0 -35
  810. /package/{ui → docs-site}/public/logo.png +0 -0
@@ -0,0 +1,636 @@
1
+ ---
2
+ date: 2026-03-16
3
+ author: Claude
4
+ status: completed
5
+ autonomy: autopilot
6
+ research: thoughts/taras/research/2026-03-16-route-wrapper-openapi.md
7
+ tags: [plan, openapi, route-wrapper, zod-to-openapi, api-docs]
8
+ commit_per_phase: single (all phases shipped in b8e0d9d)
9
+ last_updated: 2026-03-16
10
+ last_updated_by: Claude (verification)
11
+ ---
12
+
13
+ # Route Wrapper + OpenAPI Spec Generation
14
+
15
+ ## Overview
16
+
17
+ Introduce a `route()` wrapper that replaces `matchRoute()` as the single source of truth for HTTP routing, input validation, and OpenAPI 3.1 spec generation. Each route definition includes Zod schemas for params, query, body, and responses — serving as both runtime validator and documentation source.
18
+
19
+ This delivers three benefits in one change:
20
+ 1. **OpenAPI spec** — live at `/openapi.json`, interactive docs at `/docs` (Scalar)
21
+ 2. **Runtime input validation** — currently absent for most endpoints
22
+ 3. **Full TypeScript type inference** — no more `parseBody<T>` casts or manual `queryParams.get()`
23
+
24
+ ## Current State Analysis
25
+
26
+ - **68 `matchRoute()` calls** across 12 handler files, plus 1 direct URL match in `ecosystem.ts`
27
+ - **No input validation** — malformed requests can crash handlers
28
+ - **No API documentation** — endpoints only discoverable by reading source code
29
+ - **28 Zod schemas** in `src/types.ts` ready for reuse in route definitions
30
+ - **Zod v4** (`^4.2.1`) — requires `@asteasolutions/zod-to-openapi` v8.x
31
+
32
+ ### Key Discoveries:
33
+ - `repos.ts:17-137` — simplest handler (5 endpoints), good migration pilot
34
+ - `ecosystem.ts:9` — only handler using direct URL match instead of `matchRoute()`
35
+ - `agents.ts` exports TWO handler functions (`handleAgentRegister` + `handleAgentsRest`)
36
+ - `core.ts:36-278` — pre-auth routes use direct URL matching, NOT `matchRoute()`
37
+ - `mcp.ts` — uses `StreamableHTTPServerTransport`, not matchRoute-based routing
38
+ - `@asteasolutions/zod-to-openapi` v8.x supports Zod v4, but must use `.meta()` instead of `extendZodWithOpenApi(z)` to avoid type issue #340
39
+ - CI freshness check pattern exists at `.github/workflows/merge-gate.yml:91-117` (pi-skills)
40
+
41
+ ## Desired End State
42
+
43
+ - All ~69 REST endpoints defined via `route()` with Zod schemas
44
+ - `/openapi.json` endpoint serving live spec (computed from running code, cached)
45
+ - `/docs` endpoint serving Scalar interactive API explorer (pre-auth, like `/health`)
46
+ - `openapi.json` file committed to repo for CI freshness check
47
+ - `bun run docs:openapi` script to regenerate the committed file
48
+ - Merge gate blocks PRs with stale `openapi.json`
49
+ - Zero raw `matchRoute()` calls remaining in handler files
50
+
51
+ ### Verification:
52
+ - `curl http://localhost:3013/openapi.json` returns valid OpenAPI 3.1 JSON
53
+ - `curl http://localhost:3013/docs` returns Scalar HTML page
54
+ - `bun run docs:openapi && git diff --exit-code openapi.json` passes
55
+ - `bun run tsc:check` passes
56
+ - `bun run lint:fix` passes
57
+ - `bun test` passes
58
+ - Sending malformed request bodies returns 400 with Zod error details
59
+
60
+ ## Quick Verification Reference
61
+
62
+ Common commands:
63
+ - `bun run tsc:check` — TypeScript type check
64
+ - `bun run lint:fix` — Biome lint + format
65
+ - `bun test` — Unit tests
66
+ - `bun run docs:openapi` — Regenerate openapi.json
67
+ - `curl http://localhost:3013/health` — Server running check
68
+ - `curl http://localhost:3013/openapi.json | head -20` — Spec served correctly
69
+ - `curl http://localhost:3013/docs` — Scalar UI served
70
+
71
+ Key files:
72
+ - `src/http/route-def.ts` — Route wrapper, registry, types (NEW)
73
+ - `src/http/openapi.ts` — OpenAPI spec generator (NEW)
74
+ - `scripts/generate-openapi.ts` — CI dump script (NEW)
75
+ - `src/http/core.ts` — Pre-auth endpoint additions (/docs, /openapi.json)
76
+ - `src/http/repos.ts` — Migration pilot
77
+
78
+ ## What We're NOT Doing
79
+
80
+ - Converting `core.ts` pre-auth routes (`/health`, `/me`, `/ping`, `/close`, `/cancelled-tasks`) — these use direct URL matching and are infrastructure, not API surface
81
+ - Converting `mcp.ts` — uses `StreamableHTTPServerTransport` with its own protocol
82
+ - Adding response validation (only request input validation)
83
+ - Migrating to Hono or another framework
84
+ - Adding named `$ref` schemas initially — inline schemas keep the migration simpler; `$ref` optimization can be added later if the spec gets too large
85
+ - Validating auth in the route wrapper — auth stays in `handleCore`
86
+
87
+ ## Implementation Approach
88
+
89
+ **Incremental migration**: old `matchRoute()` and new `route()` coexist. Each handler file is converted independently — unconverted handlers still work, they just don't appear in the OpenAPI spec. The spec grows organically as handlers are converted.
90
+
91
+ **Per-file conversion** is mechanical: ~20-25 lines of route definition per endpoint, replacing ~10-15 lines of inline parsing. Net line change is roughly neutral per handler.
92
+
93
+ **Migration order**: simplest files first (repos.ts pilot, then 1-3 endpoint files, then 5-6 endpoint files, then complex files). This builds confidence and catches issues early.
94
+
95
+ ---
96
+
97
+ ## Phase 0: Foundation
98
+
99
+ ### Overview
100
+ Install dependency, create the route wrapper module, OpenAPI generator, Scalar viewer, and dump script. No handler migrations yet — this phase establishes the infrastructure.
101
+
102
+ ### Changes Required:
103
+
104
+ #### 1. Install dependency
105
+ **Command**: `bun add @asteasolutions/zod-to-openapi@^8.0.0`
106
+
107
+ Verify Zod v4 compatibility after install:
108
+ ```typescript
109
+ // Quick smoke test in a scratch file
110
+ import { z } from "zod";
111
+ import { OpenAPIRegistry, OpenApiGeneratorV31 } from "@asteasolutions/zod-to-openapi";
112
+ const registry = new OpenAPIRegistry();
113
+ registry.registerPath({
114
+ method: "get",
115
+ path: "/test",
116
+ responses: { 200: { description: "OK" } },
117
+ });
118
+ const gen = new OpenApiGeneratorV31(registry.definitions);
119
+ const doc = gen.generateDocument({ openapi: "3.1.0", info: { title: "Test", version: "1.0.0" } });
120
+ console.log(JSON.stringify(doc, null, 2));
121
+ ```
122
+
123
+ If this fails, fall back to `zod-openapi@^5.0.0` (samchungy) which also supports Zod v4.
124
+
125
+ #### 2. Route wrapper module
126
+ **File**: `src/http/route-def.ts` (NEW, ~80-100 lines)
127
+
128
+ Create the `route()` factory function, `routeRegistry`, and associated types as described in the research document. Key implementation details:
129
+
130
+ - `RouteDef` interface with method, path, pattern, summary, tags, Zod schemas for params/query/body/responses
131
+ - `RouteHandle` interface with `match()` and `parse()` methods
132
+ - `route()` factory that pushes to `routeRegistry` and returns a `RouteHandle`
133
+ - `parse()` extracts path params from dynamic segments (null positions in pattern), validates with Zod, returns typed result or sends 400
134
+ - Use `Object.fromEntries(queryParams)` for query parsing with `z.coerce` for type conversion
135
+ - Do NOT call `extendZodWithOpenApi(z)` — not needed for basic schema conversion
136
+
137
+ Reference implementation: `thoughts/taras/research/2026-03-16-route-wrapper-openapi.md` lines 92-208
138
+
139
+ #### 3. OpenAPI spec generator
140
+ **File**: `src/http/openapi.ts` (NEW, ~80 lines)
141
+
142
+ - Import `routeRegistry` from `route-def.ts`
143
+ - Import `OpenAPIRegistry`, `OpenApiGeneratorV31` from `@asteasolutions/zod-to-openapi`
144
+ - Register Bearer auth and X-Agent-ID security schemes
145
+ - Iterate `routeRegistry`, convert each `RouteDef` to `registry.registerPath()` call
146
+ - Cache generated spec string (only changes on process restart)
147
+ - Export `generateOpenApiSpec(opts: { version: string; serverUrl?: string }): string`
148
+
149
+ Reference implementation: `thoughts/taras/research/2026-03-16-route-wrapper-openapi.md` lines 356-456
150
+
151
+ #### 4. Scalar viewer HTML
152
+ **File**: `src/http/openapi.ts` (same file, export a constant)
153
+
154
+ Add `SCALAR_HTML` constant — minimal HTML page loading Scalar CDN, pointing at `/openapi.json`:
155
+
156
+ ```html
157
+ <!DOCTYPE html>
158
+ <html>
159
+ <head><title>Agent Swarm API</title><meta charset="utf-8" /></head>
160
+ <body>
161
+ <script id="api-reference" data-url="/openapi.json"></script>
162
+ <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
163
+ </body>
164
+ </html>
165
+ ```
166
+
167
+ #### 5. Serve /openapi.json and /docs pre-auth
168
+ **File**: `src/http/core.ts`
169
+ **Location**: After the `/health` check (around line 49), before the auth gate (line 66)
170
+
171
+ Add two route checks:
172
+ ```typescript
173
+ if (req.url === "/openapi.json") {
174
+ const version = (await Bun.file("package.json").json()).version;
175
+ const spec = generateOpenApiSpec({ version });
176
+ res.writeHead(200, { "Content-Type": "application/json" });
177
+ res.end(spec);
178
+ return true;
179
+ }
180
+ if (req.url === "/docs" || req.url === "/docs/") {
181
+ res.writeHead(200, { "Content-Type": "text/html" });
182
+ res.end(SCALAR_HTML);
183
+ return true;
184
+ }
185
+ ```
186
+
187
+ Import `generateOpenApiSpec` and `SCALAR_HTML` from `./openapi`.
188
+
189
+ **Note on registry population**: At runtime, `routeRegistry` is populated when handler files are imported by `index.ts` — so the registry is already full when `generateOpenApiSpec()` is called at request time. For the dump script (`scripts/generate-openapi.ts`), handler files must be explicitly imported to trigger `route()` registrations. Importing individual handler files is safe — verified that `db.ts` uses lazy init (`getDb()` only opens DB when a query is actually called), and no handler has top-level side effects. Do NOT import `src/http/index.ts` (boots the whole server).
190
+
191
+ #### 6. Dump script for CI
192
+ **File**: `scripts/generate-openapi.ts` (NEW, ~20 lines)
193
+
194
+ ```typescript
195
+ import { generateOpenApiSpec } from "../src/http/openapi";
196
+ // Import all handler files to trigger route() registrations
197
+ import "../src/http/repos";
198
+ // ... add more imports as handlers are migrated ...
199
+
200
+ const version = (await Bun.file("package.json").json()).version;
201
+ const spec = generateOpenApiSpec({ version, serverUrl: "http://localhost:3013" });
202
+ await Bun.write("openapi.json", spec);
203
+ console.log(`Generated openapi.json (${(spec.length / 1024).toFixed(1)}KB)`);
204
+ ```
205
+
206
+ **Important**: This script will need handler imports added incrementally as each handler file is migrated. Each Phase 2 sub-step should add the import.
207
+
208
+ #### 7. Package.json script
209
+ **File**: `package.json`
210
+
211
+ Add script: `"docs:openapi": "bun scripts/generate-openapi.ts"`
212
+
213
+ ### Success Criteria:
214
+
215
+ #### Automated Verification:
216
+ - [ ] Dependency installed: `bun add @asteasolutions/zod-to-openapi@^8.0.0`
217
+ - [ ] TypeScript compiles: `bun run tsc:check`
218
+ - [ ] Lint passes: `bun run lint:fix`
219
+ - [ ] Tests pass: `bun test`
220
+ - [ ] Dump script runs: `bun run docs:openapi`
221
+ - [ ] openapi.json created: `ls -la openapi.json`
222
+
223
+ #### Manual Verification:
224
+ - [ ] Start server: `bun run start:http`
225
+ - [ ] `curl http://localhost:3013/openapi.json` returns valid JSON with `openapi: "3.1.0"` (empty paths is OK)
226
+ - [ ] `curl http://localhost:3013/docs` returns HTML page with Scalar
227
+ - [ ] Open `http://localhost:3013/docs` in browser — Scalar UI loads (empty API is OK)
228
+ - [ ] Existing endpoints still work: `curl -H "Authorization: Bearer $API_KEY" http://localhost:3013/api/tasks`
229
+
230
+ **Implementation Note**: After completing this phase, pause for manual confirmation before proceeding to Phase 1.
231
+
232
+ ---
233
+
234
+ ## Phase 1: Pilot Migration (repos.ts)
235
+
236
+ ### Overview
237
+ Convert all 5 endpoints in `repos.ts` to use `route()`. This is the simplest handler file and serves as proof-of-concept for the migration pattern.
238
+
239
+ ### Changes Required:
240
+
241
+ #### 1. Add route definitions
242
+ **File**: `src/http/repos.ts`
243
+ **Location**: Top of file, after imports
244
+
245
+ Define 5 route objects:
246
+
247
+ | Route | Method | Path | Schemas |
248
+ |-------|--------|------|---------|
249
+ | `getRepo` | GET | `/api/repos/{id}` | params: `{ id: z.string().uuid() }` |
250
+ | `listRepos` | GET | `/api/repos` | (no schemas) |
251
+ | `createRepo` | POST | `/api/repos` | body: `{ url, name?, clonePath? }` using `SwarmRepoSchema` fields |
252
+ | `updateRepo` | PUT | `/api/repos/{id}` | params: `{ id }`, body: `{ url?, name?, clonePath? }` |
253
+ | `deleteRepo` | DELETE | `/api/repos/{id}` | params: `{ id }` |
254
+
255
+ Add response schemas for each using `SwarmRepoSchema` from `src/types.ts`.
256
+
257
+ #### 2. Replace matchRoute() calls with route handle usage
258
+ **File**: `src/http/repos.ts`
259
+
260
+ For each endpoint, replace:
261
+ ```typescript
262
+ // Before
263
+ if (matchRoute(req.method, pathSegments, "GET", ["api", "repos", null], true)) {
264
+ const id = pathSegments[2];
265
+ // ...
266
+ }
267
+
268
+ // After
269
+ if (getRepo.match(req.method, pathSegments)) {
270
+ const parsed = await getRepo.parse(req, res, pathSegments, queryParams);
271
+ if (!parsed) return true;
272
+ const { id } = parsed.params;
273
+ // ...
274
+ }
275
+ ```
276
+
277
+ Remove inline body parsing (`JSON.parse(Buffer.concat(chunks).toString())`) — the route wrapper's `parse()` handles this via `parseBody()`.
278
+
279
+ #### 3. Update dump script imports
280
+ **File**: `scripts/generate-openapi.ts`
281
+
282
+ The repos.ts import should already be there from Phase 0. Verify it's present.
283
+
284
+ #### 4. Regenerate openapi.json
285
+ **Command**: `bun run docs:openapi`
286
+
287
+ The spec should now contain the 5 repos endpoints.
288
+
289
+ ### Success Criteria:
290
+
291
+ #### Automated Verification:
292
+ - [ ] TypeScript compiles: `bun run tsc:check`
293
+ - [ ] Lint passes: `bun run lint:fix`
294
+ - [ ] Tests pass: `bun test`
295
+ - [ ] Spec regenerated: `bun run docs:openapi`
296
+ - [ ] Spec contains repos paths: `grep -c '"/api/repos' openapi.json` (should be ≥ 2 — one for `/api/repos`, one for `/api/repos/{id}`)
297
+
298
+ #### Manual Verification:
299
+ - [ ] Start server: `bun run start:http`
300
+ - [ ] CRUD operations work:
301
+ - `curl -H "Authorization: Bearer $API_KEY" http://localhost:3013/api/repos` (list)
302
+ - `curl -X POST -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" http://localhost:3013/api/repos -d '{"url":"https://github.com/test/repo"}'` (create)
303
+ - `curl -H "Authorization: Bearer $API_KEY" http://localhost:3013/api/repos/<id>` (get)
304
+ - `curl -X DELETE -H "Authorization: Bearer $API_KEY" http://localhost:3013/api/repos/<id>` (delete)
305
+ - [ ] Validation works: `curl -X POST -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" http://localhost:3013/api/repos -d '{}'` returns 400 with Zod validation error
306
+ - [ ] `/docs` in browser shows repos endpoints with schemas
307
+ - [ ] Non-migrated endpoints still work: `curl -H "Authorization: Bearer $API_KEY" http://localhost:3013/api/tasks`
308
+
309
+ **Implementation Note**: After completing this phase, pause for manual confirmation. This is the most critical checkpoint — if the pilot works cleanly, the remaining migrations are mechanical.
310
+
311
+ ---
312
+
313
+ ## Phase 2: Migrate Remaining Handlers
314
+
315
+ ### Overview
316
+ Convert all remaining handler files from `matchRoute()` to `route()`. Each file conversion is atomic and independently testable. Order is by increasing complexity.
317
+
318
+ ### Changes Required:
319
+
320
+ Each file follows the same pattern as the repos.ts pilot:
321
+ 1. Add route definitions at the top (import `route` from `./route-def`, import Zod schemas from `../types`)
322
+ 2. Replace `matchRoute()` calls with `routeHandle.match()` + `routeHandle.parse()`
323
+ 3. Remove inline body/query parsing
324
+ 4. Add import to `scripts/generate-openapi.ts`
325
+ 5. Regenerate: `bun run docs:openapi`
326
+
327
+ #### Conversion Order (recommended):
328
+
329
+ **Batch A — Simple files (1-3 endpoints):**
330
+
331
+ | # | File | Endpoints | Notes |
332
+ |---|------|-----------|-------|
333
+ | 1 | `src/http/poll.ts` | 1 | Single POST endpoint |
334
+ | 2 | `src/http/memory.ts` | 2 | GET + POST |
335
+ | 3 | `src/http/webhooks.ts` | 3 | GitHub/GitLab/AgentMail webhook receivers |
336
+ | 4 | `src/http/ecosystem.ts` | 1 | Convert from direct URL match to `route()` |
337
+
338
+ **Batch B — Medium files (5-6 endpoints):**
339
+
340
+ | # | File | Endpoints | Notes |
341
+ |---|------|-----------|-------|
342
+ | 5 | `src/http/config.ts` | 5 | CRUD + list |
343
+ | 6 | `src/http/stats.ts` | 5 | Read-only stats endpoints |
344
+ | 7 | `src/http/schedules.ts` | 5 | CRUD + run-now |
345
+ | 8 | `src/http/active-sessions.ts` | 6 | Session management |
346
+ | 9 | `src/http/session-data.ts` | 6 | Session data CRUD |
347
+
348
+ **Batch C — Complex files (7+ endpoints):**
349
+
350
+ | # | File | Endpoints | Notes |
351
+ |---|------|-----------|-------|
352
+ | 10 | `src/http/agents.ts` | 7 | Two handler functions: `handleAgentRegister` + `handleAgentsRest` |
353
+ | 11 | `src/http/workflows.ts` | 9 | Workflows + workflow runs |
354
+ | 12 | `src/http/tasks.ts` | 10 | Most complex handler, many query params |
355
+ | 13 | `src/http/epics.ts` | 12 | Largest handler file |
356
+
357
+ **Per-file checklist** (repeat for each file):
358
+ - [ ] Add route definitions at top of file
359
+ - [ ] Replace all `matchRoute()` calls with route handle pattern
360
+ - [ ] Remove inline `parseBody()` / `queryParams.get()` / `Number()` casts
361
+ - [ ] Add response schemas to route definitions
362
+ - [ ] Add handler import to `scripts/generate-openapi.ts`
363
+ - [ ] Run `bun run tsc:check`
364
+ - [ ] Run `bun run lint:fix`
365
+ - [ ] Run `bun run docs:openapi`
366
+
367
+ **After each batch**, run the full integration test suite as regression gate:
368
+ ```bash
369
+ bun test src/tests/http-api-integration.test.ts
370
+ ```
371
+ This test covers 20+ API surface areas (agents, tasks, epics, schedules, config, repos, memory, ecosystem, etc.) and will catch any routing regressions from the migration. Additional focused tests to run per batch:
372
+ - Batch A: `bun test src/tests/memory.test.ts`
373
+ - Batch B: `bun test src/tests/scheduled-tasks-api.test.ts src/tests/session-logs.test.ts src/tests/session-costs.test.ts`
374
+ - Batch C: `bun test src/tests/workflow-http.test.ts src/tests/task-pause-resume.test.ts src/tests/task-cancellation.test.ts`
375
+
376
+ #### Special Cases:
377
+
378
+ **`ecosystem.ts`**: Currently uses `req.method === "GET" && req.url === "/ecosystem"`. Convert to:
379
+ ```typescript
380
+ const getEcosystem = route({
381
+ method: "get",
382
+ path: "/ecosystem",
383
+ pattern: ["ecosystem"],
384
+ summary: "Get ecosystem status",
385
+ tags: ["Ecosystem"],
386
+ responses: { 200: { description: "Ecosystem data" } },
387
+ });
388
+ ```
389
+ Then use `getEcosystem.match()` + `getEcosystem.parse()` like all other handlers.
390
+
391
+ **`agents.ts`**: Has two exported handlers. Route definitions for both should be in the same file. The `handleAgentRegister` function handles `POST /api/agents/register` and `POST /api/agents/{id}/heartbeat`. The `handleAgentsRest` function handles the remaining 5 CRUD endpoints.
392
+
393
+ **`webhooks.ts`**: Webhook endpoints receive external payloads (GitHub, GitLab, AgentMail). Define body schemas loosely (`z.record(z.unknown())` or `z.any()`) since we don't control these payloads. The value here is documentation, not strict validation.
394
+
395
+ ### Success Criteria:
396
+
397
+ #### Automated Verification:
398
+ - [ ] TypeScript compiles: `bun run tsc:check`
399
+ - [ ] Lint passes: `bun run lint:fix`
400
+ - [ ] Tests pass: `bun test`
401
+ - [ ] Spec regenerated: `bun run docs:openapi`
402
+ - [ ] No raw matchRoute in handlers: `grep -rn "matchRoute(" src/http/ --include="*.ts" | grep -v route-def.ts | grep -v utils.ts` (should return empty)
403
+ - [ ] All endpoints in spec: `bun run docs:openapi && grep -c '"/' openapi.json` (should be ~69 paths)
404
+
405
+ #### Manual Verification:
406
+ - [ ] Start server and open `/docs` — all endpoints visible with schemas
407
+ - [ ] Test a few endpoints from different handlers to verify routing still works
408
+ - [ ] Test validation: send malformed body to POST /api/tasks — should get 400
409
+ - [ ] Test validation: send invalid UUID as path param — should get 400
410
+ - [ ] Test query coercion: `GET /api/tasks?limit=abc` — should get 400 (not NaN behavior)
411
+
412
+ **Implementation Note**: After completing each batch (A, B, C), pause for a quick sanity check. After all batches, pause for full manual verification before proceeding to Phase 3.
413
+
414
+ ---
415
+
416
+ ## Phase 3: CI Freshness Check
417
+
418
+ ### Overview
419
+ Add a merge gate job that ensures `openapi.json` stays in sync with route definitions. Uses the same pattern as the existing pi-skills freshness check.
420
+
421
+ ### Changes Required:
422
+
423
+ #### 1. Add CI job
424
+ **File**: `.github/workflows/merge-gate.yml`
425
+ **Location**: After the `pi-skills-freshness` job (around line 117)
426
+
427
+ ```yaml
428
+ openapi-freshness:
429
+ name: OpenAPI Spec Freshness Check
430
+ needs: detect-changes
431
+ if: needs.detect-changes.outputs.code == 'true'
432
+ runs-on: ubuntu-latest
433
+ steps:
434
+ - name: Checkout repository
435
+ uses: actions/checkout@v4
436
+ - name: Setup Bun
437
+ uses: oven-sh/setup-bun@v2
438
+ with:
439
+ bun-version: latest
440
+ - name: Install dependencies
441
+ run: bun install --frozen-lockfile
442
+ - name: Rebuild OpenAPI spec and check for drift
443
+ run: |
444
+ bun run docs:openapi
445
+ if [ -n "$(git diff --name-only openapi.json)" ]; then
446
+ echo "::error::openapi.json is out of date! Run 'bun run docs:openapi' and commit the changes."
447
+ git diff --stat openapi.json
448
+ exit 1
449
+ fi
450
+ echo "OpenAPI spec is up to date."
451
+ ```
452
+
453
+ #### 2. Add to gate job needs
454
+ **File**: `.github/workflows/merge-gate.yml`
455
+ **Location**: The `gate` job's `needs` array
456
+
457
+ Add `openapi-freshness` to the existing needs list.
458
+
459
+ #### 3. Add raw matchRoute() lint check (optional)
460
+ **File**: `.github/workflows/merge-gate.yml`
461
+
462
+ As part of the openapi-freshness job, add a step that fails if any raw `matchRoute()` calls exist in handler files:
463
+
464
+ ```yaml
465
+ - name: Check for raw matchRoute usage
466
+ run: |
467
+ UNREGISTERED=$(grep -rn "matchRoute(" src/http/ --include="*.ts" | grep -v "route-def.ts" | grep -v "utils.ts" || true)
468
+ if [ -n "$UNREGISTERED" ]; then
469
+ echo "::error::Found raw matchRoute() calls. Convert to route() definitions:"
470
+ echo "$UNREGISTERED"
471
+ exit 1
472
+ fi
473
+ echo "No raw matchRoute() calls found."
474
+ ```
475
+
476
+ ### Success Criteria:
477
+
478
+ #### Automated Verification:
479
+ - [ ] CI config valid YAML: `python3 -c "import yaml; yaml.safe_load(open('.github/workflows/merge-gate.yml'))"`
480
+ - [ ] Freshness check passes locally: `bun run docs:openapi && git diff --exit-code openapi.json`
481
+ - [ ] matchRoute lint passes: `grep -rn "matchRoute(" src/http/ --include="*.ts" | grep -v route-def.ts | grep -v utils.ts` (empty)
482
+
483
+ #### Manual Verification:
484
+ - [ ] Intentionally edit a route definition, verify `bun run docs:openapi && git diff openapi.json` shows the change
485
+ - [ ] Push branch, verify the openapi-freshness job runs in CI
486
+ - [ ] Verify the gate job includes openapi-freshness in its needs
487
+
488
+ **Implementation Note**: This phase should be done last, after all handlers are migrated, so the matchRoute() lint check passes.
489
+
490
+ ---
491
+
492
+ ## Testing Strategy
493
+
494
+ ### Unit Tests
495
+ - No new test files needed initially — existing tests exercise the endpoints through the handler functions
496
+ - If any existing tests call `matchRoute()` directly, they don't need updating (the function still exists in utils.ts)
497
+ - Consider adding a unit test for `route-def.ts` that verifies `parse()` returns correct types and sends 400 on validation failure
498
+
499
+ ### Integration Testing
500
+ - Run `bun test src/tests/http-api-integration.test.ts` after each batch — this is the comprehensive regression gate covering 20+ API areas
501
+ - Run focused test files per handler (e.g., `workflow-http.test.ts` after converting `workflows.ts`)
502
+ - The OpenAPI spec itself serves as a form of documentation test — if it generates without errors, the schemas are valid
503
+
504
+ ### Regression Testing
505
+ - Run `bun test` after every file conversion to catch regressions
506
+ - Run `bun test src/tests/http-api-integration.test.ts` as the primary regression gate after each batch
507
+ - The `bun run tsc:check` catches type errors from incorrect schema usage
508
+
509
+ ## E2E Verification (Claude runs these)
510
+
511
+ After all phases are complete, Claude will execute these verification steps:
512
+
513
+ ```bash
514
+ # 1. Start server in background
515
+ bun run start:http &
516
+
517
+ # 2. Verify /openapi.json returns valid OpenAPI 3.1 spec
518
+ curl -s http://localhost:3013/openapi.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(f'OpenAPI {d[\"openapi\"]}, {len(d.get(\"paths\",{}))} paths')"
519
+
520
+ # 3. Verify /docs returns Scalar HTML
521
+ curl -s http://localhost:3013/docs | grep -q "scalar" && echo "Scalar UI OK"
522
+
523
+ # 4. Test input validation — empty task body should return 400
524
+ curl -s -X POST -H "Authorization: Bearer $API_KEY" \
525
+ -H "Content-Type: application/json" \
526
+ http://localhost:3013/api/tasks \
527
+ -d '{"task": ""}' -w "\nHTTP %{http_code}"
528
+
529
+ # 5. Test valid request
530
+ curl -s -H "Authorization: Bearer $API_KEY" \
531
+ "http://localhost:3013/api/tasks?limit=5&status=completed" -w "\nHTTP %{http_code}"
532
+
533
+ # 6. Test path param validation — invalid UUID should return 400
534
+ curl -s -H "Authorization: Bearer $API_KEY" \
535
+ http://localhost:3013/api/tasks/not-a-uuid -w "\nHTTP %{http_code}"
536
+
537
+ # 7. Test query coercion — non-numeric limit should return 400
538
+ curl -s -H "Authorization: Bearer $API_KEY" \
539
+ "http://localhost:3013/api/tasks?limit=abc" -w "\nHTTP %{http_code}"
540
+
541
+ # 8. Verify CI script produces clean diff
542
+ bun run docs:openapi && git diff --exit-code openapi.json
543
+
544
+ # 9. Verify no raw matchRoute calls remain in handlers
545
+ grep -rn "matchRoute(" src/http/ --include="*.ts" | grep -v route-def.ts | grep -v utils.ts
546
+
547
+ # 10. Run full test suite + integration test
548
+ bun run tsc:check && bun run lint:fix && bun test
549
+ bun test src/tests/http-api-integration.test.ts
550
+
551
+ # 11. Kill background server
552
+ kill %1
553
+ ```
554
+
555
+ ## References
556
+
557
+ - Research: `thoughts/taras/research/2026-03-16-route-wrapper-openapi.md`
558
+ - Parent research: `thoughts/taras/research/2026-03-16-openapi-docs-generation.md`
559
+ - Zod v4 compat: `@asteasolutions/zod-to-openapi` v8.x uses `.meta()` instead of `.openapi()` — see GitHub issue #340
560
+ - CI pattern: `.github/workflows/merge-gate.yml:91-117` (pi-skills freshness)
561
+ - Existing doc gen: `scripts/generate-mcp-docs.ts` (inspiration for dump script)
562
+ - Integration test: `src/tests/http-api-integration.test.ts` (20+ API areas, primary regression gate)
563
+
564
+ ---
565
+
566
+ ## Review Errata
567
+
568
+ _Reviewed: 2026-03-16 by Claude_
569
+
570
+ ### Critical
571
+ _(none)_
572
+
573
+ ### Important
574
+ - [ ] **`commit_per_phase: TBD` in frontmatter** — resolve before implementation starts. Ask Taras for preference.
575
+ - [ ] **No rollback strategy** — add a note: if a handler conversion breaks something, rollback is `git checkout src/http/<file>.ts && bun run docs:openapi`. Each file conversion is atomic and independently revertible.
576
+ - [ ] **Endpoint count inconsistency** — plan says "~69 REST endpoints" (line 41) and "68 matchRoute() calls" (line 24). Research agent counted 76 matchRoute() calls. The discrepancy is likely because some matchRoute() calls are sub-route checks within the same endpoint (e.g., checking for `/cancel` suffix after matching `/tasks/{id}`). Reconcile with the actual endpoint catalog from the parent research (`2026-03-16-openapi-docs-generation.md` lists 62 endpoints across 17 files). The exact count will be determined during implementation — the plan should use "~62-70" or just "all" instead of a specific number.
577
+
578
+ ### Resolved
579
+ - [x] **Stream-of-consciousness note** (Phase 0, item 5) — cleaned up "Actually, this is a subtlety..." paragraph to a clear statement about registry population and import safety
580
+ - [x] **Phase 1 grep count wrong** — `grep -c "/api/repos" openapi.json` expected "≥ 5" but OpenAPI has 2 path keys (`/api/repos` and `/api/repos/{id}`), not 5 (endpoints ≠ paths). Fixed to "≥ 2"
581
+ - [x] **Import side effects verified safe** — `db.ts` uses lazy init (`getDb()` only opens DB on first query call). All handler files can be safely imported in the dump script without triggering DB connections, Slack, or timers. Only `src/http/index.ts` has dangerous top-level side effects (boots entire server).
582
+ - [x] **`Object.fromEntries(queryParams)` verified safe** — no handler uses `getAll()`, comma-splitting, or repeated query params. All query params are single-valued scalars.
583
+
584
+ ---
585
+
586
+ ## Post-Implementation Verification
587
+
588
+ _Verified: 2026-03-16 by Claude_
589
+
590
+ ### Automated Checks (all pass)
591
+
592
+ | Check | Result |
593
+ |-------|--------|
594
+ | `bun run tsc:check` | **PASS** — clean |
595
+ | `bun run lint:fix` | **PASS** — 0 warnings (after fixing 3 unused imports in active-sessions.ts, epics.ts, tasks.ts) |
596
+ | `bun test` | **PASS** — 1400/1400 tests, 0 fail |
597
+ | `bun test src/tests/http-api-integration.test.ts` | **PASS** — 166/166 tests, 0 fail |
598
+ | `bun run docs:openapi` | **PASS** — generated 83.2KB |
599
+ | `git diff --exit-code openapi.json` | **PASS** — no drift |
600
+ | `grep -rn "matchRoute(" src/http/ ...` | **PASS** — no raw matchRoute() in handlers |
601
+ | Dependency installed | **PASS** — `@asteasolutions/zod-to-openapi ^8.0.0` |
602
+ | CI job added | **PASS** — `openapi-freshness` job + gate dependency |
603
+
604
+ ### Manual E2E Tests (all pass)
605
+
606
+ Server started on port 3013, tested the following:
607
+
608
+ | Test | Expected | Actual | Status |
609
+ |------|----------|--------|--------|
610
+ | `GET /health` | 200 | 200 | **PASS** |
611
+ | `GET /openapi.json` | Valid OpenAPI 3.1.0 JSON | OpenAPI 3.1.0, 58 paths, title: "Agent Swarm API" | **PASS** |
612
+ | `GET /docs` | Scalar HTML page | HTML with `<script>` loading Scalar CDN | **PASS** |
613
+ | `GET /api/repos` (authed) | 200 + JSON list | 200, dict response | **PASS** |
614
+ | `GET /api/tasks?limit=2` (authed) | 200 + JSON with tasks/total | 200, `{tasks, total}` | **PASS** |
615
+ | `GET /api/agents` (authed) | 200 + JSON list | 200, list | **PASS** |
616
+ | `GET /api/epics` (authed) | 200 + JSON | 200, dict | **PASS** |
617
+ | `GET /api/active-sessions` (authed) | 200 + JSON | 200, dict | **PASS** |
618
+ | `GET /api/config` (authed) | 200 + JSON | 200, dict | **PASS** |
619
+ | `GET /api/workflows` (authed) | 200 + JSON list | 200, list (count: 0) | **PASS** |
620
+ | `POST /api/repos` empty body | 400 + Zod error | 400: "url: expected string, name: expected string" | **PASS** |
621
+ | `POST /api/epics` missing goal | 400 + Zod error | 400: "goal: expected string, received undefined" | **PASS** |
622
+ | `GET /api/tasks?limit=abc` | 400 + coercion error | 400: "limit: expected number, received NaN" | **PASS** |
623
+ | `GET /api/tasks` no auth | 401 | 401: "Unauthorized" | **PASS** |
624
+ | `GET /ecosystem` no X-Agent-ID | 400 | 400: "Missing X-Agent-ID header" | **PASS** |
625
+
626
+ ### Notes
627
+
628
+ - **Invalid UUID path params** (`GET /api/tasks/not-a-uuid`): Returns 404 "Task not found" instead of 400. The route param schemas use `z.string()` without `.uuid()`, so non-UUID strings are accepted and the handler returns 404 when no DB record matches. This is acceptable — strict UUID validation can be added later if desired.
629
+ - **`GET /api/schedules` returns 404**: This is pre-existing behavior — no list endpoint was ever implemented (only CRUD on individual schedules). Not a regression.
630
+ - **58 OpenAPI paths**: Plan estimated ~62-70. The difference is because OpenAPI groups multiple HTTP methods under one path key, and some matchRoute() calls were sub-route checks (e.g., `/tasks/{id}/cancel`), not distinct paths.
631
+ - **Test assertion changes**: Two test files were updated — `http-api-integration.test.ts` loosened an epic validation assertion (`"name, goal"` → `"goal"`), and `workflow-http.test.ts` changed `toBe` → `toContain` for an error message. Both reflect Zod validation producing slightly different error messages than the old manual validation. All 1400 tests pass.
632
+
633
+ ### Cleanup Applied During Verification
634
+
635
+ - Removed unused `parseBody` import from `epics.ts` and `tasks.ts`
636
+ - Removed unused `jsonError` import from `active-sessions.ts`