@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,111 @@
1
+ import { randomBytes, randomUUID } from "node:crypto";
2
+ import { createServer } from "node:net";
3
+ import { Spinner } from "@inkjs/ui";
4
+ import { Box, Text } from "ink";
5
+ import { useEffect, useRef, useState } from "react";
6
+ import type { StepProps } from "../types.ts";
7
+
8
+ /** Find an available port, starting from the preferred one. */
9
+ async function findAvailablePort(preferred: number): Promise<number> {
10
+ return new Promise((resolve) => {
11
+ const server = createServer();
12
+ server.listen(preferred, () => {
13
+ server.close(() => resolve(preferred));
14
+ });
15
+ server.on("error", () => {
16
+ // Port is in use, try a random one
17
+ const server2 = createServer();
18
+ server2.listen(0, () => {
19
+ const addr = server2.address();
20
+ const port = typeof addr === "object" && addr ? addr.port : 0;
21
+ server2.close(() => resolve(port));
22
+ });
23
+ });
24
+ });
25
+ }
26
+
27
+ export function CoreCredentialsStep({ state, goToNext, addLog }: StepProps) {
28
+ const [apiKey, setApiKey] = useState("");
29
+ const [agentIds, setAgentIds] = useState<Record<string, string>>({});
30
+ const [apiPort, setApiPort] = useState(0);
31
+ const [ready, setReady] = useState(false);
32
+ const generatedRef = useRef(false);
33
+
34
+ useEffect(() => {
35
+ if (generatedRef.current) return;
36
+ generatedRef.current = true;
37
+
38
+ const generate = async () => {
39
+ const key = randomBytes(32).toString("hex").slice(0, 24);
40
+ setApiKey(key);
41
+
42
+ const ids: Record<string, string> = {};
43
+ for (const service of state.services) {
44
+ for (let i = 0; i < service.count; i++) {
45
+ const suffix = service.count > 1 ? `-${i + 1}` : "";
46
+ const name = service.isLead ? "lead" : `worker-${service.role}${suffix}`;
47
+ ids[name] = randomUUID();
48
+ }
49
+ }
50
+ setAgentIds(ids);
51
+
52
+ // Find available port (prefer 3013)
53
+ const port = await findAvailablePort(3013);
54
+ setApiPort(port);
55
+
56
+ const masked = `${key.slice(0, 4)}...${key.slice(-4)}`;
57
+ addLog(`Generated API key: ${masked}`);
58
+ addLog(`Generated ${Object.keys(ids).length} agent ID(s)`);
59
+ addLog(`API port: ${port}${port !== 3013 ? " (3013 was in use)" : ""}`);
60
+
61
+ setTimeout(() => setReady(true), 1000);
62
+ };
63
+
64
+ generate();
65
+ }, [state.services, addLog]);
66
+
67
+ useEffect(() => {
68
+ if (!ready) return;
69
+ goToNext({ apiKey, agentIds, apiPort });
70
+ }, [ready, apiKey, agentIds, apiPort, goToNext]);
71
+
72
+ const idEntries = Object.entries(agentIds);
73
+
74
+ return (
75
+ <Box flexDirection="column" padding={1}>
76
+ <Text bold>Generating credentials...</Text>
77
+ {apiKey && (
78
+ <Box marginTop={1} flexDirection="column">
79
+ <Text>
80
+ API Key:{" "}
81
+ <Text color="green">
82
+ {apiKey.slice(0, 4)}...{apiKey.slice(-4)}
83
+ </Text>
84
+ </Text>
85
+ {apiPort > 0 && (
86
+ <Text>
87
+ API Port: <Text color="green">{apiPort}</Text>
88
+ {apiPort !== 3013 && <Text dimColor> (3013 was in use)</Text>}
89
+ </Text>
90
+ )}
91
+ {idEntries.length > 0 && (
92
+ <Box flexDirection="column" marginTop={1}>
93
+ <Text>Agent IDs:</Text>
94
+ {idEntries.map(([label, id]) => (
95
+ <Text key={id}>
96
+ {" "}
97
+ {label}: <Text dimColor>{id}</Text>
98
+ </Text>
99
+ ))}
100
+ </Box>
101
+ )}
102
+ </Box>
103
+ )}
104
+ {!ready && (
105
+ <Box marginTop={1}>
106
+ <Spinner label="Preparing next step..." />
107
+ </Box>
108
+ )}
109
+ </Box>
110
+ );
111
+ }
@@ -0,0 +1,168 @@
1
+ import { Select } from "@inkjs/ui";
2
+ import { Box, Text } from "ink";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import type { TemplateConfig } from "../../../../templates/schema.ts";
5
+ import { fetchTemplateList } from "../templates.ts";
6
+ import type { ServiceEntry, StepProps } from "../types.ts";
7
+
8
+ type SubStep = "loading" | "picking" | "confirming";
9
+
10
+ export function CustomTemplatesStep({
11
+ state: _state,
12
+ dryRun,
13
+ addLog,
14
+ goToNext,
15
+ goToError,
16
+ }: StepProps) {
17
+ const [subStep, setSubStep] = useState<SubStep>("loading");
18
+ const [templates, setTemplates] = useState<TemplateConfig[]>([]);
19
+ const [services, setServices] = useState<ServiceEntry[]>([]);
20
+ const fetchedRef = useRef(false);
21
+
22
+ // Fetch templates on mount
23
+ useEffect(() => {
24
+ if (fetchedRef.current) return;
25
+ fetchedRef.current = true;
26
+
27
+ const load = async () => {
28
+ addLog("Fetching templates from registry...");
29
+ try {
30
+ const list = await fetchTemplateList();
31
+ if (list.length === 0) {
32
+ goToError("No templates found in the registry.");
33
+ return;
34
+ }
35
+ setTemplates(list);
36
+ setSubStep("picking");
37
+ addLog(`Found ${list.length} templates`);
38
+ } catch (err) {
39
+ goToError(err instanceof Error ? err.message : String(err));
40
+ }
41
+ };
42
+
43
+ load();
44
+ }, [addLog, goToError]);
45
+
46
+ if (subStep === "loading") {
47
+ return (
48
+ <Box flexDirection="column" padding={1}>
49
+ <Text dimColor>Loading templates from registry...</Text>
50
+ </Box>
51
+ );
52
+ }
53
+
54
+ if (subStep === "picking") {
55
+ const leadTemplates = templates.filter((t) => t.agentDefaults.isLead);
56
+ const workerTemplates = templates.filter((t) => !t.agentDefaults.isLead);
57
+
58
+ const options = [
59
+ ...leadTemplates.map((t) => ({
60
+ label: `[Lead] ${t.displayName} — ${t.description}`,
61
+ value: t.name,
62
+ })),
63
+ ...workerTemplates.map((t) => ({
64
+ label: `${t.displayName} — ${t.description}`,
65
+ value: t.name,
66
+ })),
67
+ ];
68
+
69
+ return (
70
+ <Box flexDirection="column" padding={1}>
71
+ {services.length > 0 && (
72
+ <Box flexDirection="column" marginBottom={1}>
73
+ <Text bold>Selected services:</Text>
74
+ {services.map((s) => (
75
+ <Text key={s.template}>
76
+ {" "}- {s.displayName} ({s.template}){s.isLead ? " [lead]" : ""}
77
+ </Text>
78
+ ))}
79
+ </Box>
80
+ )}
81
+ <Text bold>Add a service template{services.length > 0 ? " (or select Done)" : ""}:</Text>
82
+ <Box marginTop={1}>
83
+ <Select
84
+ options={[
85
+ ...(services.length > 0
86
+ ? [{ label: "Done — finish selecting", value: "__done__" }]
87
+ : []),
88
+ ...options,
89
+ ]}
90
+ onChange={(value) => {
91
+ if (value === "__done__") {
92
+ setSubStep("confirming");
93
+ return;
94
+ }
95
+
96
+ const tpl = templates.find((t) => t.name === value);
97
+ if (!tpl) return;
98
+
99
+ // Avoid adding the same template twice
100
+ if (services.some((s) => s.template === tpl.name)) {
101
+ addLog(`Template "${tpl.displayName}" is already selected.`);
102
+ return;
103
+ }
104
+
105
+ const entry: ServiceEntry = {
106
+ template: tpl.name,
107
+ displayName: tpl.displayName,
108
+ count: 1,
109
+ role: tpl.agentDefaults.role,
110
+ isLead: tpl.agentDefaults.isLead ?? false,
111
+ };
112
+
113
+ setServices((prev) => [...prev, entry]);
114
+ addLog(`Added: ${tpl.displayName}`);
115
+ }}
116
+ />
117
+ </Box>
118
+ </Box>
119
+ );
120
+ }
121
+
122
+ if (subStep === "confirming") {
123
+ const hasLead = services.some((s) => s.isLead);
124
+
125
+ return (
126
+ <Box flexDirection="column" padding={1}>
127
+ <Box flexDirection="column" marginBottom={1}>
128
+ <Text bold>Selected services:</Text>
129
+ {services.map((s) => (
130
+ <Text key={s.template}>
131
+ {" "}- {s.displayName} ({s.template}){s.isLead ? " [lead]" : ""}
132
+ </Text>
133
+ ))}
134
+ </Box>
135
+ {!hasLead && (
136
+ <Box marginBottom={1}>
137
+ <Text color="yellow">
138
+ Warning: No lead agent selected. A lead coordinates task delegation.
139
+ </Text>
140
+ </Box>
141
+ )}
142
+ <Text bold>Confirm selection?</Text>
143
+ <Box marginTop={1}>
144
+ <Select
145
+ options={[
146
+ { label: "Confirm and continue", value: "confirm" },
147
+ { label: "Go back and add more", value: "back" },
148
+ ]}
149
+ onChange={(value) => {
150
+ if (value === "back") {
151
+ setSubStep("picking");
152
+ return;
153
+ }
154
+ addLog(
155
+ dryRun
156
+ ? `[DRY-RUN] Would use ${services.length} custom templates`
157
+ : `Using ${services.length} custom templates`,
158
+ );
159
+ goToNext({ services });
160
+ }}
161
+ />
162
+ </Box>
163
+ </Box>
164
+ );
165
+ }
166
+
167
+ return null;
168
+ }
@@ -0,0 +1,154 @@
1
+ import { Spinner } from "@inkjs/ui";
2
+ import { Box, Text } from "ink";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { generateCompose } from "../compose-generator.ts";
5
+ import { generateEnv } from "../env-generator.ts";
6
+ import type { StepProps } from "../types.ts";
7
+
8
+ interface ManifestConfig {
9
+ presetId: string | null;
10
+ deployType: string;
11
+ harness: string;
12
+ services: { template: string; displayName: string; count: number; role: string }[];
13
+ integrations: Record<string, boolean>;
14
+ agentIds: Record<string, string>;
15
+ createdAt: string;
16
+ }
17
+
18
+ function generateManifest(state: {
19
+ presetId: string | null;
20
+ deployType: string;
21
+ harness: string;
22
+ services: { template: string; displayName: string; count: number; role: string }[];
23
+ integrations: Record<string, boolean>;
24
+ agentIds: Record<string, string>;
25
+ }): ManifestConfig {
26
+ return {
27
+ presetId: state.presetId,
28
+ deployType: state.deployType,
29
+ harness: state.harness,
30
+ services: state.services.map((s) => ({
31
+ template: s.template,
32
+ displayName: s.displayName,
33
+ count: s.count,
34
+ role: s.role,
35
+ })),
36
+ integrations: { ...state.integrations },
37
+ agentIds: { ...state.agentIds },
38
+ createdAt: new Date().toISOString(),
39
+ };
40
+ }
41
+
42
+ export function GenerateStep({ state, dryRun, addLog, goToNext, goToStep, goToError }: StepProps) {
43
+ const executedRef = useRef(false);
44
+ const [composePreview, setComposePreview] = useState<string | null>(null);
45
+ const [envPreview, setEnvPreview] = useState<string | null>(null);
46
+ const [done, setDone] = useState(false);
47
+
48
+ useEffect(() => {
49
+ if (executedRef.current) return;
50
+ executedRef.current = true;
51
+
52
+ const run = async () => {
53
+ const composeContent = generateCompose(state);
54
+ const envContent = generateEnv(state);
55
+ const manifest = generateManifest(state);
56
+
57
+ if (dryRun) {
58
+ const composeLines = composeContent.split("\n").slice(0, 30).join("\n");
59
+ const envLines = envContent.split("\n").slice(0, 20).join("\n");
60
+ setComposePreview(composeLines);
61
+ setEnvPreview(envLines);
62
+
63
+ addLog("Write docker-compose.yml", true);
64
+ addLog("Write .env", true);
65
+ addLog("Write .agent-swarm/config.json", true);
66
+ // In dry-run, skip prereq/start/health — go straight to done
67
+ goToStep("done");
68
+ return;
69
+ }
70
+
71
+ // Write docker-compose.yml
72
+ const composePath = `${state.outputDir}/docker-compose.yml`;
73
+ await Bun.write(composePath, composeContent);
74
+ addLog(`Wrote ${composePath}`);
75
+
76
+ // Write .env
77
+ const envPath = `${state.outputDir}/.env`;
78
+ await Bun.write(envPath, envContent);
79
+ addLog(`Wrote ${envPath}`);
80
+
81
+ // Create .agent-swarm/ dir and write config.json
82
+ await Bun.$`mkdir -p ${state.outputDir}/.agent-swarm`;
83
+ const manifestPath = `${state.outputDir}/.agent-swarm/config.json`;
84
+ await Bun.write(manifestPath, JSON.stringify(manifest, null, 2));
85
+ addLog(`Wrote ${manifestPath}`);
86
+
87
+ // Add to .gitignore if in a git repo
88
+ try {
89
+ const result = await Bun.$`git -C ${state.outputDir} rev-parse --show-toplevel`.quiet();
90
+ if (result.exitCode === 0) {
91
+ const gitRoot = result.text().trim();
92
+ const gitignorePath = `${gitRoot}/.gitignore`;
93
+ const gitignoreFile = Bun.file(gitignorePath);
94
+
95
+ let content = "";
96
+ if (await gitignoreFile.exists()) {
97
+ content = await gitignoreFile.text();
98
+ }
99
+
100
+ const entriesToAdd: string[] = [];
101
+ if (!content.includes(".env")) {
102
+ entriesToAdd.push(".env");
103
+ }
104
+ if (!content.includes(".agent-swarm/")) {
105
+ entriesToAdd.push(".agent-swarm/");
106
+ }
107
+
108
+ if (entriesToAdd.length > 0) {
109
+ const block = `\n# Added by agent-swarm onboard\n${entriesToAdd.join("\n")}\n`;
110
+ await Bun.write(gitignorePath, content + block);
111
+ addLog(`Added to .gitignore: ${entriesToAdd.join(", ")}`);
112
+ }
113
+ }
114
+ } catch {
115
+ // Not a git repo — skip
116
+ }
117
+
118
+ setDone(true);
119
+ };
120
+
121
+ run().catch((err) => goToError(String(err)));
122
+ }, [state, dryRun, addLog, goToStep, goToError]);
123
+
124
+ useEffect(() => {
125
+ if (!done) return;
126
+ goToNext();
127
+ }, [done, goToNext]);
128
+
129
+ if (dryRun && composePreview != null && envPreview != null) {
130
+ return (
131
+ <Box flexDirection="column" padding={1}>
132
+ <Text bold color="yellow">
133
+ DRY-RUN — File previews:
134
+ </Text>
135
+
136
+ <Box marginTop={1} flexDirection="column">
137
+ <Text bold>docker-compose.yml (first 30 lines):</Text>
138
+ <Text dimColor>{composePreview}</Text>
139
+ </Box>
140
+
141
+ <Box marginTop={1} flexDirection="column">
142
+ <Text bold>.env (first 20 lines):</Text>
143
+ <Text dimColor>{envPreview}</Text>
144
+ </Box>
145
+ </Box>
146
+ );
147
+ }
148
+
149
+ return (
150
+ <Box flexDirection="column" padding={1}>
151
+ <Spinner label="Generating files..." />
152
+ </Box>
153
+ );
154
+ }
@@ -0,0 +1,195 @@
1
+ import { Select, TextInput } from "@inkjs/ui";
2
+ import { Box, Text } from "ink";
3
+ import { useEffect, useState } from "react";
4
+ import type { StepProps } from "../types.ts";
5
+
6
+ type SubStep =
7
+ | "choose_method"
8
+ | "running_cli"
9
+ | "confirm_token"
10
+ | "manual_oauth"
11
+ | "manual_api_key";
12
+
13
+ const TOKEN_REGEX = /sk-ant-oat[^\s]+/;
14
+
15
+ export function HarnessCredentialsStep({ goToNext, addLog }: StepProps) {
16
+ const [subStep, setSubStep] = useState<SubStep>("choose_method");
17
+ const [cliOutput, setCliOutput] = useState("");
18
+ const [parsedToken, setParsedToken] = useState("");
19
+ const [cliError, setCliError] = useState("");
20
+
21
+ // Run CLI when entering running_cli
22
+ useEffect(() => {
23
+ if (subStep !== "running_cli") return;
24
+
25
+ let cancelled = false;
26
+
27
+ (async () => {
28
+ try {
29
+ const result = await Bun.$`claude setup-token`.quiet();
30
+ if (cancelled) return;
31
+
32
+ const output = result.text().trim();
33
+ setCliOutput(output);
34
+
35
+ if (result.exitCode !== 0) {
36
+ addLog("claude setup-token exited with a non-zero code");
37
+ setCliError("Command exited with a non-zero code. Is Claude CLI installed?");
38
+ setSubStep("manual_oauth");
39
+ return;
40
+ }
41
+
42
+ const match = output.match(TOKEN_REGEX);
43
+ if (match) {
44
+ addLog("Token detected from claude setup-token output");
45
+ setParsedToken(match[0]);
46
+ setSubStep("confirm_token");
47
+ } else {
48
+ addLog("claude setup-token completed but no token found in output");
49
+ setSubStep("manual_oauth");
50
+ }
51
+ } catch (err) {
52
+ if (cancelled) return;
53
+ const msg = err instanceof Error ? err.message : String(err);
54
+ addLog(`Failed to run claude setup-token: ${msg}`);
55
+ setCliError(msg);
56
+ setSubStep("manual_oauth");
57
+ }
58
+ })();
59
+
60
+ return () => {
61
+ cancelled = true;
62
+ };
63
+ }, [subStep, addLog]);
64
+
65
+ if (subStep === "choose_method") {
66
+ return (
67
+ <Box flexDirection="column" padding={1}>
68
+ <Text bold>How would you like to provide credentials?</Text>
69
+ <Box marginTop={1}>
70
+ <Select
71
+ options={[
72
+ {
73
+ label: "Run `claude setup-token` (recommended)",
74
+ value: "setup_token",
75
+ },
76
+ { label: "Paste OAuth token manually", value: "manual_oauth" },
77
+ { label: "Provide ANTHROPIC_API_KEY", value: "manual_api_key" },
78
+ ]}
79
+ onChange={(value) => {
80
+ if (value === "setup_token") {
81
+ setSubStep("running_cli");
82
+ } else if (value === "manual_oauth") {
83
+ setSubStep("manual_oauth");
84
+ } else if (value === "manual_api_key") {
85
+ setSubStep("manual_api_key");
86
+ }
87
+ }}
88
+ />
89
+ </Box>
90
+ </Box>
91
+ );
92
+ }
93
+
94
+ if (subStep === "running_cli") {
95
+ return (
96
+ <Box flexDirection="column" padding={1}>
97
+ <Text>
98
+ Running <Text color="cyan">claude setup-token</Text>...
99
+ </Text>
100
+ <Text dimColor>This may take a moment.</Text>
101
+ </Box>
102
+ );
103
+ }
104
+
105
+ if (subStep === "confirm_token") {
106
+ const masked = `${parsedToken.slice(0, 14)}...${parsedToken.slice(-4)}`;
107
+ return (
108
+ <Box flexDirection="column" padding={1}>
109
+ <Text bold>Token detected from CLI output:</Text>
110
+ <Text color="green">{masked}</Text>
111
+ {cliOutput ? (
112
+ <Box marginTop={1}>
113
+ <Text dimColor>CLI output: {cliOutput.slice(0, 200)}</Text>
114
+ </Box>
115
+ ) : null}
116
+ <Box marginTop={1}>
117
+ <Select
118
+ options={[
119
+ { label: "Use this token", value: "use" },
120
+ { label: "Paste manually instead", value: "manual" },
121
+ ]}
122
+ onChange={(value) => {
123
+ if (value === "use") {
124
+ addLog("Claude OAuth token collected via CLI");
125
+ goToNext({
126
+ claudeOAuthToken: parsedToken,
127
+ anthropicApiKey: "",
128
+ credentialType: "oauth",
129
+ });
130
+ } else {
131
+ setSubStep("manual_oauth");
132
+ }
133
+ }}
134
+ />
135
+ </Box>
136
+ </Box>
137
+ );
138
+ }
139
+
140
+ if (subStep === "manual_oauth") {
141
+ return (
142
+ <Box flexDirection="column" padding={1}>
143
+ {cliError ? (
144
+ <Box marginBottom={1} flexDirection="column">
145
+ <Text color="red">Could not run claude setup-token: {cliError}</Text>
146
+ <Text dimColor>Falling back to manual token entry.</Text>
147
+ </Box>
148
+ ) : null}
149
+ <Text bold>Paste your CLAUDE_CODE_OAUTH_TOKEN:</Text>
150
+ <TextInput
151
+ placeholder="sk-ant-oat..."
152
+ onSubmit={(value) => {
153
+ const trimmed = value.trim();
154
+ if (!trimmed) {
155
+ addLog("Token cannot be empty.");
156
+ return;
157
+ }
158
+ addLog("Claude OAuth token collected");
159
+ goToNext({
160
+ claudeOAuthToken: trimmed,
161
+ anthropicApiKey: "",
162
+ credentialType: "oauth",
163
+ });
164
+ }}
165
+ />
166
+ </Box>
167
+ );
168
+ }
169
+
170
+ if (subStep === "manual_api_key") {
171
+ return (
172
+ <Box flexDirection="column" padding={1}>
173
+ <Text bold>Paste your ANTHROPIC_API_KEY:</Text>
174
+ <TextInput
175
+ placeholder="sk-ant-api..."
176
+ onSubmit={(value) => {
177
+ const trimmed = value.trim();
178
+ if (!trimmed) {
179
+ addLog("API key cannot be empty.");
180
+ return;
181
+ }
182
+ addLog("Anthropic API key collected");
183
+ goToNext({
184
+ claudeOAuthToken: "",
185
+ anthropicApiKey: trimmed,
186
+ credentialType: "api_key",
187
+ });
188
+ }}
189
+ />
190
+ </Box>
191
+ );
192
+ }
193
+
194
+ return null;
195
+ }
@@ -0,0 +1,21 @@
1
+ import { Select } from "@inkjs/ui";
2
+ import { Box, Text } from "ink";
3
+ import type { StepProps } from "../types.ts";
4
+
5
+ export function HarnessStep({ goToNext, addLog }: StepProps) {
6
+ return (
7
+ <Box flexDirection="column" padding={1}>
8
+ <Text bold>Which harness should run your agents?</Text>
9
+ <Box marginTop={1}>
10
+ <Select
11
+ options={[{ label: "Claude Code (Recommended)", value: "claude" }]}
12
+ onChange={() => {
13
+ addLog("Harness: Claude Code");
14
+ goToNext({ harness: "claude" });
15
+ }}
16
+ />
17
+ </Box>
18
+ <Text dimColor>Pi-mono — Coming soon</Text>
19
+ </Box>
20
+ );
21
+ }