@desplega.ai/agent-swarm 1.156.0 → 1.158.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. package/dist/{acp-adapter-c1msptrw.js → acp-adapter-xaq4n6pc.js} +1 -1
  2. package/dist/{actions-wd41qtdc.js → actions-p9hz5yat.js} +15 -15
  3. package/dist/{app-tz2qrnah.js → app-g26wdcz6.js} +4 -4
  4. package/dist/{artifact-td4q4dch.js → artifact-3v5t9jtg.js} +1 -1
  5. package/dist/{assistant-c3q1zj2t.js → assistant-wydfqkb3.js} +16 -16
  6. package/dist/{boot-reembed-0be1krkm.js → boot-reembed-g5ckg9yb.js} +6 -6
  7. package/dist/{boot-reembed-r00j03f3.js → boot-reembed-se8zmdcp.js} +5 -5
  8. package/dist/{boot-scrub-logs-9j4hd0vw.js → boot-scrub-logs-wfxqan61.js} +3 -3
  9. package/dist/{seed-pricing-ncgxz1r2.js → boot-seeds-s3q01xj3.js} +10 -10
  10. package/dist/{claude-adapter-112w28qc.js → claude-adapter-tv2x4f36.js} +7 -7
  11. package/dist/{claude-managed-adapter-ea2aga6w.js → claude-managed-adapter-41b2s7fd.js} +2 -2
  12. package/dist/{claude-sdk-session-k7pb5kfz.js → claude-sdk-session-t442qz6f.js} +8 -8
  13. package/dist/{cli-e781c6f9.js → cli-0xjkj1j7.js} +1 -0
  14. package/dist/{cli-58rgvkt4.js → cli-1hkrch3k.js} +2 -2
  15. package/dist/{cli-mx3bzbv8.js → cli-20cj37vt.js} +1968 -44
  16. package/dist/{cli-h0wdadsx.js → cli-4198qc9v.js} +7 -3
  17. package/dist/{cli-24w39x6n.js → cli-47m6dkd3.js} +362 -126
  18. package/dist/{cli-90x9ewbz.js → cli-53sz8gkz.js} +1 -1
  19. package/dist/{cli-005pze6s.js → cli-5d10vd2m.js} +1 -1
  20. package/dist/{cli-08n8jxcw.js → cli-65hjmev5.js} +57 -17
  21. package/dist/{cli-scwq51gn.js → cli-68w09sjw.js} +7 -1
  22. package/dist/{cli-7j2098n5.js → cli-7gtvvpbh.js} +4 -4
  23. package/dist/{cli-b05d7szr.js → cli-7s3syk22.js} +18 -11
  24. package/dist/{cli-9w4ex8vh.js → cli-8qmme6vd.js} +2 -2
  25. package/dist/{cli-28wkjpdp.js → cli-987hg0aa.js} +2 -2
  26. package/dist/{cli-7pgcpcrg.js → cli-9httdpyq.js} +1 -1
  27. package/dist/{cli-jk26c1sz.js → cli-aky8tctm.js} +26 -93
  28. package/dist/{cli-865swy5p.js → cli-c07r9a2m.js} +3 -2
  29. package/dist/{cli-nyqza443.js → cli-fgqxwrpv.js} +291 -12
  30. package/dist/{cli-9pyah9c4.js → cli-ftfvggzx.js} +633 -166
  31. package/dist/{cli-ytxs7mn1.js → cli-g8djp6qe.js} +17 -0
  32. package/dist/{cli-avkd6mqv.js → cli-h967nb6r.js} +551 -0
  33. package/dist/{cli-y8bfxjtw.js → cli-j55n64b6.js} +23 -22
  34. package/dist/{cli-7vj52450.js → cli-j57qkrpq.js} +86 -28
  35. package/dist/{cli-tjmghmm5.js → cli-q67y4wzm.js} +6 -3
  36. package/dist/{cli-n6zq3kbd.js → cli-rj19hc34.js} +1 -1
  37. package/dist/{cli-tp0d7vzb.js → cli-rjehvrts.js} +4 -4
  38. package/dist/{cli-s8hpxeg4.js → cli-rqz8qbw7.js} +245 -75
  39. package/dist/{cli-p37sg0a9.js → cli-s8eet254.js} +1 -1
  40. package/dist/cli-t1ze64h3.js +811 -0
  41. package/dist/{cli-hc2fkhdv.js → cli-ws6rqycm.js} +3 -2
  42. package/dist/{cli-t1cd3mhp.js → cli-wscdvcqz.js} +13 -5
  43. package/dist/{cli-xa4j64zh.js → cli-x24pshtq.js} +5 -5
  44. package/dist/{cli-nbp6m6gp.js → cli-xberxa1r.js} +51 -26
  45. package/dist/{cli-szcyv1mm.js → cli-xhaeg2nc.js} +1 -1
  46. package/dist/cli.js +30 -16
  47. package/dist/{codex-adapter-g4tj1f2g.js → codex-adapter-cnm8wk11.js} +5 -5
  48. package/dist/{codex-session-runner-ad8ha7zt.js → codex-session-runner-gfg547zj.js} +5 -5
  49. package/dist/{commands-z3gd8ppc.js → commands-e3bn0p75.js} +3 -3
  50. package/dist/{db-bezm97r9.js → db-03v9kzr2.js} +17 -3
  51. package/dist/{dispatcher-a97hc33y.js → dispatcher-nrmg8yht.js} +14 -14
  52. package/dist/{dsh-adapter-1dwg97zv.js → dsh-adapter-k03nfqa6.js} +2 -2
  53. package/dist/{handlers-wtdy1x02.js → handlers-aqcedbyb.js} +17 -17
  54. package/dist/{hook-7edgmzng.js → hook-7vkskkre.js} +19 -11
  55. package/dist/{hook-fvs58a5b.js → hook-ybvmrmhq.js} +4 -4
  56. package/dist/{http-phnf93hp.js → http-2eqa8t24.js} +432 -195
  57. package/dist/{index-7x131mmf.js → index-1yks3qcr.js} +14 -14
  58. package/dist/{index-1fktvwxc.js → index-a3vn96n8.js} +31 -28
  59. package/dist/{index-yp8rasxk.js → index-c6zsv1bd.js} +5 -5
  60. package/dist/{index-50jxgw0d.js → index-chgdkq36.js} +14 -14
  61. package/dist/{index-7jwk7nsm.js → index-x71bvq0p.js} +15 -15
  62. package/dist/{keepalive-nnz07ebd.js → keepalive-vtkf5n99.js} +5 -5
  63. package/dist/{lead-mg7qcgww.js → lead-h3sp357x.js} +26 -26
  64. package/dist/{maintenance-ywmnqrpx.js → maintenance-jzeqtk3q.js} +6 -6
  65. package/dist/{oauth-refresh-sweep-c63sqfs1.js → oauth-refresh-sweep-qp3dzmdp.js} +4 -4
  66. package/dist/{onboard-2zj8sqkq.js → onboard-tmsp0qbz.js} +278 -81
  67. package/dist/{opencode-adapter-z64xjzec.js → opencode-adapter-x6x2da1z.js} +3 -3
  68. package/dist/{otel-impl-jgdfm26f.js → otel-impl-9mz73q65.js} +416 -301
  69. package/dist/{pi-mono-adapter-2b7mw16r.js → pi-mono-adapter-m6dvv0dz.js} +2 -2
  70. package/dist/{pricing-refresh-3whntb69.js → pricing-refresh-v1cbr9te.js} +5 -5
  71. package/dist/{rbac-roles-3zptcc3p.js → rbac-roles-c9wqz83x.js} +4 -4
  72. package/dist/{render-v2-dbvpyysc.js → render-v2-gryrh9h8.js} +4 -4
  73. package/dist/{setup-qwx0j8z9.js → setup-q9720bt6.js} +2 -2
  74. package/dist/{virtual-modules-8qheft18.js → virtual-modules-3htpgn8x.js} +1 -1
  75. package/dist/{work-objects-sjbcmvep.js → work-objects-b76x7deb.js} +17 -17
  76. package/dist/{worker-xezqdkb7.js → worker-6vrxbv41.js} +26 -26
  77. package/openapi.json +1626 -629
  78. package/package.json +3 -2
  79. package/src/apps/catalog.generated.json +229 -0
  80. package/src/apps/page-validator.ts +71 -16
  81. package/src/apps/row-store.ts +66 -11
  82. package/src/apps/sync.ts +59 -17
  83. package/src/artifact-sdk/browser-sdk.ts +436 -2
  84. package/src/be/approval-sweeps.ts +109 -0
  85. package/src/be/boot-seeds.ts +40 -0
  86. package/src/be/chunking.ts +1 -1
  87. package/src/be/db/agents.ts +20 -0
  88. package/src/be/db/approvals.ts +78 -0
  89. package/src/be/db/tasks/read.ts +197 -39
  90. package/src/be/db/tasks/write.ts +41 -9
  91. package/src/be/db-client.ts +107 -48
  92. package/src/be/db.ts +219 -76
  93. package/src/be/events.ts +33 -1
  94. package/src/be/memory/graph-expansion.ts +10 -3
  95. package/src/be/memory/providers/sqlite-store.ts +55 -13
  96. package/src/be/memory/raters/retrieval.ts +5 -2
  97. package/src/be/memory/reranker.ts +26 -2
  98. package/src/be/memory/types.ts +2 -0
  99. package/src/be/migrations/166_approval_request_auto_cancellation.sql +9 -0
  100. package/src/be/migrations/171_memory_retrieval_relevance.sql +8 -0
  101. package/src/be/migrations/175_workflow_runs_list_index.sql +11 -0
  102. package/src/be/migrations/177_events_event_agent_created_index.sql +11 -0
  103. package/src/be/models-catalog.ts +2 -0
  104. package/src/be/modelsdev-cache.json +1857 -0
  105. package/src/be/modelsdev-cache.ts +14 -1
  106. package/src/be/pricing-normalize.ts +2 -0
  107. package/src/be/scripts/typecheck.ts +1 -0
  108. package/src/be/seed-pricing.ts +3 -1
  109. package/src/be/seed-skills/bundled-files.generated.json +1 -1
  110. package/src/be/steering.ts +53 -3
  111. package/src/be/swarm-config-guard.ts +3 -0
  112. package/src/be/task-citations.ts +29 -0
  113. package/src/cli.tsx +14 -1
  114. package/src/commands/onboard/compose-generator.ts +8 -3
  115. package/src/commands/onboard/container-engine.ts +220 -0
  116. package/src/commands/onboard/manifest.ts +1 -0
  117. package/src/commands/onboard/steps/health-check.tsx +4 -1
  118. package/src/commands/onboard/steps/prereq-check.tsx +50 -54
  119. package/src/commands/onboard/steps/start.tsx +31 -16
  120. package/src/commands/onboard/types.ts +7 -2
  121. package/src/commands/onboard.tsx +39 -4
  122. package/src/commands/profile-sync.ts +79 -26
  123. package/src/commands/runner.ts +8 -1
  124. package/src/extensions/catalog.generated.json +17 -0
  125. package/src/extensions/contract-types.generated.ts +1 -1
  126. package/src/heartbeat/heartbeat.ts +263 -103
  127. package/src/hooks/hook.ts +21 -12
  128. package/src/http/agents.ts +35 -0
  129. package/src/http/approval-requests.ts +136 -64
  130. package/src/http/apps.ts +14 -3
  131. package/src/http/config.ts +15 -1
  132. package/src/http/events.ts +62 -2
  133. package/src/http/index.ts +6 -4
  134. package/src/http/memory.ts +21 -7
  135. package/src/http/schedules.ts +1 -1
  136. package/src/http/session-data.ts +9 -4
  137. package/src/http/sessions.ts +25 -18
  138. package/src/http/stats.ts +19 -7
  139. package/src/http/status.ts +11 -1
  140. package/src/http/tasks.ts +40 -8
  141. package/src/http/webhooks.ts +67 -46
  142. package/src/http/workflows.ts +15 -20
  143. package/src/linear/outbound.ts +37 -15
  144. package/src/otel-impl.ts +151 -1
  145. package/src/otel.ts +14 -3
  146. package/src/prompts/memories.ts +19 -2
  147. package/src/providers/claude-managed-models.ts +8 -0
  148. package/src/providers/codex-agents-md.ts +140 -17
  149. package/src/providers/modelsdev-reasoning.json +551 -0
  150. package/src/rbac/legacy-policy.ts +16 -0
  151. package/src/rbac/permissions.ts +4 -0
  152. package/src/scheduler/deferred-task-waits.ts +28 -0
  153. package/src/scheduler/schedule-task.ts +3 -0
  154. package/src/scheduler/scheduler.ts +14 -0
  155. package/src/scripts-runtime/sdk-allowlist.ts +1 -0
  156. package/src/scripts-runtime/swarm-sdk.ts +9 -0
  157. package/src/scripts-runtime/types/stdlib.d.ts +1 -0
  158. package/src/scripts-runtime/types/swarm-extension.d.ts +1 -0
  159. package/src/scripts-runtime/types/swarm-sdk.d.ts +1 -0
  160. package/src/server.ts +12 -7
  161. package/src/slack/app.ts +35 -4
  162. package/src/slack/connection-state.ts +17 -0
  163. package/src/tasks/context-key.ts +1 -0
  164. package/src/tasks/worker-follow-up.ts +6 -2
  165. package/src/tests/agent-task-activity.test.ts +74 -0
  166. package/src/tests/agents-list-model-display.test.ts +6 -1
  167. package/src/tests/approval-auto-cancellation-migration.test.ts +104 -0
  168. package/src/tests/approval-requests.test.ts +395 -0
  169. package/src/tests/approval-sweeps-config.test.ts +47 -0
  170. package/src/tests/approval-sweeps.test.ts +508 -0
  171. package/src/tests/apps-kibo-blocks.test.ts +77 -0
  172. package/src/tests/apps-spike.test.ts +56 -1
  173. package/src/tests/apps-sync-engine.test.ts +20 -9
  174. package/src/tests/boot-seeds.test.ts +170 -0
  175. package/src/tests/cancel-approval-request-tool.test.ts +115 -0
  176. package/src/tests/claude-managed-adapter.test.ts +6 -0
  177. package/src/tests/codex-adapter.test.ts +126 -1
  178. package/src/tests/config-key-filter.test.ts +80 -0
  179. package/src/tests/context-window.test.ts +1 -0
  180. package/src/tests/db-client-busy-retry.test.ts +96 -0
  181. package/src/tests/db-client.test.ts +60 -1
  182. package/src/tests/db-task-read-contract.test.ts +10 -0
  183. package/src/tests/db-task-write-contract.test.ts +9 -0
  184. package/src/tests/deferred-schedule-reaper.test.ts +193 -0
  185. package/src/tests/docs-index-footprint.test.js +3 -3
  186. package/src/tests/events-http.test.ts +103 -0
  187. package/src/tests/extensions-catalog.test.ts +22 -17
  188. package/src/tests/extensions-pre-task.test.ts +107 -0
  189. package/src/tests/fixtures/kibo-blocks-definition.json.txt +105 -0
  190. package/src/tests/follow-up-config-inheritance.test.ts +260 -0
  191. package/src/tests/heartbeat-orphan-resume.test.ts +84 -0
  192. package/src/tests/heartbeat-reboot-live.test.ts +95 -0
  193. package/src/tests/heartbeat-stall-cas.test.ts +80 -0
  194. package/src/tests/heartbeat.test.ts +99 -3
  195. package/src/tests/hook-mcp-config.test.ts +29 -0
  196. package/src/tests/http-api-integration.test.ts +16 -2
  197. package/src/tests/kv-storage.test.ts +62 -0
  198. package/src/tests/linear-outbound-sync.test.ts +120 -5
  199. package/src/tests/list-endpoint-slimming.test.ts +91 -0
  200. package/src/tests/memory-graph-organic-route.test.ts +155 -0
  201. package/src/tests/memory-http-recall-gating.test.ts +14 -4
  202. package/src/tests/memory-hybrid.test.ts +161 -1
  203. package/src/tests/memory-prompt-recall-crowdout.test.ts +297 -0
  204. package/src/tests/memory.test.ts +22 -0
  205. package/src/tests/onboard-container-engine.test.ts +240 -0
  206. package/src/tests/otel-event-loop-and-logs.test.ts +99 -0
  207. package/src/tests/pricing-routes.test.ts +14 -0
  208. package/src/tests/profile-sync-warning.test.ts +8 -4
  209. package/src/tests/promote-draft-task-route.test.ts +19 -0
  210. package/src/tests/provider-registration.test.ts +296 -42
  211. package/src/tests/rbac-engine.test.ts +30 -0
  212. package/src/tests/reasoning-effort.test.ts +8 -0
  213. package/src/tests/script-connections.test.ts +7 -0
  214. package/src/tests/sdk-allowlist.test.ts +39 -0
  215. package/src/tests/session-costs-model-key-normalize.test.ts +1 -0
  216. package/src/tests/sessions-detail-batch.test.ts +250 -0
  217. package/src/tests/sessions.test.ts +118 -0
  218. package/src/tests/slack-config.test.ts +22 -0
  219. package/src/tests/sonnet-5-5-registry.test.ts +44 -0
  220. package/src/tests/status.test.ts +36 -1
  221. package/src/tests/swarm-diff.test.ts +316 -10
  222. package/src/tests/task-completion-idempotency.test.ts +2 -1
  223. package/src/tests/tasks-requested-by-filter.test.ts +3 -1
  224. package/src/tests/tool-annotations.test.ts +1 -1
  225. package/src/tests/ui-list-slim-projections.test.ts +158 -0
  226. package/src/tests/webhooks-task-blocked.test.ts +127 -0
  227. package/src/tests/workflow-approval-recovery.test.ts +203 -0
  228. package/src/tests/workflow-hitl-routing.test.ts +22 -1
  229. package/src/tests/workflow-hitl-slack-card.test.ts +52 -0
  230. package/src/tests/workflow-http-v2.test.ts +99 -8
  231. package/src/tests/workflow-retry-validation.test.ts +56 -0
  232. package/src/tests/workflow-tla-races.test.ts +389 -0
  233. package/src/tests/workflow-validation-port-routing.test.ts +113 -1
  234. package/src/tools/cancel-approval-request.ts +57 -0
  235. package/src/tools/memory-search.ts +1 -0
  236. package/src/tools/request-human-input.ts +4 -2
  237. package/src/tools/schedules/list-schedules.ts +4 -2
  238. package/src/tools/send-task.ts +4 -0
  239. package/src/tools/templates.ts +19 -0
  240. package/src/tools/tool-config.ts +2 -1
  241. package/src/tools/workflows/list-workflow-runs.ts +1 -0
  242. package/src/types.ts +38 -0
  243. package/src/utils/context-window.ts +1 -0
  244. package/src/workflows/approval-cancel.ts +152 -0
  245. package/src/workflows/approval-notifications.ts +84 -0
  246. package/src/workflows/checkpoint.ts +10 -5
  247. package/src/workflows/definition.ts +21 -0
  248. package/src/workflows/engine.ts +152 -21
  249. package/src/workflows/executors/human-in-the-loop.ts +1 -1
  250. package/src/workflows/recovery.ts +100 -45
  251. package/src/workflows/resume.ts +49 -18
  252. package/src/workflows/retry-poller.ts +71 -21
  253. package/templates/extensions/README.md +1 -0
  254. package/templates/extensions/github-sender-allowlist/README.md +18 -0
  255. package/templates/extensions/github-sender-allowlist/hooks.ts +55 -0
  256. package/templates/extensions/github-sender-allowlist/manifest.json +8 -0
  257. package/templates/skills/apps/content.md +20 -1
  258. package/templates/skills/code-quality/content.md +26 -1
  259. package/templates/skills/pages/content.md +16 -4
  260. package/templates/skills/pages/files/examples/multiplayer-board.html +3 -12
  261. package/templates/skills/scheduling/content.md +1 -1
  262. package/dist/cli-2daksqps.js +0 -378
  263. package/dist/rbac-roles-3zw68x72.js +0 -37
@@ -1,22 +1,18 @@
1
1
  import {
2
2
  BROWSER_SDK_JS,
3
3
  SWARM_UI_JS
4
- } from "./cli-2daksqps.js";
4
+ } from "./cli-t1ze64h3.js";
5
5
  import {
6
6
  ACP_TARGET_IDS
7
7
  } from "./cli-dgnj0zcc.js";
8
8
  import {
9
9
  SIMILARITY_THRESHOLD,
10
+ memoryRelevance,
10
11
  writeSkillsToFilesystem
11
- } from "./cli-tjmghmm5.js";
12
+ } from "./cli-q67y4wzm.js";
12
13
  import {
13
14
  Anthropic
14
15
  } from "./cli-j490egb5.js";
15
- import {
16
- checkHeartbeatChecklist,
17
- runHeartbeatSweep,
18
- stopHeartbeat
19
- } from "./cli-s8hpxeg4.js";
20
16
  import {
21
17
  isClaudeBridgeEffective,
22
18
  resolveClaudeTransport
@@ -26,11 +22,16 @@ import {
26
22
  } from "./cli-npssxgaz.js";
27
23
  import {
28
24
  reasoningCapability
29
- } from "./cli-avkd6mqv.js";
25
+ } from "./cli-h967nb6r.js";
30
26
  import {
31
27
  ensureAgentFsCredentialsForAgent,
32
28
  inviteEmailToSharedOrg
33
- } from "./cli-szcyv1mm.js";
29
+ } from "./cli-xhaeg2nc.js";
30
+ import {
31
+ checkHeartbeatChecklist,
32
+ runHeartbeatSweep,
33
+ stopHeartbeat
34
+ } from "./cli-rqz8qbw7.js";
34
35
  import {
35
36
  AGENT_MAX_TASKS_CONFIG_KEY,
36
37
  ALL_CAPABILITIES,
@@ -70,6 +71,7 @@ import {
70
71
  calculateNextRun,
71
72
  canClaim,
72
73
  canReadMemory,
74
+ cancelApprovalRequest,
73
75
  cancelTaskHandler,
74
76
  cancelTaskInputSchema,
75
77
  cancelTaskOutputSchema,
@@ -78,6 +80,7 @@ import {
78
80
  checkOutputSchemaShape,
79
81
  clearJiraMetadata,
80
82
  closeRooms,
83
+ createApprovalFollowUpTask,
81
84
  createEvent,
82
85
  createEventsBatch,
83
86
  createResumeFollowUp,
@@ -285,7 +288,7 @@ import {
285
288
  verifyWebhookSignature,
286
289
  warnIfCorsAllowsAnyOrigin,
287
290
  wireHttpSpanLifecycle
288
- } from "./cli-9pyah9c4.js";
291
+ } from "./cli-ftfvggzx.js";
289
292
  import"./cli-0z2v4nhw.js";
290
293
  import {
291
294
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -307,15 +310,9 @@ import {
307
310
  } from "./cli-re8z5p8p.js";
308
311
  import"./cli-3dpj7atn.js";
309
312
  import"./cli-aw1jwp1r.js";
310
- import {
311
- getModelsCatalog
312
- } from "./cli-hc2fkhdv.js";
313
- import {
314
- normalizeModelKey
315
- } from "./cli-t1cd3mhp.js";
316
313
  import {
317
314
  getUserGrant
318
- } from "./cli-jk26c1sz.js";
315
+ } from "./cli-aky8tctm.js";
319
316
  import {
320
317
  LEGACY_RULES,
321
318
  can,
@@ -323,7 +320,13 @@ import {
323
320
  decideToolAdmission,
324
321
  isRbacEnabled,
325
322
  setAuditSink
326
- } from "./cli-ytxs7mn1.js";
323
+ } from "./cli-g8djp6qe.js";
324
+ import {
325
+ getModelsCatalog
326
+ } from "./cli-ws6rqycm.js";
327
+ import {
328
+ normalizeModelKey
329
+ } from "./cli-wscdvcqz.js";
327
330
  import {
328
331
  ConnectionAuthInputSchema,
329
332
  MAX_SCRIPT_WALL_CLOCK_MS,
@@ -415,7 +418,7 @@ import {
415
418
  upsertScriptByName,
416
419
  upsertScriptConnection,
417
420
  validateDefinition
418
- } from "./cli-nyqza443.js";
421
+ } from "./cli-fgqxwrpv.js";
419
422
  import"./cli-epan13p1.js";
420
423
  import {
421
424
  detachedProcessGroup,
@@ -429,7 +432,7 @@ import {
429
432
  } from "./cli-f14fvzag.js";
430
433
  import {
431
434
  searchScripts
432
- } from "./cli-28wkjpdp.js";
435
+ } from "./cli-987hg0aa.js";
433
436
  import {
434
437
  acquireOAuthRefreshLock,
435
438
  buildAuthorizationUrl,
@@ -453,7 +456,7 @@ import {
453
456
  updateAuthorizationIdentity,
454
457
  updateOAuthAppById,
455
458
  upsertAuthorization
456
- } from "./cli-90x9ewbz.js";
459
+ } from "./cli-53sz8gkz.js";
457
460
  import {
458
461
  FilesError,
459
462
  getFileStorageProvider,
@@ -467,8 +470,8 @@ import {
467
470
  init_constants as init_constants2,
468
471
  init_reranker,
469
472
  rerank
470
- } from "./cli-08n8jxcw.js";
471
- import"./cli-nbp6m6gp.js";
473
+ } from "./cli-65hjmev5.js";
474
+ import"./cli-xberxa1r.js";
472
475
  import"./cli-bsakbbkm.js";
473
476
  import"./cli-fad8m16k.js";
474
477
  import"./cli-51tf7ac3.js";
@@ -480,7 +483,9 @@ import {
480
483
  TaskCitationSchema,
481
484
  ensure,
482
485
  getSlackApp,
486
+ getSlackConnectionState,
483
487
  getTaskCitations,
488
+ getTaskCitationsForTasks,
484
489
  initOtel,
485
490
  initialize,
486
491
  isPollTracingEnabled,
@@ -493,7 +498,7 @@ import {
493
498
  withRemoteContext,
494
499
  withSpan,
495
500
  withSpanContext
496
- } from "./cli-7vj52450.js";
501
+ } from "./cli-j57qkrpq.js";
497
502
  import"./cli-q51yprfq.js";
498
503
  import"./cli-3er6gcsn.js";
499
504
  import"./cli-2658f6at.js";
@@ -580,6 +585,7 @@ import {
580
585
  getActivePricingRow,
581
586
  getActiveSessions,
582
587
  getAgentById,
588
+ getAgentDailyTaskCounts,
583
589
  getAgentHarnessProviders,
584
590
  getAgentMcpServers,
585
591
  getAgentSkills,
@@ -668,6 +674,7 @@ import {
668
674
  getTaskById,
669
675
  getTaskStats,
670
676
  getTaskSteeringFields,
677
+ getTaskSteeringFieldsForTasks,
671
678
  getTasksCount,
672
679
  getUnassignedTaskIdsForAgent,
673
680
  getUsageDataVersion,
@@ -710,6 +717,7 @@ import {
710
717
  listAgentsWithCredStatusByProvider,
711
718
  listAllMetrics,
712
719
  listAllPages,
720
+ listApprovalRequestSummaries,
713
721
  listApprovalRequests,
714
722
  listAssetSummaries,
715
723
  listFavorites,
@@ -724,7 +732,6 @@ import {
724
732
  listSkillFileManifest,
725
733
  listSkills,
726
734
  listTaskTemplates,
727
- listWorkflowRuns,
728
735
  listWorkflowRunsPage,
729
736
  listWorkflows,
730
737
  markKeyRateLimited,
@@ -801,7 +808,7 @@ import {
801
808
  upsertSwarmConfig,
802
809
  validateConfigValue,
803
810
  withFavoriteFlags
804
- } from "./cli-24w39x6n.js";
811
+ } from "./cli-47m6dkd3.js";
805
812
  import {
806
813
  ActiveSessionSchema,
807
814
  AgentAcpStatusSchema,
@@ -918,6 +925,7 @@ import {
918
925
  WorkflowRunSchema,
919
926
  WorkflowRunStatusSchema,
920
927
  WorkflowRunStepSchema,
928
+ WorkflowRunSummarySchema,
921
929
  WorkflowSchema,
922
930
  WorkflowVersionSchema,
923
931
  init_bundle_path,
@@ -926,7 +934,7 @@ import {
926
934
  isSafeBundlePath,
927
935
  isTerminalTaskStatus,
928
936
  splitLegacyModelAlias
929
- } from "./cli-h0wdadsx.js";
937
+ } from "./cli-4198qc9v.js";
930
938
  import {
931
939
  IDENTITY_FIELD_BUDGETS,
932
940
  IdentityFieldBudgetError,
@@ -988,7 +996,7 @@ import {
988
996
  import {
989
997
  init_package,
990
998
  package_default
991
- } from "./cli-865swy5p.js";
999
+ } from "./cli-c07r9a2m.js";
992
1000
  import {
993
1001
  init_secret_scrubber,
994
1002
  registerVolatileSecret,
@@ -3584,6 +3592,25 @@ var listAgentRuntimeInstances = route({
3584
3592
  404: { description: "Agent not found" }
3585
3593
  }
3586
3594
  });
3595
+ var getAgentTaskActivity = route({
3596
+ method: "get",
3597
+ path: "/api/agents/{id}/task-activity",
3598
+ pattern: ["api", "agents", null, "task-activity"],
3599
+ summary: "Daily task counts for an agent",
3600
+ description: "Number of tasks created for the agent per UTC day over the last `days` days (default 365, max 730), oldest first. Days with no tasks are omitted. Backs the activity heatmap on the agent page.",
3601
+ tags: ["Agents"],
3602
+ params: exports_external.object({ id: exports_external.string() }),
3603
+ query: exports_external.object({ days: exports_external.coerce.number().int().min(1).max(730).optional() }),
3604
+ responses: {
3605
+ 200: {
3606
+ description: "Daily task counts",
3607
+ schema: exports_external.object({
3608
+ days: exports_external.array(exports_external.object({ date: exports_external.string(), count: exports_external.number().int() }))
3609
+ })
3610
+ },
3611
+ 404: { description: "Agent not found" }
3612
+ }
3613
+ });
3587
3614
  var ContentHashSchema = exports_external.string().regex(/^[0-9a-f]{64}$/, "sha256 hex");
3588
3615
  var ProfileSyncRejectionSchema = exports_external.object({
3589
3616
  field: exports_external.enum(["soulMd", "identityMd", "claudeMd", "toolsMd"]),
@@ -3890,6 +3917,19 @@ async function handleAgentsRest(req, res, pathSegments, queryParams, _myAgentId)
3890
3917
  });
3891
3918
  return true;
3892
3919
  }
3920
+ if (getAgentTaskActivity.match(req.method, pathSegments)) {
3921
+ const parsed = await getAgentTaskActivity.parse(req, res, pathSegments, queryParams);
3922
+ if (!parsed)
3923
+ return true;
3924
+ if (!await getAgentById(parsed.params.id)) {
3925
+ jsonError(res, "Agent not found", 404);
3926
+ return true;
3927
+ }
3928
+ getAgentTaskActivity.respond(res, 200, {
3929
+ days: await getAgentDailyTaskCounts(parsed.params.id, parsed.query.days ?? 365)
3930
+ });
3931
+ return true;
3932
+ }
3893
3933
  if (updateAgentProfileRoute.match(req.method, pathSegments)) {
3894
3934
  const parsed = await updateAgentProfileRoute.parse(req, res, pathSegments, queryParams);
3895
3935
  if (!parsed)
@@ -4850,7 +4890,6 @@ async function handleApiKeys(req, res, pathSegments, queryParams) {
4850
4890
  // src/http/approval-requests.ts
4851
4891
  init_zod();
4852
4892
  init_db();
4853
- init_resolver();
4854
4893
  init_request_auth_context();
4855
4894
  init_event_bus();
4856
4895
  var QuestionSchema = exports_external.object({
@@ -4900,6 +4939,13 @@ var ApprovalRequestSchema = exports_external.object({
4900
4939
  createdAt: exports_external.string(),
4901
4940
  updatedAt: exports_external.string()
4902
4941
  });
4942
+ var ApprovalRequestSummarySchema = ApprovalRequestSchema.omit({
4943
+ questions: true,
4944
+ approvers: true,
4945
+ responses: true,
4946
+ resolutionReason: true,
4947
+ notificationChannels: true
4948
+ }).extend({ questionCount: exports_external.number().int() });
4903
4949
  function toApprovalRequestResponse(request) {
4904
4950
  return {
4905
4951
  ...request,
@@ -4976,7 +5022,7 @@ var createRoute = route({
4976
5022
  workflowRunId: exports_external.string().uuid().optional(),
4977
5023
  workflowRunStepId: exports_external.string().uuid().optional(),
4978
5024
  sourceTaskId: exports_external.string().uuid().optional(),
4979
- timeoutSeconds: exports_external.number().int().min(1).optional(),
5025
+ timeoutSeconds: exports_external.number().int().min(1).optional().describe("Seconds until the request expires. After that the request becomes 'timeout' and you get a hitl-follow-up task. A request with no timeout is cancelled after APPROVAL_REQUEST_AUTO_CANCELLATION_DAYS days (default 7)."),
4980
5026
  notifications: exports_external.array(exports_external.object({
4981
5027
  channel: exports_external.enum(["slack", "email"]),
4982
5028
  target: exports_external.string()
@@ -5029,21 +5075,54 @@ var respondRoute = route({
5029
5075
  },
5030
5076
  auth: { apiKey: true }
5031
5077
  });
5078
+ var cancelRoute = route({
5079
+ method: "post",
5080
+ path: "/api/approval-requests/{id}/cancel",
5081
+ pattern: ["api", "approval-requests", null, "cancel"],
5082
+ summary: "Cancel a pending approval request",
5083
+ tags: ["ApprovalRequests"],
5084
+ params: exports_external.object({ id: exports_external.string().uuid() }),
5085
+ body: exports_external.object({ reason: exports_external.string().max(500).optional() }),
5086
+ responses: {
5087
+ 200: {
5088
+ description: "Request cancelled, or already cancelled. A request that gates a running or waiting workflow run cancels that run too.",
5089
+ schema: exports_external.object({
5090
+ approvalRequest: ApprovalRequestSchema,
5091
+ alreadyCancelled: exports_external.boolean(),
5092
+ runCancelled: exports_external.boolean()
5093
+ })
5094
+ },
5095
+ 403: { description: "Caller may not cancel this request" },
5096
+ 404: { description: "Not found" },
5097
+ 409: {
5098
+ description: "Already resolved with approved, rejected, or timeout, or its expiresAt passed"
5099
+ }
5100
+ },
5101
+ auth: { apiKey: true },
5102
+ rbac: { permission: "approval.cancel.any" }
5103
+ });
5032
5104
  var listRoute = route({
5033
5105
  method: "get",
5034
5106
  path: "/api/approval-requests",
5035
5107
  pattern: ["api", "approval-requests"],
5036
5108
  summary: "List approval requests with optional filters",
5109
+ description: "Returns full approval requests by default. Pass `fields=slim` for the list-view shape: `questions`, `approvers`, `responses`, `resolutionReason` and `notificationChannels` are dropped and `questionCount` is added. Fetch one request in full via `GET /api/approval-requests/{id}`.",
5037
5110
  tags: ["ApprovalRequests"],
5038
5111
  query: exports_external.object({
5039
5112
  status: exports_external.string().optional(),
5040
5113
  workflowRunId: exports_external.string().optional(),
5041
- limit: exports_external.coerce.number().optional()
5114
+ limit: exports_external.coerce.number().optional(),
5115
+ fields: exports_external.enum(["full", "slim"]).optional()
5042
5116
  }),
5043
5117
  responses: {
5044
5118
  200: {
5045
5119
  description: "List of approval requests",
5046
- schema: exports_external.object({ approvalRequests: exports_external.array(ApprovalRequestSchema) })
5120
+ schema: exports_external.object({
5121
+ approvalRequests: exports_external.union([
5122
+ exports_external.array(ApprovalRequestSchema),
5123
+ exports_external.array(ApprovalRequestSummarySchema)
5124
+ ])
5125
+ })
5047
5126
  }
5048
5127
  },
5049
5128
  auth: { apiKey: true }
@@ -5063,6 +5142,19 @@ async function handleApprovalRequests(req, res, pathSegments, queryParams) {
5063
5142
  jsonError(res, `Approval request already resolved with status: ${existing.status}${reason}`, 409);
5064
5143
  return true;
5065
5144
  }
5145
+ if (existing.expiresAt && new Date(existing.expiresAt) < new Date) {
5146
+ await getDbClient().transaction(async () => {
5147
+ const timedOut = await resolveApprovalRequest(existing.id, {
5148
+ status: "timeout",
5149
+ resolutionReason: `Timed out: the answer arrived after the deadline ${existing.expiresAt}`
5150
+ });
5151
+ if (timedOut && !existing.workflowRunId) {
5152
+ await createApprovalFollowUpTask(timedOut, "hitl.timeout");
5153
+ }
5154
+ });
5155
+ jsonError(res, `Approval request expired at ${existing.expiresAt}`, 409);
5156
+ return true;
5157
+ }
5066
5158
  const unavailableReason = await getWorkflowApprovalUnavailableReason(existing);
5067
5159
  if (unavailableReason) {
5068
5160
  jsonError(res, unavailableReason, 409);
@@ -5104,33 +5196,32 @@ async function handleApprovalRequests(req, res, pathSegments, queryParams) {
5104
5196
  workflowRunStepId: updated.workflowRunStepId
5105
5197
  });
5106
5198
  }
5107
- if (!updated.workflowRunId && updated.sourceTaskId) {
5108
- const sourceTask = await getTaskById(updated.sourceTaskId);
5109
- if (sourceTask) {
5110
- const formattedResponses = formatResponses(updated.questions, updated.responses);
5111
- const { text: taskText } = resolveTemplate("hitl.follow_up", {
5112
- request_id: updated.id,
5113
- title: updated.title,
5114
- status: updated.status,
5115
- responses: formattedResponses
5116
- });
5117
- await createTaskExtended(taskText, {
5118
- agentId: sourceTask.agentId,
5119
- routingReason: sourceTask.agentId ? "continuity" : undefined,
5120
- routingSource: sourceTask.agentId ? "engine_default" : undefined,
5121
- parentTaskId: updated.sourceTaskId,
5122
- source: "system",
5123
- taskType: "hitl-follow-up",
5124
- tags: ["hitl", "follow-up"],
5125
- slackChannelId: sourceTask.slackChannelId ?? undefined,
5126
- slackThreadTs: sourceTask.slackThreadTs ?? undefined,
5127
- slackUserId: sourceTask.slackUserId ?? undefined
5128
- });
5129
- }
5130
- }
5199
+ await createApprovalFollowUpTask(updated, "hitl.follow_up");
5131
5200
  respondRoute.respond(res, 200, { approvalRequest: toApprovalRequestResponse(updated) });
5132
5201
  return true;
5133
5202
  }
5203
+ if (cancelRoute.match(req.method, pathSegments)) {
5204
+ const parsed = await cancelRoute.parse(req, res, pathSegments, queryParams);
5205
+ if (!parsed)
5206
+ return true;
5207
+ const { principal, resolvedBy } = await approvalCancelPrincipal(req);
5208
+ const result = await cancelApprovalRequest({
5209
+ id: parsed.params.id,
5210
+ reason: parsed.body.reason,
5211
+ principal,
5212
+ resolvedBy
5213
+ });
5214
+ if (!result.ok) {
5215
+ jsonError(res, result.message, result.status);
5216
+ return true;
5217
+ }
5218
+ cancelRoute.respond(res, 200, {
5219
+ approvalRequest: toApprovalRequestResponse(result.request),
5220
+ alreadyCancelled: result.alreadyCancelled,
5221
+ runCancelled: result.runCancelled
5222
+ });
5223
+ return true;
5224
+ }
5134
5225
  if (getByIdRoute.match(req.method, pathSegments)) {
5135
5226
  const parsed = await getByIdRoute.parse(req, res, pathSegments, queryParams);
5136
5227
  if (!parsed)
@@ -5171,11 +5262,18 @@ async function handleApprovalRequests(req, res, pathSegments, queryParams) {
5171
5262
  const parsed = await listRoute.parse(req, res, pathSegments, queryParams);
5172
5263
  if (!parsed)
5173
5264
  return true;
5174
- const requests = await listApprovalRequests({
5265
+ const filters = {
5175
5266
  status: parsed.query.status || undefined,
5176
5267
  workflowRunId: parsed.query.workflowRunId || undefined,
5177
5268
  limit: parsed.query.limit || undefined
5178
- });
5269
+ };
5270
+ if (parsed.query.fields === "slim") {
5271
+ listRoute.respond(res, 200, {
5272
+ approvalRequests: await listApprovalRequestSummaries(filters)
5273
+ });
5274
+ return true;
5275
+ }
5276
+ const requests = await listApprovalRequests(filters);
5179
5277
  listRoute.respond(res, 200, {
5180
5278
  approvalRequests: requests.map(toApprovalRequestResponse)
5181
5279
  });
@@ -5183,25 +5281,21 @@ async function handleApprovalRequests(req, res, pathSegments, queryParams) {
5183
5281
  }
5184
5282
  return false;
5185
5283
  }
5186
- function formatResponses(questions, responses) {
5187
- return questions.map((q) => {
5188
- const answer = responses[q.id];
5189
- let answerText;
5190
- if (answer == null) {
5191
- answerText = "(no answer)";
5192
- } else if (q.type === "approval") {
5193
- const a = answer;
5194
- answerText = a.approved ? "Approved" : "Rejected";
5195
- if (a.comment)
5196
- answerText += ` — ${a.comment}`;
5197
- } else if (typeof answer === "object") {
5198
- answerText = JSON.stringify(answer);
5199
- } else {
5200
- answerText = String(answer);
5201
- }
5202
- return `- ${q.label}: ${answerText}`;
5203
- }).join(`
5204
- `);
5284
+ async function approvalCancelPrincipal(req) {
5285
+ const auth = getRequestAuth(req);
5286
+ if (auth?.kind === "user") {
5287
+ return { principal: { kind: "user", userId: auth.userId }, resolvedBy: auth.userId };
5288
+ }
5289
+ const rawAgentId = req.headers["x-agent-id"];
5290
+ const agentId = auth?.kind === "agent" ? auth.agentId : Array.isArray(rawAgentId) ? rawAgentId[0] : rawAgentId;
5291
+ if (agentId) {
5292
+ const agent = await getAgentById(agentId);
5293
+ return {
5294
+ principal: { kind: "agent", agentId, isLead: agent?.isLead ?? false },
5295
+ resolvedBy: agentId
5296
+ };
5297
+ }
5298
+ return { principal: { kind: "operator" }, resolvedBy: "operator" };
5205
5299
  }
5206
5300
 
5207
5301
  // src/http/assets.ts
@@ -6363,6 +6457,7 @@ var getResolvedConfigRoute = route({
6363
6457
  query: exports_external.object({
6364
6458
  agentId: exports_external.string().optional(),
6365
6459
  repoId: exports_external.string().optional(),
6460
+ key: exports_external.string().min(1).optional().describe("Return only the entry with this exact key. Omit to return every resolved entry."),
6366
6461
  includeSecrets: exports_external.enum(["true", "false"]).optional()
6367
6462
  }),
6368
6463
  responses: {
@@ -6439,6 +6534,7 @@ var listConfig = route({
6439
6534
  query: exports_external.object({
6440
6535
  scope: exports_external.string().optional(),
6441
6536
  scopeId: exports_external.string().optional(),
6537
+ key: exports_external.string().min(1).optional().describe("Return only entries with this exact key. Omit to return every entry."),
6442
6538
  includeSecrets: exports_external.enum(["true", "false"]).optional()
6443
6539
  }),
6444
6540
  responses: {
@@ -6495,7 +6591,8 @@ async function handleConfig(req, res, pathSegments, queryParams) {
6495
6591
  return true;
6496
6592
  const includeSecrets = parsed.query.includeSecrets === "true";
6497
6593
  const { effectiveIncludeSecrets, secretsNote } = await resolveSecretsRead(req, includeSecrets);
6498
- const configs = stripApiOnlyKeys(await getResolvedConfig(parsed.query.agentId || undefined, parsed.query.repoId || undefined));
6594
+ const key = parsed.query.key;
6595
+ const configs = stripApiOnlyKeys(await getResolvedConfig(parsed.query.agentId || undefined, parsed.query.repoId || undefined)).filter((c) => !key || c.key === key);
6499
6596
  const result = effectiveIncludeSecrets ? configs : maskSecrets(configs);
6500
6597
  if (effectiveIncludeSecrets) {
6501
6598
  for (const c of result) {
@@ -6568,7 +6665,8 @@ async function handleConfig(req, res, pathSegments, queryParams) {
6568
6665
  const { effectiveIncludeSecrets, secretsNote } = await resolveSecretsRead(req, includeSecrets);
6569
6666
  const configs = stripApiOnlyKeys(await getSwarmConfigs({
6570
6667
  scope: parsed.query.scope || undefined,
6571
- scopeId: parsed.query.scopeId || undefined
6668
+ scopeId: parsed.query.scopeId || undefined,
6669
+ key: parsed.query.key
6572
6670
  }));
6573
6671
  const listResult = effectiveIncludeSecrets ? configs : maskSecrets(configs);
6574
6672
  if (effectiveIncludeSecrets) {
@@ -7258,13 +7356,20 @@ var getEventsRoute = route({
7258
7356
  dataField: exports_external.string().optional(),
7259
7357
  since: exports_external.string().optional(),
7260
7358
  until: exports_external.string().optional(),
7261
- limit: exports_external.coerce.number().int().min(1).max(1000).optional()
7359
+ limit: exports_external.coerce.number().int().min(1).max(1000).optional(),
7360
+ events: exports_external.string().optional().describe("Comma-separated event names; matches any of them (ANDed with `event`)"),
7361
+ dataFields: exports_external.string().optional().describe("Comma-separated `data.field` values, used with latestPerDataField"),
7362
+ latestPerDataField: exports_external.enum(["true", "false"]).optional().describe("When true, return only the newest event per (event, data.field) pair for every name in `event`/`events` and every value in `dataFields`")
7262
7363
  }),
7263
7364
  responses: {
7264
7365
  200: {
7265
7366
  description: "List of events",
7266
- schema: exports_external.object({ events: exports_external.array(SwarmEventSchema) })
7267
- }
7367
+ schema: exports_external.object({
7368
+ events: exports_external.array(SwarmEventSchema),
7369
+ latestPerDataField: exports_external.literal(true).optional().describe("Present only when the request asked for latestPerDataField=true")
7370
+ })
7371
+ },
7372
+ 400: { description: "Validation error" }
7268
7373
  },
7269
7374
  auth: { apiKey: true }
7270
7375
  });
@@ -7293,6 +7398,7 @@ var getEventCountsRoute = route({
7293
7398
  },
7294
7399
  auth: { apiKey: true }
7295
7400
  });
7401
+ var MAX_LATEST_PAIRS = 50;
7296
7402
  async function handleEvents(req, res, pathSegments, queryParams, _myAgentId) {
7297
7403
  if (createEventsBatchRoute.match(req.method, pathSegments)) {
7298
7404
  const parsed = await createEventsBatchRoute.parse(req, res, pathSegments, queryParams);
@@ -7340,6 +7446,20 @@ async function handleEvents(req, res, pathSegments, queryParams, _myAgentId) {
7340
7446
  const parsed = await getEventsRoute.parse(req, res, pathSegments, queryParams);
7341
7447
  if (!parsed)
7342
7448
  return true;
7449
+ const eventNames = parsed.query.events ? parsed.query.events.split(",").map((name) => EventNameSchema.safeParse(name.trim())) : [];
7450
+ const invalid = eventNames.find((result) => !result.success);
7451
+ if (invalid) {
7452
+ jsonError(res, "Invalid event name in `events`", 400);
7453
+ return true;
7454
+ }
7455
+ const eventFilter = eventNames.flatMap((result) => result.success ? [result.data] : []);
7456
+ const latestPerDataField = parsed.query.latestPerDataField === "true";
7457
+ const dataFields = (parsed.query.dataFields ?? "").split(",").map((field) => field.trim()).filter(Boolean);
7458
+ const latestEvents = eventFilter.length > 0 ? eventFilter : parsed.query.event ? [parsed.query.event] : [];
7459
+ if (latestPerDataField && (latestEvents.length === 0 || dataFields.length === 0 || latestEvents.length * dataFields.length > MAX_LATEST_PAIRS)) {
7460
+ jsonError(res, `latestPerDataField needs \`event\` or \`events\` and \`dataFields\`, at most ${MAX_LATEST_PAIRS} pairs`, 400);
7461
+ return true;
7462
+ }
7343
7463
  const events = await getEventsFiltered({
7344
7464
  category: parsed.query.category || undefined,
7345
7465
  event: parsed.query.event || undefined,
@@ -7351,9 +7471,11 @@ async function handleEvents(req, res, pathSegments, queryParams, _myAgentId) {
7351
7471
  dataField: parsed.query.dataField || undefined,
7352
7472
  since: parsed.query.since || undefined,
7353
7473
  until: parsed.query.until || undefined,
7354
- limit: parsed.query.limit ?? 100
7474
+ limit: parsed.query.limit ?? 100,
7475
+ events: eventFilter,
7476
+ latestPerDataField: latestPerDataField ? { events: latestEvents, dataFields } : undefined
7355
7477
  });
7356
- getEventsRoute.respond(res, 200, { events });
7478
+ getEventsRoute.respond(res, 200, latestPerDataField ? { events, latestPerDataField: true } : { events });
7357
7479
  return true;
7358
7480
  }
7359
7481
  return false;
@@ -7433,6 +7555,7 @@ declare module "swarm-extension" {
7433
7555
  outputSchema?: Record<string, unknown> | undefined;
7434
7556
  inheritParentOutputSchema?: boolean | undefined;
7435
7557
  inheritParentRoutingAffinity?: boolean | undefined;
7558
+ inheritParentFollowUpConfig?: boolean | undefined;
7436
7559
  followUpConfig?:
7437
7560
  | {
7438
7561
  disabled?: boolean | undefined;
@@ -8049,6 +8172,78 @@ void _configIsValid;
8049
8172
 
8050
8173
  // src/extensions/catalog.generated.json
8051
8174
  var catalog_generated_default = {
8175
+ "github-sender-allowlist": {
8176
+ manifestFile: "manifest.json",
8177
+ manifest: {
8178
+ $schema: "../manifest.schema.json",
8179
+ name: "github-sender-allowlist",
8180
+ description: "Blocks GitHub webhook tasks from senders outside configured allowlists",
8181
+ version: "1.0.0",
8182
+ runtime: "api",
8183
+ assets: {
8184
+ hooks: "hooks.ts"
8185
+ }
8186
+ },
8187
+ files: {
8188
+ "hooks.ts": `import { block, type SwarmExtension } from "swarm-extension";
8189
+ import { z } from "zod";
8190
+
8191
+ export const config = z.object({
8192
+ internal: z.array(z.string()).default([]),
8193
+ external: z.array(z.string()).default([]),
8194
+ reviewBots: z.array(z.string()).default([]),
8195
+ exemptTaskTypes: z.array(z.string()).default([]),
8196
+ });
8197
+
8198
+ const manifest = {
8199
+ name: "github-sender-allowlist",
8200
+ description: "Blocks GitHub webhook tasks from senders outside configured allowlists",
8201
+ version: "1.0.0",
8202
+ runtime: "api",
8203
+ assets: { hooks: "hooks.ts" },
8204
+ config,
8205
+ } as const;
8206
+
8207
+ function includesLogin(logins: string[], login: string): boolean {
8208
+ return logins.some((allowed) => allowed.toLowerCase() === login.toLowerCase());
8209
+ }
8210
+
8211
+ const extension: SwarmExtension<typeof manifest> = (api) => {
8212
+ api.on("pre.task.create", (event, ctx) => {
8213
+ const { options } = event;
8214
+ if (options.source !== "github") return;
8215
+
8216
+ const taskType = options.taskType ?? "unknown";
8217
+ const login = options.vcsAuthor ?? "";
8218
+ if (includesLogin(ctx.config.internal, login)) return;
8219
+
8220
+ const isReviewBot = includesLogin(ctx.config.reviewBots, login);
8221
+ if (isReviewBot && taskType === "github-review") return;
8222
+ if (!isReviewBot && ctx.config.exemptTaskTypes.includes(taskType)) return;
8223
+
8224
+ const isPullRequest = options.vcsUrl?.includes("/pull/") ?? false;
8225
+ const isExternalPullRequestTask =
8226
+ (taskType === "github-comment" || taskType === "github-pr" || taskType === "github-review") &&
8227
+ isPullRequest;
8228
+ const isExternalSender = includesLogin(ctx.config.external, login);
8229
+ if (!isReviewBot && isExternalSender && isExternalPullRequestTask) return;
8230
+
8231
+ const rule = isReviewBot
8232
+ ? "review bots are allowed only for github-review tasks"
8233
+ : isExternalSender
8234
+ ? "external senders are allowed only for PR comments, reviews, and github-pr tasks on pull requests"
8235
+ : "sender is not on the internal, external, or reviewBots allowlist";
8236
+ const reason = \`GitHub sender "\${login || "unknown"}" is blocked: \${rule}.\`;
8237
+ ctx.log.warn(reason, { login: login || null, taskType, vcsUrl: options.vcsUrl ?? null });
8238
+ return block(reason);
8239
+ });
8240
+ };
8241
+
8242
+ export default extension;
8243
+ `
8244
+ },
8245
+ readme: '# github-sender-allowlist\n\nBlocks GitHub webhook tasks from senders outside the configured allowlists. Login matching is case-insensitive. Tasks from other sources pass through. No task type is exempt by default.\n\nConfig:\n\n```json\n{\n "internal": ["tarasyarema", "harlequinetcie"],\n "external": ["fuvidani", "capchase-bot"],\n "reviewBots": [],\n "exemptTaskTypes": []\n}\n```\n\nInternal senders can create any GitHub task, including reviews. Logins in `reviewBots` can create `github-review` tasks only. External senders can create `github-comment` or `github-pr` tasks on pull requests, and `github-review` tasks when `vcsUrl` contains `/pull/`. Choose any review-bot logins from the sender census in the [security audit](https://live.agent-fs.dev/file/~/648a5f3c-35c8-4f11-8673-b89de52cd6bd/2faf73ba-4eee-4472-8b3b-359c4ed6bfbb/thoughts/a09d19a4-bd35-4593-9b6f-c2ccafccead8/reviews/2026-09-28-github-sender-authorization-audit.md) when installing the extension; the template intentionally defaults to an empty list.\n\n`exemptTaskTypes` is an optional operator override for explicitly exempting task types. It defaults to an empty list. The GitHub handler does not pass the action for `github-pr` tasks, so external `github-pr` access also permits assignment and label events on pull requests.\n'
8246
+ },
8052
8247
  "notify-on-complete": {
8053
8248
  manifestFile: "manifest.json",
8054
8249
  manifest: {
@@ -14072,18 +14267,20 @@ async function handleMemory(req, res, pathSegments, callerAgentId) {
14072
14267
  source,
14073
14268
  isLead: false
14074
14269
  });
14075
- const ranked = rerank(expanded, { limit: Math.min(limit, 20) });
14270
+ const resultLimit = Math.min(limit, 20);
14271
+ const consumptionHeader = req.headers["x-memory-consumption"];
14272
+ const consumptionMode = Array.isArray(consumptionHeader) ? consumptionHeader[0] : consumptionHeader;
14273
+ const ranked = consumptionMode === "prompt" ? rerank(expanded, { limit: expanded.length }).map((r) => ({ r, eligible: memoryRelevance(r) > SIMILARITY_THRESHOLD })).sort((a, b) => Number(b.eligible) - Number(a.eligible)).slice(0, resultLimit).map(({ r }) => r) : rerank(expanded, { limit: resultLimit });
14076
14274
  const sourceTaskIdHeader = req.headers["x-source-task-id"];
14077
14275
  const sourceTaskId = Array.isArray(sourceTaskIdHeader) ? sourceTaskIdHeader[0] : sourceTaskIdHeader;
14078
14276
  const contextKeyHeader = req.headers["x-context-key"];
14079
14277
  const contextKey = Array.isArray(contextKeyHeader) ? contextKeyHeader[0] : contextKeyHeader;
14080
- const consumptionHeader = req.headers["x-memory-consumption"];
14081
- const consumptionMode = Array.isArray(consumptionHeader) ? consumptionHeader[0] : consumptionHeader;
14082
14278
  if (sourceTaskId && intent) {
14083
14279
  try {
14084
14280
  await recordRetrievals(sourceTaskId, myAgentId, ranked.map((r) => ({
14085
14281
  memoryId: r.id,
14086
14282
  similarity: r.similarity,
14283
+ relevance: r.rawSimilarity,
14087
14284
  retrievalSource: r.retrievalSource
14088
14285
  })), undefined, { intent, contextKey, eventType: "search" });
14089
14286
  } catch (err) {
@@ -14092,7 +14289,7 @@ async function handleMemory(req, res, pathSegments, callerAgentId) {
14092
14289
  }
14093
14290
  let consumedIds = [];
14094
14291
  if (intent) {
14095
- const consumed = consumptionMode === "prompt" ? ranked.filter((r) => r.similarity > SIMILARITY_THRESHOLD) : ranked;
14292
+ const consumed = consumptionMode === "prompt" ? ranked.filter((r) => memoryRelevance(r) > SIMILARITY_THRESHOLD) : ranked;
14096
14293
  consumedIds = dedupeMemoryDocumentIds(consumed);
14097
14294
  try {
14098
14295
  await recordMemoryAccesses(consumedIds);
@@ -15803,11 +16000,19 @@ function slackMilestone(state) {
15803
16000
  action_url: automationIntegrationFixUrl("slack")
15804
16001
  };
15805
16002
  }
16003
+ if (config.mode === "socket" && getSlackConnectionState() === "connected") {
16004
+ return {
16005
+ id: "slack",
16006
+ label: "Slack configured",
16007
+ state: "verified",
16008
+ action_url: automationIntegrationFixUrl("slack")
16009
+ };
16010
+ }
15806
16011
  return {
15807
16012
  id: "slack",
15808
16013
  label: "Slack configured",
15809
16014
  state: "configured",
15810
- hint: config.mode === "http" ? "HTTP credentials are configured, but HTTP ingress is unavailable until the receiver is installed." : "Socket Mode credentials are configured; a live connection has not been verified.",
16015
+ hint: config.mode === "http" ? "HTTP credentials are configured, but HTTP ingress is unavailable until the receiver is installed." : "Socket Mode credentials are configured, but the bot is not connected to Slack.",
15811
16016
  action_url: automationIntegrationFixUrl("slack")
15812
16017
  };
15813
16018
  }
@@ -23348,7 +23553,7 @@ var createSessionCostRoute = route({
23348
23553
  model: exports_external.string().optional(),
23349
23554
  models: exports_external.array(SessionCostModelBreakdownSchema.omit({ costUsd: true })).optional(),
23350
23555
  isError: exports_external.boolean().optional(),
23351
- provider: exports_external.enum(["claude", "claude-managed", "codex", "pi", "opencode", "devin", "gemini", "acp"]).optional(),
23556
+ provider: PricingProviderSchema.optional(),
23352
23557
  createdAt: exports_external.number().int().nonnegative().optional()
23353
23558
  }),
23354
23559
  responses: {
@@ -23700,6 +23905,7 @@ var listSessions = route({
23700
23905
  source: exports_external.string().optional(),
23701
23906
  q: exports_external.string().optional(),
23702
23907
  requestedByUserId: exports_external.string().min(1).optional(),
23908
+ contextKeyPrefix: exports_external.string().min(1).optional(),
23703
23909
  fields: exports_external.enum(["full", "slim"]).optional()
23704
23910
  }),
23705
23911
  responses: {
@@ -23773,13 +23979,15 @@ async function handleSessions(req, res, pathSegments, queryParams) {
23773
23979
  offset: parsed.query.offset,
23774
23980
  source: sources,
23775
23981
  q: parsed.query.q,
23776
- requestedByUserId: parsed.query.requestedByUserId
23982
+ requestedByUserId: parsed.query.requestedByUserId,
23983
+ contextKeyPrefix: parsed.query.contextKeyPrefix
23777
23984
  };
23778
23985
  const sessions = parsed.query.fields === "full" ? await listRecentSessions(baseOpts) : await listRecentSessions({ ...baseOpts, slim: true });
23779
23986
  const total = await countSessions({
23780
23987
  source: sources,
23781
23988
  q: parsed.query.q,
23782
- requestedByUserId: parsed.query.requestedByUserId
23989
+ requestedByUserId: parsed.query.requestedByUserId,
23990
+ contextKeyPrefix: parsed.query.contextKeyPrefix
23783
23991
  });
23784
23992
  listSessions.respond(res, 200, {
23785
23993
  sessions,
@@ -23799,18 +24007,17 @@ async function handleSessions(req, res, pathSegments, queryParams) {
23799
24007
  return true;
23800
24008
  }
23801
24009
  const chain = await getRootTaskChain(parsed.params.rootTaskId);
23802
- getSession.respond(res, 200, {
23803
- root: {
23804
- ...root,
23805
- ...await getTaskSteeringFields(root),
23806
- citations: await getTaskCitations(root.id)
23807
- },
23808
- chain: await Promise.all(chain.map(async (task) => ({
23809
- ...task,
23810
- ...await getTaskSteeringFields(task),
23811
- citations: await getTaskCitations(task.id)
23812
- })))
24010
+ const tasks = [root, ...chain];
24011
+ const [steering, citations] = await Promise.all([
24012
+ getTaskSteeringFieldsForTasks(tasks),
24013
+ getTaskCitationsForTasks(tasks.map((task) => task.id))
24014
+ ]);
24015
+ const decorate = (task) => ({
24016
+ ...task,
24017
+ ...steering.get(task.id),
24018
+ citations: citations.get(task.id)
23813
24019
  });
24020
+ getSession.respond(res, 200, { root: decorate(root), chain: chain.map(decorate) });
23814
24021
  return true;
23815
24022
  }
23816
24023
  return false;
@@ -24732,6 +24939,7 @@ var listScheduledTasks = route({
24732
24939
  path: "/api/scheduled-tasks",
24733
24940
  pattern: ["api", "scheduled-tasks"],
24734
24941
  summary: "List scheduled tasks",
24942
+ description: "Returns full schedules by default. Pass `fields=slim` for the list-view shape, which swaps the full `taskTemplate` for a bounded `taskTemplatePreview`. Fetch one schedule in full via `GET /api/schedules/{id}`.",
24735
24943
  tags: ["Stats"],
24736
24944
  query: exports_external.object({
24737
24945
  enabled: exports_external.enum(["true", "false"]).optional(),
@@ -24740,12 +24948,18 @@ var listScheduledTasks = route({
24740
24948
  hideCompleted: exports_external.enum(["true", "false"]).optional(),
24741
24949
  targetType: exports_external.enum(["agent-task", "workflow", "script"]).optional(),
24742
24950
  workflowId: exports_external.string().uuid().optional(),
24743
- scriptName: exports_external.string().optional()
24951
+ scriptName: exports_external.string().optional(),
24952
+ fields: exports_external.enum(["full", "slim"]).optional()
24744
24953
  }),
24745
24954
  responses: {
24746
24955
  200: {
24747
24956
  description: "Scheduled tasks list",
24748
- schema: exports_external.object({ scheduledTasks: exports_external.array(ScheduledTaskSchema) })
24957
+ schema: exports_external.object({
24958
+ scheduledTasks: exports_external.union([
24959
+ exports_external.array(ScheduledTaskSchema),
24960
+ exports_external.array(scheduleSummaryWithFavoriteSchema)
24961
+ ])
24962
+ })
24749
24963
  }
24750
24964
  }
24751
24965
  });
@@ -24825,7 +25039,7 @@ async function handleStats(req, res, pathSegments, queryParams, myAgentId) {
24825
25039
  const parsed = await listScheduledTasks.parse(req, res, pathSegments, queryParams);
24826
25040
  if (!parsed)
24827
25041
  return true;
24828
- const scheduledTasks = await getScheduledTasks({
25042
+ const filters = {
24829
25043
  enabled: parsed.query.enabled !== undefined ? parsed.query.enabled === "true" : undefined,
24830
25044
  name: parsed.query.name || undefined,
24831
25045
  scheduleType: parsed.query.scheduleType || undefined,
@@ -24833,13 +25047,11 @@ async function handleStats(req, res, pathSegments, queryParams, myAgentId) {
24833
25047
  targetType: parsed.query.targetType,
24834
25048
  workflowId: parsed.query.workflowId,
24835
25049
  scriptName: parsed.query.scriptName
24836
- });
25050
+ };
24837
25051
  const favoriteScope = (await resolveHttpFavoriteOwner(req, myAgentId))?.scope;
25052
+ const favoriteOpts = { favoriteScope, itemType: "schedule" };
24838
25053
  listScheduledTasks.respond(res, 200, {
24839
- scheduledTasks: await withFavoriteFlags(scheduledTasks, {
24840
- favoriteScope,
24841
- itemType: "schedule"
24842
- })
25054
+ scheduledTasks: parsed.query.fields === "slim" ? await withFavoriteFlags(await getScheduledTasks(filters, { slim: true }), favoriteOpts) : await withFavoriteFlags(await getScheduledTasks(filters), favoriteOpts)
24843
25055
  });
24844
25056
  return true;
24845
25057
  }
@@ -24927,6 +25139,19 @@ var AgentTaskSummarySchema2 = AgentTaskSchema.pick({
24927
25139
  peakContextPercent: true,
24928
25140
  totalCostUsd: true
24929
25141
  });
25142
+ var AgentTaskTimelineItemSchema = AgentTaskSchema.pick({
25143
+ id: true,
25144
+ agentId: true,
25145
+ parentTaskId: true,
25146
+ task: true,
25147
+ title: true,
25148
+ status: true,
25149
+ createdAt: true,
25150
+ lastUpdatedAt: true,
25151
+ finishedAt: true,
25152
+ peakContextTokens: true,
25153
+ totalCostUsd: true
25154
+ });
24930
25155
  var TaskActionResultSchema = exports_external.object({
24931
25156
  success: exports_external.literal(true),
24932
25157
  task: AgentTaskSchema
@@ -24971,7 +25196,7 @@ var listTasks = route({
24971
25196
  path: "/api/tasks",
24972
25197
  pattern: ["api", "tasks"],
24973
25198
  summary: "List tasks with filters",
24974
- description: "Returns tasks with the full `task` text replaced by a bounded `taskPreview` and completion/integration blobs dropped by default — list views only need the preview. Pass `fields=full` to restore the full `AgentTask`. Fetch a single task in full via `GET /api/tasks/{id}`.",
25199
+ description: "Returns tasks with the full `task` text replaced by a bounded `taskPreview` and completion/integration blobs dropped by default — list views only need the preview. Pass `fields=full` to restore the full `AgentTask`, or `fields=timeline` for the narrow shape the dashboard timeline draws. Fetch a single task in full via `GET /api/tasks/{id}`. `total` (the filtered row count, ignoring limit/offset) is computed only with `includeTotal=true`.",
24975
25200
  tags: ["Tasks"],
24976
25201
  query: exports_external.object({
24977
25202
  status: exports_external.string().optional(),
@@ -24988,14 +25213,19 @@ var listTasks = route({
24988
25213
  orderBy: exports_external.enum(["lastUpdatedAt", "createdAt"]).optional(),
24989
25214
  limit: exports_external.coerce.number().int().optional(),
24990
25215
  offset: exports_external.coerce.number().int().optional(),
24991
- fields: exports_external.enum(["full", "slim"]).optional()
25216
+ fields: exports_external.enum(["full", "slim", "timeline"]).optional(),
25217
+ includeTotal: exports_external.enum(["true", "false"]).optional()
24992
25218
  }),
24993
25219
  responses: {
24994
25220
  200: {
24995
25221
  description: "Paginated task list",
24996
25222
  schema: exports_external.object({
24997
- tasks: exports_external.union([exports_external.array(AgentTaskSchema), exports_external.array(AgentTaskSummarySchema2)]),
24998
- total: exports_external.number().int()
25223
+ tasks: exports_external.union([
25224
+ exports_external.array(AgentTaskSchema),
25225
+ exports_external.array(AgentTaskSummarySchema2),
25226
+ exports_external.array(AgentTaskTimelineItemSchema)
25227
+ ]),
25228
+ total: exports_external.number().int().optional()
24999
25229
  })
25000
25230
  },
25001
25231
  400: { description: "Validation error (e.g. unknown status token)" }
@@ -25489,9 +25719,13 @@ async function handleTasks(req, res, pathSegments, queryParams, myAgentId) {
25489
25719
  limit: parsed.query.limit,
25490
25720
  offset: parsed.query.offset
25491
25721
  };
25492
- const tasks = parsed.query.fields === "full" ? await getAllTasks(filters) : await getAllTasks(filters, { slim: true });
25493
- const total = await getTasksCount(filters);
25494
- listTasks.respond(res, 200, { tasks, total });
25722
+ const tasks = parsed.query.fields === "full" ? await getAllTasks(filters) : parsed.query.fields === "timeline" ? await getAllTasks(filters, { fields: "timeline" }) : await getAllTasks(filters, { slim: true });
25723
+ if (parsed.query.includeTotal === "true") {
25724
+ const total = await getTasksCount(filters);
25725
+ listTasks.respond(res, 200, { tasks, total });
25726
+ } else {
25727
+ listTasks.respond(res, 200, { tasks });
25728
+ }
25495
25729
  return true;
25496
25730
  }
25497
25731
  if (createTask.match(req.method, pathSegments)) {
@@ -27890,8 +28124,21 @@ async function routeKapsoInbound(payload) {
27890
28124
  init_event_bus();
27891
28125
  var WebhookDispatchResultSchema = exports_external.object({
27892
28126
  created: exports_external.boolean(),
27893
- taskId: exports_external.string().optional()
28127
+ taskId: exports_external.string().optional(),
28128
+ skipped: exports_external.boolean().optional(),
28129
+ reason: exports_external.string().optional(),
28130
+ extension: exports_external.object({ id: exports_external.string(), name: exports_external.string() }).optional()
27894
28131
  });
28132
+ async function runBlockableHandler(source, handler) {
28133
+ try {
28134
+ return await handler();
28135
+ } catch (err) {
28136
+ if (!(err instanceof TaskCreationBlockedError))
28137
+ throw err;
28138
+ console.log(`[${source}] Task creation blocked by extension ${err.extension.name}: ${err.reason}`);
28139
+ return { created: false, skipped: true, reason: err.reason, extension: err.extension };
28140
+ }
28141
+ }
27895
28142
  var githubWebhook = route({
27896
28143
  method: "post",
27897
28144
  path: "/api/github/webhook",
@@ -28039,34 +28286,29 @@ async function handleWebhooks(req, res, pathSegments) {
28039
28286
  console.log(`[GitHub] Received ${eventType} event`);
28040
28287
  let result = { created: false };
28041
28288
  try {
28042
- switch (eventType) {
28043
- case "pull_request":
28044
- result = await handlePullRequest(body);
28045
- break;
28046
- case "issues":
28047
- result = await handleIssue(body);
28048
- break;
28049
- case "issue_comment":
28050
- result = await handleComment(body, "issue_comment");
28051
- break;
28052
- case "pull_request_review_comment":
28053
- result = await handleComment(body, "pull_request_review_comment");
28054
- break;
28055
- case "pull_request_review":
28056
- result = await handlePullRequestReview(body);
28057
- break;
28058
- case "check_run":
28059
- result = await handleCheckRun(body);
28060
- break;
28061
- case "check_suite":
28062
- result = await handleCheckSuite(body);
28063
- break;
28064
- case "workflow_run":
28065
- result = await handleWorkflowRun(body);
28066
- break;
28067
- default:
28068
- console.log(`[GitHub] Ignoring unsupported event type: ${eventType}`);
28069
- }
28289
+ result = await runBlockableHandler("GitHub", async () => {
28290
+ switch (eventType) {
28291
+ case "pull_request":
28292
+ return await handlePullRequest(body);
28293
+ case "issues":
28294
+ return await handleIssue(body);
28295
+ case "issue_comment":
28296
+ return await handleComment(body, "issue_comment");
28297
+ case "pull_request_review_comment":
28298
+ return await handleComment(body, "pull_request_review_comment");
28299
+ case "pull_request_review":
28300
+ return await handlePullRequestReview(body);
28301
+ case "check_run":
28302
+ return await handleCheckRun(body);
28303
+ case "check_suite":
28304
+ return await handleCheckSuite(body);
28305
+ case "workflow_run":
28306
+ return await handleWorkflowRun(body);
28307
+ default:
28308
+ console.log(`[GitHub] Ignoring unsupported event type: ${eventType}`);
28309
+ return { created: false };
28310
+ }
28311
+ });
28070
28312
  switch (eventType) {
28071
28313
  case "pull_request": {
28072
28314
  const pr = body;
@@ -28155,22 +28397,21 @@ async function handleWebhooks(req, res, pathSegments) {
28155
28397
  console.log(`[GitLab] Received ${objectKind} event`);
28156
28398
  let result = { created: false };
28157
28399
  try {
28158
- switch (objectKind) {
28159
- case "merge_request":
28160
- result = await handleMergeRequest(body);
28161
- break;
28162
- case "issue":
28163
- result = await handleIssue2(body);
28164
- break;
28165
- case "note":
28166
- result = await handleNote(body);
28167
- break;
28168
- case "pipeline":
28169
- result = await handlePipeline(body);
28170
- break;
28171
- default:
28172
- console.log(`[GitLab] Ignoring unsupported event type: ${objectKind}`);
28173
- }
28400
+ result = await runBlockableHandler("GitLab", async () => {
28401
+ switch (objectKind) {
28402
+ case "merge_request":
28403
+ return await handleMergeRequest(body);
28404
+ case "issue":
28405
+ return await handleIssue2(body);
28406
+ case "note":
28407
+ return await handleNote(body);
28408
+ case "pipeline":
28409
+ return await handlePipeline(body);
28410
+ default:
28411
+ console.log(`[GitLab] Ignoring unsupported event type: ${objectKind}`);
28412
+ return { created: false };
28413
+ }
28414
+ });
28174
28415
  switch (objectKind) {
28175
28416
  case "merge_request": {
28176
28417
  const mr = body;
@@ -28463,8 +28704,9 @@ var ExecutorTypeInfoSchema = exports_external.object({
28463
28704
  configSchema: exports_external.record(exports_external.string(), exports_external.unknown()),
28464
28705
  outputSchema: exports_external.record(exports_external.string(), exports_external.unknown())
28465
28706
  });
28707
+ var DEFAULT_WORKFLOW_RUNS_LIMIT = 50;
28466
28708
  var WorkflowRunPageSchema = exports_external.object({
28467
- runs: exports_external.array(WorkflowRunSchema),
28709
+ runs: exports_external.array(WorkflowRunSummarySchema),
28468
28710
  page: exports_external.object({
28469
28711
  limit: exports_external.number().int(),
28470
28712
  offset: exports_external.number().int(),
@@ -28646,7 +28888,8 @@ var listWorkflowRunsRoute = route({
28646
28888
  method: "get",
28647
28889
  path: "/api/workflows/{id}/runs",
28648
28890
  pattern: ["api", "workflows", null, "runs"],
28649
- summary: "List runs for a workflow",
28891
+ summary: "List runs for a workflow, newest first",
28892
+ description: `Returns one page of runs without \`context\` (fetch it with GET /api/workflow-runs/{id}). \`limit\` defaults to ${DEFAULT_WORKFLOW_RUNS_LIMIT} and is capped at 100; follow \`page.nextOffset\` while \`page.hasMore\` is true.`,
28650
28893
  tags: ["Workflows"],
28651
28894
  params: exports_external.object({ id: exports_external.string() }),
28652
28895
  query: exports_external.object({
@@ -28656,8 +28899,8 @@ var listWorkflowRunsRoute = route({
28656
28899
  }),
28657
28900
  responses: {
28658
28901
  200: {
28659
- description: "Workflow run list",
28660
- schema: exports_external.union([exports_external.array(WorkflowRunSchema), WorkflowRunPageSchema])
28902
+ description: "One page of workflow runs",
28903
+ schema: WorkflowRunPageSchema
28661
28904
  }
28662
28905
  }
28663
28906
  });
@@ -29132,18 +29375,12 @@ async function handleWorkflows(req, res, pathSegments, queryParams, myAgentId) {
29132
29375
  const parsed = await listWorkflowRunsRoute.parse(req, res, pathSegments, queryParams);
29133
29376
  if (!parsed)
29134
29377
  return true;
29135
- const paginationRequested = parsed.query?.limit !== undefined || parsed.query?.offset !== undefined;
29136
- if (paginationRequested) {
29137
- const page = await listWorkflowRunsPage(parsed.params.id, {
29138
- status: parsed.query?.status,
29139
- limit: parsed.query?.limit ?? 20,
29140
- offset: parsed.query?.offset ?? 0
29141
- });
29142
- listWorkflowRunsRoute.respond(res, 200, page);
29143
- return true;
29144
- }
29145
- const runs = await listWorkflowRuns(parsed.params.id, { status: parsed.query?.status });
29146
- listWorkflowRunsRoute.respond(res, 200, runs);
29378
+ const page = await listWorkflowRunsPage(parsed.params.id, {
29379
+ status: parsed.query?.status,
29380
+ limit: parsed.query?.limit ?? DEFAULT_WORKFLOW_RUNS_LIMIT,
29381
+ offset: parsed.query?.offset ?? 0
29382
+ });
29383
+ listWorkflowRunsRoute.respond(res, 200, page);
29147
29384
  return true;
29148
29385
  }
29149
29386
  if (getWorkflowRunRoute.match(req.method, pathSegments)) {
@@ -29613,7 +29850,7 @@ async function shutdown() {
29613
29850
  sessionsProcessed: getServerSessionsProcessed()
29614
29851
  });
29615
29852
  if (hasCapability("scheduling")) {
29616
- const { stopScheduler } = await import("./index-50jxgw0d.js");
29853
+ const { stopScheduler } = await import("./index-chgdkq36.js");
29617
29854
  stopScheduler();
29618
29855
  }
29619
29856
  stopHeartbeat();
@@ -29621,7 +29858,7 @@ async function shutdown() {
29621
29858
  await stopScriptRunSupervisor();
29622
29859
  await stopSlackApp();
29623
29860
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
29624
- const { stopOAuthKeepalive } = await import("./keepalive-nnz07ebd.js");
29861
+ const { stopOAuthKeepalive } = await import("./keepalive-vtkf5n99.js");
29625
29862
  await stopOAuthKeepalive();
29626
29863
  }
29627
29864
  stopOAuthPendingGc();
@@ -29689,23 +29926,23 @@ try {
29689
29926
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
29690
29927
  }
29691
29928
  try {
29692
- const { seedPricingFromModelsDev } = await import("./seed-pricing-ncgxz1r2.js");
29693
- seedPricingFromModelsDev();
29694
- const { startPricingRefreshLoop } = await import("./pricing-refresh-3whntb69.js");
29929
+ const { ensurePricingSeeded } = await import("./boot-seeds-s3q01xj3.js");
29930
+ ensurePricingSeeded();
29931
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-v1cbr9te.js");
29695
29932
  startPricingRefreshLoop();
29696
29933
  } catch (err) {
29697
29934
  console.error("[startup] Failed to seed pricing rows:", err);
29698
29935
  }
29699
29936
  try {
29700
- const { ensureRbacSeedsSynced } = await import("./rbac-roles-3zw68x72.js");
29701
- ensureRbacSeedsSynced();
29937
+ const { ensureRbacSeeded } = await import("./boot-seeds-s3q01xj3.js");
29938
+ ensureRbacSeeded();
29702
29939
  } catch (err) {
29703
29940
  console.error("[startup] Failed to sync RBAC seed rows:", err);
29704
29941
  if (isRbacEnabled())
29705
29942
  throw err;
29706
29943
  }
29707
29944
  try {
29708
- const { runAllSeeders } = await import("./index-1fktvwxc.js");
29945
+ const { runAllSeeders } = await import("./index-a3vn96n8.js");
29709
29946
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
29710
29947
  } catch (err) {
29711
29948
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -29759,36 +29996,36 @@ httpServer.listen(port, async () => {
29759
29996
  await initWorkflows();
29760
29997
  await startScriptRunSupervisor(getMcpBaseUrl());
29761
29998
  if (hasCapability("scheduling")) {
29762
- const { startScheduler } = await import("./index-50jxgw0d.js");
29763
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-7x131mmf.js");
29999
+ const { startScheduler } = await import("./index-chgdkq36.js");
30000
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-1yks3qcr.js");
29764
30001
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
29765
30002
  startScheduler(getExecutorRegistry2(), intervalMs, {
29766
30003
  runId: globalState.__runId
29767
30004
  });
29768
30005
  }
29769
30006
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
29770
- const { startHeartbeat } = await import("./index-7jwk7nsm.js");
30007
+ const { startHeartbeat } = await import("./index-x71bvq0p.js");
29771
30008
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
29772
30009
  startHeartbeat(heartbeatMs);
29773
30010
  }
29774
30011
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
29775
- const { startOAuthKeepalive } = await import("./keepalive-nnz07ebd.js");
30012
+ const { startOAuthKeepalive } = await import("./keepalive-vtkf5n99.js");
29776
30013
  startOAuthKeepalive();
29777
30014
  }
29778
30015
  if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
29779
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-c63sqfs1.js");
30016
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-qp3dzmdp.js");
29780
30017
  startOAuthRefreshSweep();
29781
30018
  }
29782
30019
  startOAuthPendingGc();
29783
30020
  await startMemoryGc();
29784
30021
  await startDbRetention();
29785
- import("./boot-reembed-r00j03f3.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
30022
+ import("./boot-reembed-se8zmdcp.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
29786
30023
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
29787
30024
  });
29788
- import("./boot-reembed-0be1krkm.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
30025
+ import("./boot-reembed-g5ckg9yb.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
29789
30026
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
29790
30027
  });
29791
- import("./boot-scrub-logs-9j4hd0vw.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
30028
+ import("./boot-scrub-logs-wfxqan61.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
29792
30029
  console.error("[boot-scrub-logs] startup scrub failed (non-fatal):", err);
29793
30030
  });
29794
30031
  }).on("error", (err) => {