@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,193 @@
1
+ export interface MemoryChunk {
2
+ content: string;
3
+ chunkIndex: number;
4
+ totalChunks: number;
5
+ headings: string[];
6
+ }
7
+
8
+ const MAX_CHUNK_SIZE = 2000; // ~500 tokens
9
+ const CHUNK_OVERLAP = 100; // chars
10
+ const MIN_CHUNK_SIZE = 50; // skip trivially small chunks
11
+
12
+ /**
13
+ * Two-stage markdown-aware content chunker.
14
+ * Stage 1: Split by markdown headers (#, ##, ###) to preserve document structure.
15
+ * Stage 2: If any section exceeds MAX_CHUNK_SIZE, apply recursive character splitting.
16
+ * Small files (< MAX_CHUNK_SIZE) are returned as a single chunk.
17
+ */
18
+ export function chunkContent(text: string): MemoryChunk[] {
19
+ const trimmed = text.trim();
20
+ if (!trimmed || trimmed.length < MIN_CHUNK_SIZE) {
21
+ return [];
22
+ }
23
+
24
+ // Small content: single chunk
25
+ if (trimmed.length <= MAX_CHUNK_SIZE) {
26
+ return [{ content: trimmed, chunkIndex: 0, totalChunks: 1, headings: [] }];
27
+ }
28
+
29
+ // Stage 1: Split by markdown headers
30
+ const sections = splitByHeaders(trimmed);
31
+
32
+ // Stage 2: Split oversized sections
33
+ const rawChunks: { content: string; headings: string[] }[] = [];
34
+ for (const section of sections) {
35
+ if (section.content.length <= MAX_CHUNK_SIZE) {
36
+ rawChunks.push(section);
37
+ } else {
38
+ const subChunks = recursiveSplit(section.content);
39
+ for (const sub of subChunks) {
40
+ rawChunks.push({ content: sub, headings: section.headings });
41
+ }
42
+ }
43
+ }
44
+
45
+ // Filter out trivially small chunks and build final result
46
+ const filtered = rawChunks.filter((c) => c.content.trim().length >= MIN_CHUNK_SIZE);
47
+ if (filtered.length === 0) {
48
+ return [{ content: trimmed, chunkIndex: 0, totalChunks: 1, headings: [] }];
49
+ }
50
+
51
+ return filtered.map((c, i) => ({
52
+ content: c.headings.length > 0 ? `${c.headings.join(" > ")}\n\n${c.content}` : c.content,
53
+ chunkIndex: i,
54
+ totalChunks: filtered.length,
55
+ headings: c.headings,
56
+ }));
57
+ }
58
+
59
+ interface Section {
60
+ content: string;
61
+ headings: string[];
62
+ }
63
+
64
+ function splitByHeaders(text: string): Section[] {
65
+ const lines = text.split("\n");
66
+ const sections: Section[] = [];
67
+ let currentContent: string[] = [];
68
+ const headingStack: string[] = [];
69
+
70
+ for (const line of lines) {
71
+ const headingMatch = line.match(/^(#{1,3})\s+(.+)$/);
72
+ if (headingMatch) {
73
+ // Flush current section
74
+ if (currentContent.length > 0) {
75
+ const content = currentContent.join("\n").trim();
76
+ if (content) {
77
+ sections.push({ content, headings: [...headingStack] });
78
+ }
79
+ currentContent = [];
80
+ }
81
+
82
+ const level = headingMatch[1]!.length;
83
+ const title = headingMatch[2]!.trim();
84
+
85
+ // Update heading stack: pop everything at or below this level
86
+ while (headingStack.length >= level) {
87
+ headingStack.pop();
88
+ }
89
+ headingStack.push(`${"#".repeat(level)} ${title}`);
90
+ } else {
91
+ currentContent.push(line);
92
+ }
93
+ }
94
+
95
+ // Flush remaining content
96
+ if (currentContent.length > 0) {
97
+ const content = currentContent.join("\n").trim();
98
+ if (content) {
99
+ sections.push({ content, headings: [...headingStack] });
100
+ }
101
+ }
102
+
103
+ // If no headers found, return as single section
104
+ if (sections.length === 0) {
105
+ return [{ content: text, headings: [] }];
106
+ }
107
+
108
+ return sections;
109
+ }
110
+
111
+ const SEPARATORS = ["\n\n", "\n", ". ", " "];
112
+
113
+ function recursiveSplit(text: string): string[] {
114
+ return recursiveSplitWithSeparators(text, 0);
115
+ }
116
+
117
+ function recursiveSplitWithSeparators(text: string, separatorIndex: number): string[] {
118
+ if (text.length <= MAX_CHUNK_SIZE) {
119
+ return [text.trim()].filter((s) => s.length > 0);
120
+ }
121
+
122
+ if (separatorIndex >= SEPARATORS.length) {
123
+ // Last resort: hard split at MAX_CHUNK_SIZE with overlap
124
+ return hardSplit(text);
125
+ }
126
+
127
+ const separator = SEPARATORS[separatorIndex]!;
128
+ const parts = text.split(separator);
129
+
130
+ if (parts.length <= 1) {
131
+ // This separator doesn't split; try next
132
+ return recursiveSplitWithSeparators(text, separatorIndex + 1);
133
+ }
134
+
135
+ const chunks: string[] = [];
136
+ let current = "";
137
+
138
+ for (const part of parts) {
139
+ const candidate = current ? current + separator + part : part;
140
+ if (candidate.length <= MAX_CHUNK_SIZE) {
141
+ current = candidate;
142
+ } else {
143
+ if (current) {
144
+ chunks.push(current.trim());
145
+ }
146
+ // If part itself is too big, recursively split it
147
+ if (part.length > MAX_CHUNK_SIZE) {
148
+ chunks.push(...recursiveSplitWithSeparators(part, separatorIndex + 1));
149
+ current = "";
150
+ } else {
151
+ current = part;
152
+ }
153
+ }
154
+ }
155
+
156
+ if (current.trim()) {
157
+ chunks.push(current.trim());
158
+ }
159
+
160
+ // Add overlap between chunks
161
+ return addOverlap(chunks, text);
162
+ }
163
+
164
+ function hardSplit(text: string): string[] {
165
+ const chunks: string[] = [];
166
+ let start = 0;
167
+ while (start < text.length) {
168
+ const end = Math.min(start + MAX_CHUNK_SIZE, text.length);
169
+ chunks.push(text.slice(start, end).trim());
170
+ start = end - CHUNK_OVERLAP;
171
+ if (start >= text.length - MIN_CHUNK_SIZE) break;
172
+ }
173
+ return chunks.filter((c) => c.length > 0);
174
+ }
175
+
176
+ function addOverlap(chunks: string[], _originalText: string): string[] {
177
+ if (chunks.length <= 1) return chunks;
178
+
179
+ const result: string[] = [chunks[0]!];
180
+ for (let i = 1; i < chunks.length; i++) {
181
+ const prevChunk = chunks[i - 1]!;
182
+ const chunk = chunks[i]!;
183
+ // Take the last CHUNK_OVERLAP chars from previous chunk as prefix
184
+ const overlapText = prevChunk.slice(-CHUNK_OVERLAP);
185
+ // Only add overlap if it doesn't make the chunk too long
186
+ if (overlapText.length + chunk.length <= MAX_CHUNK_SIZE + CHUNK_OVERLAP) {
187
+ result.push(overlapText + chunk);
188
+ } else {
189
+ result.push(chunk);
190
+ }
191
+ }
192
+ return result;
193
+ }
@@ -0,0 +1,90 @@
1
+ import type { OAuthApp, OAuthTokens } from "../../tracker/types";
2
+ import { getDb } from "../db";
3
+
4
+ // ── OAuth Apps ──
5
+
6
+ export function getOAuthApp(provider: string): OAuthApp | null {
7
+ return getDb()
8
+ .query("SELECT * FROM oauth_apps WHERE provider = ?")
9
+ .get(provider) as OAuthApp | null;
10
+ }
11
+
12
+ export function upsertOAuthApp(
13
+ provider: string,
14
+ data: {
15
+ clientId: string;
16
+ clientSecret: string;
17
+ authorizeUrl: string;
18
+ tokenUrl: string;
19
+ redirectUri: string;
20
+ scopes: string;
21
+ metadata?: string;
22
+ },
23
+ ): void {
24
+ getDb()
25
+ .query(
26
+ `INSERT INTO oauth_apps (provider, clientId, clientSecret, authorizeUrl, tokenUrl, redirectUri, scopes, metadata)
27
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
28
+ ON CONFLICT(provider) DO UPDATE SET
29
+ clientId = excluded.clientId,
30
+ clientSecret = excluded.clientSecret,
31
+ authorizeUrl = excluded.authorizeUrl,
32
+ tokenUrl = excluded.tokenUrl,
33
+ redirectUri = excluded.redirectUri,
34
+ scopes = excluded.scopes,
35
+ metadata = excluded.metadata,
36
+ updatedAt = datetime('now')`,
37
+ )
38
+ .run(
39
+ provider,
40
+ data.clientId,
41
+ data.clientSecret,
42
+ data.authorizeUrl,
43
+ data.tokenUrl,
44
+ data.redirectUri,
45
+ data.scopes,
46
+ data.metadata ?? "{}",
47
+ );
48
+ }
49
+
50
+ // ── OAuth Tokens ──
51
+
52
+ export function getOAuthTokens(provider: string): OAuthTokens | null {
53
+ return getDb()
54
+ .query("SELECT * FROM oauth_tokens WHERE provider = ?")
55
+ .get(provider) as OAuthTokens | null;
56
+ }
57
+
58
+ export function storeOAuthTokens(
59
+ provider: string,
60
+ data: {
61
+ accessToken: string;
62
+ refreshToken?: string | null;
63
+ expiresAt: string;
64
+ scope?: string | null;
65
+ },
66
+ ): void {
67
+ getDb()
68
+ .query(
69
+ `INSERT INTO oauth_tokens (provider, accessToken, refreshToken, expiresAt, scope)
70
+ VALUES (?, ?, ?, ?, ?)
71
+ ON CONFLICT(provider) DO UPDATE SET
72
+ accessToken = excluded.accessToken,
73
+ refreshToken = COALESCE(excluded.refreshToken, oauth_tokens.refreshToken),
74
+ expiresAt = excluded.expiresAt,
75
+ scope = COALESCE(excluded.scope, oauth_tokens.scope),
76
+ updatedAt = datetime('now')`,
77
+ )
78
+ .run(provider, data.accessToken, data.refreshToken ?? null, data.expiresAt, data.scope ?? null);
79
+ }
80
+
81
+ export function deleteOAuthTokens(provider: string): void {
82
+ getDb().query("DELETE FROM oauth_tokens WHERE provider = ?").run(provider);
83
+ }
84
+
85
+ export function isTokenExpiringSoon(provider: string, bufferMs = 5 * 60 * 1000): boolean {
86
+ const tokens = getOAuthTokens(provider);
87
+ if (!tokens) return true;
88
+ const expiresAt = new Date(tokens.expiresAt).getTime();
89
+ return expiresAt - Date.now() < bufferMs;
90
+ }
@@ -0,0 +1,182 @@
1
+ import type { TrackerAgentMapping, TrackerSync } from "../../tracker/types";
2
+ import { getDb } from "../db";
3
+
4
+ // ── Tracker Sync ──
5
+
6
+ export function getTrackerSync(
7
+ provider: string,
8
+ entityType: "task" | "epic",
9
+ swarmId: string,
10
+ ): TrackerSync | null {
11
+ return getDb()
12
+ .query("SELECT * FROM tracker_sync WHERE provider = ? AND entityType = ? AND swarmId = ?")
13
+ .get(provider, entityType, swarmId) as TrackerSync | null;
14
+ }
15
+
16
+ export function getTrackerSyncByExternalId(
17
+ provider: string,
18
+ entityType: "task" | "epic",
19
+ externalId: string,
20
+ ): TrackerSync | null {
21
+ return getDb()
22
+ .query("SELECT * FROM tracker_sync WHERE provider = ? AND entityType = ? AND externalId = ?")
23
+ .get(provider, entityType, externalId) as TrackerSync | null;
24
+ }
25
+
26
+ export function createTrackerSync(data: {
27
+ provider: string;
28
+ entityType: "task" | "epic";
29
+ providerEntityType?: string | null;
30
+ swarmId: string;
31
+ externalId: string;
32
+ externalIdentifier?: string | null;
33
+ externalUrl?: string | null;
34
+ lastSyncOrigin?: "swarm" | "external" | null;
35
+ lastDeliveryId?: string | null;
36
+ syncDirection?: "inbound" | "outbound" | "bidirectional";
37
+ }): TrackerSync {
38
+ const result = getDb()
39
+ .query(
40
+ `INSERT INTO tracker_sync (provider, entityType, providerEntityType, swarmId, externalId, externalIdentifier, externalUrl, lastSyncOrigin, lastDeliveryId, syncDirection)
41
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
42
+ RETURNING *`,
43
+ )
44
+ .get(
45
+ data.provider,
46
+ data.entityType,
47
+ data.providerEntityType ?? null,
48
+ data.swarmId,
49
+ data.externalId,
50
+ data.externalIdentifier ?? null,
51
+ data.externalUrl ?? null,
52
+ data.lastSyncOrigin ?? null,
53
+ data.lastDeliveryId ?? null,
54
+ data.syncDirection ?? "inbound",
55
+ ) as TrackerSync;
56
+ return result;
57
+ }
58
+
59
+ export function updateTrackerSync(
60
+ id: string,
61
+ data: Partial<
62
+ Pick<
63
+ TrackerSync,
64
+ | "lastSyncedAt"
65
+ | "lastSyncOrigin"
66
+ | "lastDeliveryId"
67
+ | "syncDirection"
68
+ | "externalUrl"
69
+ | "externalIdentifier"
70
+ >
71
+ >,
72
+ ): void {
73
+ const sets: string[] = [];
74
+ const values: (string | null)[] = [];
75
+
76
+ if (data.lastSyncedAt !== undefined) {
77
+ sets.push("lastSyncedAt = ?");
78
+ values.push(data.lastSyncedAt);
79
+ }
80
+ if (data.lastSyncOrigin !== undefined) {
81
+ sets.push("lastSyncOrigin = ?");
82
+ values.push(data.lastSyncOrigin);
83
+ }
84
+ if (data.lastDeliveryId !== undefined) {
85
+ sets.push("lastDeliveryId = ?");
86
+ values.push(data.lastDeliveryId);
87
+ }
88
+ if (data.syncDirection !== undefined) {
89
+ sets.push("syncDirection = ?");
90
+ values.push(data.syncDirection);
91
+ }
92
+ if (data.externalUrl !== undefined) {
93
+ sets.push("externalUrl = ?");
94
+ values.push(data.externalUrl);
95
+ }
96
+ if (data.externalIdentifier !== undefined) {
97
+ sets.push("externalIdentifier = ?");
98
+ values.push(data.externalIdentifier);
99
+ }
100
+
101
+ if (sets.length === 0) return;
102
+
103
+ values.push(id);
104
+ getDb()
105
+ .query(`UPDATE tracker_sync SET ${sets.join(", ")} WHERE id = ?`)
106
+ .run(...values);
107
+ }
108
+
109
+ export function deleteTrackerSync(id: string): void {
110
+ getDb().query("DELETE FROM tracker_sync WHERE id = ?").run(id);
111
+ }
112
+
113
+ export function getAllTrackerSyncs(provider?: string, entityType?: "task" | "epic"): TrackerSync[] {
114
+ const conditions: string[] = [];
115
+ const values: string[] = [];
116
+
117
+ if (provider) {
118
+ conditions.push("provider = ?");
119
+ values.push(provider);
120
+ }
121
+ if (entityType) {
122
+ conditions.push("entityType = ?");
123
+ values.push(entityType);
124
+ }
125
+
126
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
127
+ return getDb()
128
+ .query(`SELECT * FROM tracker_sync ${where} ORDER BY createdAt DESC`)
129
+ .all(...values) as TrackerSync[];
130
+ }
131
+
132
+ // ── Tracker Agent Mapping ──
133
+
134
+ export function getTrackerAgentMapping(
135
+ provider: string,
136
+ agentId: string,
137
+ ): TrackerAgentMapping | null {
138
+ return getDb()
139
+ .query("SELECT * FROM tracker_agent_mapping WHERE provider = ? AND agentId = ?")
140
+ .get(provider, agentId) as TrackerAgentMapping | null;
141
+ }
142
+
143
+ export function getTrackerAgentMappingByExternalUser(
144
+ provider: string,
145
+ externalUserId: string,
146
+ ): TrackerAgentMapping | null {
147
+ return getDb()
148
+ .query("SELECT * FROM tracker_agent_mapping WHERE provider = ? AND externalUserId = ?")
149
+ .get(provider, externalUserId) as TrackerAgentMapping | null;
150
+ }
151
+
152
+ export function createTrackerAgentMapping(data: {
153
+ provider: string;
154
+ agentId: string;
155
+ externalUserId: string;
156
+ agentName: string;
157
+ }): TrackerAgentMapping {
158
+ return getDb()
159
+ .query(
160
+ `INSERT INTO tracker_agent_mapping (provider, agentId, externalUserId, agentName)
161
+ VALUES (?, ?, ?, ?)
162
+ RETURNING *`,
163
+ )
164
+ .get(data.provider, data.agentId, data.externalUserId, data.agentName) as TrackerAgentMapping;
165
+ }
166
+
167
+ export function deleteTrackerAgentMapping(provider: string, agentId: string): void {
168
+ getDb()
169
+ .query("DELETE FROM tracker_agent_mapping WHERE provider = ? AND agentId = ?")
170
+ .run(provider, agentId);
171
+ }
172
+
173
+ export function getAllTrackerAgentMappings(provider?: string): TrackerAgentMapping[] {
174
+ if (provider) {
175
+ return getDb()
176
+ .query("SELECT * FROM tracker_agent_mapping WHERE provider = ? ORDER BY createdAt DESC")
177
+ .all(provider) as TrackerAgentMapping[];
178
+ }
179
+ return getDb()
180
+ .query("SELECT * FROM tracker_agent_mapping ORDER BY createdAt DESC")
181
+ .all() as TrackerAgentMapping[];
182
+ }