@desplega.ai/agent-swarm 1.172.0 → 1.173.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 (214) hide show
  1. package/dist/{acp-adapter-fpecx1g1.js → acp-adapter-ccm9xrep.js} +8 -8
  2. package/dist/{actions-pw87a1a8.js → actions-sgeyv08k.js} +44 -19
  3. package/dist/{amp-adapter-8jem2bc0.js → amp-adapter-gpxp3kc9.js} +1 -1
  4. package/dist/{anthropic-messages-8ee2f22q.js → anthropic-messages-r6czkjv1.js} +7 -7
  5. package/dist/{app-wmf0m843.js → app-km9qnv2f.js} +6 -4
  6. package/dist/{assistant-emp1e108.js → assistant-5r8tcvvd.js} +44 -22
  7. package/dist/{boot-reembed-4ymn9atn.js → boot-reembed-16rv9843.js} +4 -3
  8. package/dist/{boot-reembed-1de4f4aj.js → boot-reembed-swwzdgd7.js} +4 -3
  9. package/dist/{boot-scrub-sweep-adhk1s8c.js → boot-scrub-sweep-zkr6vkqb.js} +5 -4
  10. package/dist/{boot-seeds-8q637aew.js → boot-seeds-d8sp49t2.js} +7 -6
  11. package/dist/{claude-adapter-t26cv8a4.js → claude-adapter-yzzzh8jp.js} +9 -9
  12. package/dist/{claude-sdk-session-gsfsh662.js → claude-sdk-session-4whxere4.js} +9458 -9164
  13. package/dist/{cli-g4f5pj26.js → cli-0a7mm3zp.js} +92 -10
  14. package/dist/{cli-pj6x9qce.js → cli-0kxf81jj.js} +1 -1
  15. package/dist/{cli-kb4ehzx5.js → cli-1w0vj3gw.js} +4 -4
  16. package/dist/{cli-e0a9sk00.js → cli-3nxdmjrc.js} +1 -1
  17. package/dist/{cli-6jb2rf77.js → cli-42qhyvwx.js} +3 -3
  18. package/dist/{cli-esnpehf5.js → cli-5er5gjbm.js} +4 -4
  19. package/dist/{cli-04emfe2q.js → cli-5wpw4rab.js} +1 -1
  20. package/dist/{cli-aspcaef3.js → cli-6r2f7edk.js} +4 -4
  21. package/dist/{cli-xczpdp9e.js → cli-6thk4jz3.js} +1 -1
  22. package/dist/{cli-j6kpj9az.js → cli-7a93cv8c.js} +1458 -48
  23. package/dist/{cli-k46r9hmk.js → cli-94b48jhk.js} +2 -2
  24. package/dist/{cli-gp1rtyvk.js → cli-9xf7fdtp.js} +2 -2
  25. package/dist/{cli-qsztpfry.js → cli-anzdk0z4.js} +1 -1
  26. package/dist/{cli-cceskcvt.js → cli-b07hr3bt.js} +8 -8
  27. package/dist/{cli-c2pq2rjb.js → cli-bv2etw2y.js} +2 -2
  28. package/dist/{cli-hwwvy36w.js → cli-c3rk1v0x.js} +3 -3
  29. package/dist/{cli-tgpfnm6r.js → cli-fmhj1ehj.js} +53 -13
  30. package/dist/{cli-r8smj8b8.js → cli-jpc4r224.js} +1 -1
  31. package/dist/{cli-4nz8p1p5.js → cli-m89t9jdf.js} +5 -5
  32. package/dist/{cli-bf7485pm.js → cli-na2pxe4f.js} +1 -1
  33. package/dist/{cli-prrt9fa0.js → cli-ne7smj1b.js} +4 -4
  34. package/dist/{cli-cf69s3ew.js → cli-nwrdx840.js} +2 -2
  35. package/dist/cli-p0sg24zp.js +16 -0
  36. package/dist/{cli-gj81e47t.js → cli-phcqp1b9.js} +1 -1
  37. package/dist/{cli-5rv1j9ga.js → cli-qm1448f9.js} +51 -5
  38. package/dist/{cli-8hzfb6xz.js → cli-r0byd61h.js} +7 -7
  39. package/dist/{cli-nyhb1r6x.js → cli-r4fqfpwf.js} +3 -3
  40. package/dist/{cli-1hgat6pa.js → cli-rfs4vddv.js} +5 -5
  41. package/dist/{cli-ztrv9y21.js → cli-rfz2ve55.js} +861 -246
  42. package/dist/{cli-pstq9888.js → cli-s8z6x4b4.js} +22 -21
  43. package/dist/{cli-j1pmc07z.js → cli-saqyage0.js} +92 -16
  44. package/dist/{cli-zxm9p3x4.js → cli-srqq3gc5.js} +1 -1
  45. package/dist/{cli-9xsmdpdt.js → cli-tcc4wd5d.js} +136 -42
  46. package/dist/cli-v3zhnxsb.js +263 -0
  47. package/dist/{cli-388egyf6.js → cli-w1apjecb.js} +1 -1
  48. package/dist/{cli-g6t9texm.js → cli-wrh08zjd.js} +4 -4
  49. package/dist/{cli-8vs9trd4.js → cli-x119kdba.js} +1 -1
  50. package/dist/{cli-nv4zd0b9.js → cli-xc7p7s3g.js} +1 -1
  51. package/dist/cli.js +16 -16
  52. package/dist/{codex-adapter-m4tgdysy.js → codex-adapter-r3dn4fp5.js} +6 -6
  53. package/dist/{codex-session-runner-ymwzm6ea.js → codex-session-runner-fwt793h4.js} +6 -6
  54. package/dist/{commands-n0hshcvs.js → commands-z8fq9qna.js} +14 -4
  55. package/dist/{controllers-connect-y07cqcvy.js → controllers-connect-3mf2btyj.js} +21 -19
  56. package/dist/{db-4w7tmt1g.js → db-qfpq4bt7.js} +4 -3
  57. package/dist/{db-hkqvrdcb.js → db-yyhqqrbf.js} +5 -4
  58. package/dist/{dispatcher-5sd69y14.js → dispatcher-x0x7qfcq.js} +20 -18
  59. package/dist/{dsh-adapter-2h8m4cab.js → dsh-adapter-34etvb5m.js} +1 -1
  60. package/dist/external-channel-h1fjecwe.js +51 -0
  61. package/dist/{grok-adapter-8m9yqzbq.js → grok-adapter-e7mr287e.js} +9 -9
  62. package/dist/{handlers-s20xr10r.js → handlers-znb9n7d4.js} +23 -21
  63. package/dist/{heartbeat-3k31q4g2.js → heartbeat-bm4qkn8d.js} +22 -20
  64. package/dist/{hook-gdn6a2fn.js → hook-254r4mza.js} +7 -7
  65. package/dist/{hook-ygwerrdh.js → hook-xaa3q80s.js} +8 -8
  66. package/dist/{http-jdteeg81.js → http-3dgrgp8y.js} +135 -64
  67. package/dist/{index-6ksewd5y.js → index-2ybk7khy.js} +618 -120
  68. package/dist/{index-tsszt7g9.js → index-bdsqa799.js} +22 -20
  69. package/dist/{index-e0snym4t.js → index-fx3jqq1e.js} +20 -18
  70. package/dist/{index-vm3bm9t7.js → index-g2byveez.js} +20 -18
  71. package/dist/{index-ffqzqgwb.js → index-jd7sejm2.js} +4 -3
  72. package/dist/{keepalive-jekc896t.js → keepalive-6ywhpja1.js} +6 -5
  73. package/dist/{lead-4k9s9szx.js → lead-cw45n21s.js} +32 -30
  74. package/dist/{maintenance-shazch4n.js → maintenance-ss1a1ge9.js} +4 -3
  75. package/dist/node-c9we95xf.js +1 -1
  76. package/dist/{oauth-refresh-sweep-5gb36kn8.js → oauth-refresh-sweep-3c6f8vyy.js} +5 -4
  77. package/dist/{onboard-ydrbnvww.js → onboard-8hzdhc1k.js} +2 -2
  78. package/dist/{opencode-adapter-5zh0he20.js → opencode-adapter-qbchbcfz.js} +6 -6
  79. package/dist/{otel-impl-6pf5cv86.js → otel-impl-e6mnvc4v.js} +7 -2
  80. package/dist/{pi-mono-adapter-ef9wwx9m.js → pi-mono-adapter-3c9g9snh.js} +6 -6
  81. package/dist/{pricing-refresh-s52nsa5q.js → pricing-refresh-gedkjdw0.js} +6 -5
  82. package/dist/{rbac-roles-aq3msh4e.js → rbac-roles-dt4vh1yy.js} +4 -3
  83. package/dist/{rbac-roles-q5gb5e8v.js → rbac-roles-eszdg6pm.js} +5 -4
  84. package/dist/{render-v2-pd1rg54q.js → render-v2-907cy6sa.js} +6 -4
  85. package/dist/{resume-gw4a2c6v.js → resume-42stcaz0.js} +11 -9
  86. package/dist/{setup-jda1ksdh.js → setup-adbc1c10.js} +2 -2
  87. package/dist/{virtual-modules-b3ga2m65.js → virtual-modules-rtmt494q.js} +3 -3
  88. package/dist/{work-objects-tb7ycye8.js → work-objects-wpj8ck95.js} +28 -21
  89. package/dist/{worker-njjccz5d.js → worker-bzdra9rf.js} +32 -30
  90. package/openapi.json +423 -7
  91. package/package.json +4 -4
  92. package/src/apps/catalog.generated.json +1309 -53
  93. package/src/apps/page-validator.ts +93 -31
  94. package/src/azure-devops/api.ts +94 -18
  95. package/src/azure-devops/auth.ts +32 -0
  96. package/src/azure-devops/boards-sync.ts +708 -0
  97. package/src/azure-devops/handlers.ts +52 -8
  98. package/src/azure-devops/html.ts +26 -0
  99. package/src/azure-devops/index.ts +15 -0
  100. package/src/azure-devops/templates.ts +86 -0
  101. package/src/azure-devops/types.ts +65 -1
  102. package/src/be/db.ts +22 -6
  103. package/src/be/migrations/213_script_connections_sql.sql +79 -0
  104. package/src/be/script-connections.ts +47 -8
  105. package/src/be/seed-skills/bundled-files.generated.json +10 -0
  106. package/src/be/seed-skills/index.ts +3 -0
  107. package/src/be/sql-connections.ts +118 -0
  108. package/src/be/swarm-config-guard.ts +1 -0
  109. package/src/commands/profile-sync.ts +5 -3
  110. package/src/commands/runner.ts +6 -2
  111. package/src/http/mcp-oauth.ts +6 -13
  112. package/src/http/pages-public.ts +3 -2
  113. package/src/http/pages.ts +2 -1
  114. package/src/http/route-def.ts +7 -6
  115. package/src/http/script-connection-proxy.ts +51 -4
  116. package/src/http/script-connections.ts +5 -2
  117. package/src/http/session-cost-recompute.ts +12 -2
  118. package/src/http/session-data.ts +4 -0
  119. package/src/http/webhooks.ts +24 -1
  120. package/src/jira/adf.ts +3 -1
  121. package/src/kv-reserved-namespaces.ts +2 -0
  122. package/src/oauth/mcp-wrapper.ts +10 -6
  123. package/src/otel-impl.ts +2 -1
  124. package/src/prompts/base-prompt.ts +3 -3
  125. package/src/providers/acp-targets.ts +1 -1
  126. package/src/providers/amp-adapter.ts +1 -1
  127. package/src/providers/claude-adapter.ts +27 -2
  128. package/src/providers/claude-flag-settings.ts +121 -0
  129. package/src/providers/claude-sdk-session.ts +7 -0
  130. package/src/providers/dsh-adapter.ts +1 -1
  131. package/src/providers/opencode-adapter.ts +26 -12
  132. package/src/providers/opencode-billing.ts +86 -0
  133. package/src/providers/opencode-swarm-plugin.ts +20 -0
  134. package/src/providers/pricing-sources.md +4 -1
  135. package/src/providers/types.ts +5 -0
  136. package/src/scripts-runtime/api-client.ts +15 -1
  137. package/src/scripts-runtime/api-types.ts +9 -1
  138. package/src/scripts-runtime/ctx.ts +1 -1
  139. package/src/scripts-runtime/mcp-client.ts +30 -19
  140. package/src/slack/actions.ts +29 -1
  141. package/src/slack/app.ts +14 -2
  142. package/src/slack/assistant.ts +36 -2
  143. package/src/slack/channel-join.ts +3 -16
  144. package/src/slack/commands.ts +9 -1
  145. package/src/slack/external-channel-egress.ts +113 -0
  146. package/src/slack/external-channel.ts +309 -0
  147. package/src/slack/handlers.ts +61 -0
  148. package/src/slack/render-v2.ts +40 -47
  149. package/src/slack/work-objects.ts +5 -0
  150. package/src/tasks/context-key.ts +34 -1
  151. package/src/telemetry.ts +2 -1
  152. package/src/tests/apps-catalog-feedback.test.ts +310 -0
  153. package/src/tests/apps-catalog-inputs.test.ts +70 -0
  154. package/src/tests/apps-catalog-table.test.ts +113 -0
  155. package/src/tests/azure-devops-boards-sync.test.ts +584 -0
  156. package/src/tests/azure-devops-html.test.ts +13 -0
  157. package/src/tests/azure-devops-webhook-malformed.test.ts +4 -0
  158. package/src/tests/claude-adapter-binary.test.ts +139 -0
  159. package/src/tests/claude-flag-settings.test.ts +106 -0
  160. package/src/tests/claude-sdk-lifecycle.test.ts +142 -1
  161. package/src/tests/claude-sdk-process.fixture.ts +7 -0
  162. package/src/tests/context-key.test.ts +32 -0
  163. package/src/tests/deferred-task-wake.test.ts +52 -4
  164. package/src/tests/docs-index-footprint.test.js +3 -3
  165. package/src/tests/dsh-adapter.test.ts +1 -1
  166. package/src/tests/fixtures/azure-boards/workitem.commented.json +89 -0
  167. package/src/tests/fixtures/azure-boards/workitem.created.json +81 -0
  168. package/src/tests/fixtures/azure-boards/workitem.deleted.json +70 -0
  169. package/src/tests/fixtures/azure-boards/workitem.restored.json +82 -0
  170. package/src/tests/fixtures/azure-boards/workitem.updated.json +130 -0
  171. package/src/tests/fixtures/catalog-feedback-definition.json.txt +860 -0
  172. package/src/tests/fixtures/catalog-inputs-definition.json.txt +910 -0
  173. package/src/tests/fixtures/catalog-table-definition.json.txt +468 -0
  174. package/src/tests/fixtures/runner-identity-refresh.ts +3 -0
  175. package/src/tests/node-env-runtime.test.ts +98 -0
  176. package/src/tests/opencode-adapter.test.ts +132 -1
  177. package/src/tests/opencode-billing.test.ts +28 -0
  178. package/src/tests/runner-identity-refresh.test.ts +3 -0
  179. package/src/tests/script-connections-sql.test.ts +675 -0
  180. package/src/tests/script-connections.test.ts +5 -1
  181. package/src/tests/session-cost-recompute-unit.test.ts +48 -0
  182. package/src/tests/slack-channel-join.test.ts +4 -1
  183. package/src/tests/slack-external-channel-config.test.ts +65 -0
  184. package/src/tests/slack-external-channel-egress.test.ts +237 -0
  185. package/src/tests/slack-external-channel-guard.test.ts +280 -0
  186. package/src/tests/slack-external-channel-tools.test.ts +173 -0
  187. package/src/tests/slack-external-channel.test.ts +370 -0
  188. package/src/tests/slack-render-v2.test.ts +86 -10
  189. package/src/tests/spec-base-url.test.ts +16 -1
  190. package/src/tests/vendored-openapi.test.ts +16 -1
  191. package/src/tools/defer-task.ts +17 -0
  192. package/src/tools/slack-post.ts +6 -0
  193. package/src/tools/slack-read.ts +8 -0
  194. package/src/tools/slack-reply.ts +6 -0
  195. package/src/tools/slack-start-thread.ts +6 -0
  196. package/src/tools/slack-update.ts +6 -0
  197. package/src/tools/slack-upload-file.ts +6 -0
  198. package/src/utils/node-env.ts +24 -0
  199. package/templates/skills/apps/SKILL.md +742 -0
  200. package/templates/skills/apps/content.md +52 -21
  201. package/templates/skills/qa-loom/config.json +14 -0
  202. package/templates/skills/qa-loom/content.md +187 -0
  203. package/templates/skills/qa-loom/files/build-loom.mjs +221 -0
  204. package/templates/skills/qa-loom/files/run-qa.sh +57 -0
  205. package/templates/skills/slack-interaction/content.md +4 -0
  206. package/dist/{azure-openai-responses-ap1gwxgr.js → azure-openai-responses-ygfreq4t.js} +5 -5
  207. package/dist/{cli-4fnb6884.js → cli-h7k0xtry.js} +3 -3
  208. package/dist/{cli-5rqrj7q0.js → cli-pw7ebjdt.js} +0 -0
  209. package/dist/{google-generative-ai-7pavrbv7.js → google-generative-ai-szdxbpqg.js} +1 -1
  210. package/dist/{google-vertex-3f1jk41f.js → google-vertex-qzw3p36d.js} +1 -1
  211. package/dist/{openai-codex-responses-33qhkkdy.js → openai-codex-responses-3bk0grnr.js} +4 -4
  212. package/dist/{openai-completions-s88xm3ns.js → openai-completions-5d4jpakc.js} +9 -9
  213. package/dist/{openai-responses-7xd2f2e2.js → openai-responses-krb51f59.js} +5 -5
  214. package/dist/{pi-messages-xszk613n.js → pi-messages-x9gzynm1.js} +3 -3
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  ensurePricingSeeded,
22
22
  ensureRbacSeeded
23
- } from "./cli-6jb2rf77.js";
23
+ } from "./cli-42qhyvwx.js";
24
24
  import {
25
25
  buildCatalogEntries,
26
26
  getCatalogGeneration,
@@ -30,10 +30,10 @@ import {
30
30
  requestModelCatalogRefresh,
31
31
  startPricingRefreshLoop,
32
32
  upsertModelCatalogOverlay
33
- } from "./cli-gp1rtyvk.js";
33
+ } from "./cli-9xf7fdtp.js";
34
34
  import {
35
35
  loadModelsDevCache
36
- } from "./cli-r8smj8b8.js";
36
+ } from "./cli-jpc4r224.js";
37
37
  import {
38
38
  AppDefinitionSchema,
39
39
  AppElementsSchema,
@@ -90,7 +90,7 @@ import {
90
90
  upsertScriptConnection,
91
91
  validateScriptImports,
92
92
  writeBareImportShim
93
- } from "./cli-j6kpj9az.js";
93
+ } from "./cli-7a93cv8c.js";
94
94
  import {
95
95
  detachedProcessGroup,
96
96
  registerProcessGroup,
@@ -102,7 +102,7 @@ import {
102
102
  ensureToken,
103
103
  ensureTokenOrThrow,
104
104
  onAuthorizationRefreshed
105
- } from "./cli-388egyf6.js";
105
+ } from "./cli-w1apjecb.js";
106
106
  import {
107
107
  AgentFsProvider,
108
108
  getFileStorageProvider,
@@ -158,7 +158,7 @@ import {
158
158
  walkGraph,
159
159
  withSaveWarnings,
160
160
  workflowSaveWarnings
161
- } from "./cli-kb4ehzx5.js";
161
+ } from "./cli-1w0vj3gw.js";
162
162
  import {
163
163
  BaseExecutor,
164
164
  HumanInTheLoopExecutor,
@@ -172,11 +172,14 @@ import {
172
172
  resolveValidationPort,
173
173
  resolveWorkflowLlmConfig,
174
174
  validateDefinition
175
- } from "./cli-aspcaef3.js";
175
+ } from "./cli-6r2f7edk.js";
176
176
  import {
177
177
  ZodFirstPartyTypeKind,
178
178
  objectType
179
179
  } from "./cli-fad8m16k.js";
180
+ import {
181
+ require_dist
182
+ } from "./cli-51tf7ac3.js";
180
183
  import {
181
184
  CitationInputSchema,
182
185
  MAX_TASK_CITATIONS,
@@ -200,10 +203,14 @@ import {
200
203
  taskCitationWarnings,
201
204
  upsertTaskCitations,
202
205
  withSpan
203
- } from "./cli-9xsmdpdt.js";
206
+ } from "./cli-tcc4wd5d.js";
204
207
  import {
205
- require_dist
206
- } from "./cli-51tf7ac3.js";
208
+ externalChannelToolError,
209
+ getChannelBlockReason,
210
+ slackCode,
211
+ slackMissingScopeMessage,
212
+ withAutoJoin
213
+ } from "./cli-v3zhnxsb.js";
207
214
  import {
208
215
  findOrCreateUserByEmail,
209
216
  findUserByEmail,
@@ -221,7 +228,7 @@ import {
221
228
  resolveUserByToken,
222
229
  revokeRuntimeTokensForRuntime,
223
230
  unlinkIdentity
224
- } from "./cli-e0a9sk00.js";
231
+ } from "./cli-3nxdmjrc.js";
225
232
  import {
226
233
  canProvisionKind,
227
234
  init_runtime_providers
@@ -229,7 +236,7 @@ import {
229
236
  import {
230
237
  getUserGrant,
231
238
  init_rbac_roles
232
- } from "./cli-qsztpfry.js";
239
+ } from "./cli-anzdk0z4.js";
233
240
  import {
234
241
  can,
235
242
  decideAdmission,
@@ -255,6 +262,7 @@ import {
255
262
  agentContextKey,
256
263
  agentmailContextKey,
257
264
  azureDevOpsContextKey,
265
+ azureDevOpsWorkItemContextKey,
258
266
  beginRequestAuthScope,
259
267
  breaksJsonValidity,
260
268
  buildJiraContextKey,
@@ -546,7 +554,7 @@ import {
546
554
  upsertSwarmConfig,
547
555
  validateConfigValue,
548
556
  workflowContextKey
549
- } from "./cli-tgpfnm6r.js";
557
+ } from "./cli-fmhj1ehj.js";
550
558
  import {
551
559
  $OpenAPIRegistry,
552
560
  $OpenApiGeneratorV31,
@@ -616,7 +624,7 @@ import {
616
624
  init_task_attachment_links,
617
625
  taskAttachmentDisplayUrl,
618
626
  taskAttachmentFetchCommand
619
- } from "./cli-nyhb1r6x.js";
627
+ } from "./cli-r4fqfpwf.js";
620
628
  import {
621
629
  getSlackConfiguration,
622
630
  init_config
@@ -690,10 +698,14 @@ import {
690
698
  unknown,
691
699
  uuid
692
700
  } from "./cli-w5e1d1vv.js";
701
+ import {
702
+ getNodeEnv,
703
+ init_node_env
704
+ } from "./cli-p0sg24zp.js";
693
705
  import {
694
706
  init_package,
695
707
  package_default
696
- } from "./cli-esnpehf5.js";
708
+ } from "./cli-5er5gjbm.js";
697
709
  import {
698
710
  init_event_bus,
699
711
  workflowEventBus
@@ -23010,6 +23022,32 @@ function normalizeOrgUrl(url) {
23010
23022
  const trimmed = url?.trim().replace(/\/+$/, "");
23011
23023
  return trimmed ? trimmed : null;
23012
23024
  }
23025
+ function orgKeyOf(url) {
23026
+ if (!url)
23027
+ return null;
23028
+ let parsed;
23029
+ try {
23030
+ parsed = new URL(url);
23031
+ } catch {
23032
+ return null;
23033
+ }
23034
+ if (parsed.protocol !== "https:" || parsed.username || parsed.password)
23035
+ return null;
23036
+ const host = parsed.host.toLowerCase();
23037
+ if (host !== "dev.azure.com")
23038
+ return host;
23039
+ const org = parsed.pathname.split("/").find(Boolean);
23040
+ return org ? `${host}/${org.toLowerCase()}` : null;
23041
+ }
23042
+ function isTrustedOrgUrl(url) {
23043
+ const key = orgKeyOf(url);
23044
+ if (!key)
23045
+ return false;
23046
+ const configured = orgKeyOf(orgUrl);
23047
+ if (orgUrl)
23048
+ return key === configured;
23049
+ return key.startsWith("dev.azure.com/") || key.endsWith(".visualstudio.com");
23050
+ }
23013
23051
  var AZURE_DEVOPS_BOT_NAME = process.env.AZURE_DEVOPS_BOT_NAME ?? "agent-swarm-bot";
23014
23052
  function resetAzureDevOps() {
23015
23053
  initialized3 = false;
@@ -23033,35 +23071,69 @@ function headers() {
23033
23071
  function pullRequestBase(ref) {
23034
23072
  return `${ref.orgUrl}/${encodeURIComponent(ref.projectId)}/_apis/git/repositories/` + `${encodeURIComponent(ref.repositoryId)}/pullRequests/${ref.pullRequestId}`;
23035
23073
  }
23036
- var cachedBotId = null;
23074
+
23075
+ class AzureDevOpsLookupError extends Error {
23076
+ }
23077
+ var cachedBotIdentity = null;
23078
+ function credentialedOrgUrl(orgBaseUrl) {
23079
+ const orgUrl2 = normalizeOrgUrl(orgBaseUrl) ?? getAzureDevOpsOrgUrl();
23080
+ if (!orgUrl2 || !getAzureDevOpsToken())
23081
+ return null;
23082
+ if (!isTrustedOrgUrl(orgUrl2)) {
23083
+ console.error("[AzureDevOps] Refusing to send credentials to an untrusted organization URL");
23084
+ return null;
23085
+ }
23086
+ return orgUrl2;
23087
+ }
23088
+ async function loadBotIdentity(orgUrl2) {
23089
+ if (cachedBotIdentity?.orgUrl === orgUrl2)
23090
+ return cachedBotIdentity.identity;
23091
+ let data;
23092
+ try {
23093
+ const resp = await fetch(`${orgUrl2}/_apis/connectionData`, {
23094
+ headers: headers(),
23095
+ redirect: "error"
23096
+ });
23097
+ if (!resp.ok)
23098
+ throw new AzureDevOpsLookupError(`connectionData returned ${resp.status}`);
23099
+ data = await resp.json();
23100
+ } catch (err) {
23101
+ if (err instanceof AzureDevOpsLookupError)
23102
+ throw err;
23103
+ throw new AzureDevOpsLookupError(`connectionData request failed: ${String(err)}`);
23104
+ }
23105
+ const identity = {
23106
+ id: data.authenticatedUser?.id ?? null,
23107
+ uniqueName: data.authenticatedUser?.properties?.Account?.$value?.trim() || null
23108
+ };
23109
+ if (identity.id || identity.uniqueName)
23110
+ cachedBotIdentity = { orgUrl: orgUrl2, identity };
23111
+ return identity;
23112
+ }
23037
23113
  async function resolveAzureDevOpsBotId(orgBaseUrl) {
23038
23114
  const fromEnv = process.env.AZURE_DEVOPS_BOT_ID?.trim();
23039
23115
  if (fromEnv)
23040
23116
  return fromEnv;
23041
- const orgUrl2 = normalizeOrgUrl(orgBaseUrl) ?? getAzureDevOpsOrgUrl();
23042
- if (!orgUrl2 || !getAzureDevOpsToken())
23117
+ const orgUrl2 = credentialedOrgUrl(orgBaseUrl);
23118
+ if (!orgUrl2)
23043
23119
  return null;
23044
- if (cachedBotId?.orgUrl === orgUrl2)
23045
- return cachedBotId.id;
23046
23120
  try {
23047
- const resp = await fetch(`${orgUrl2}/_apis/connectionData`, { headers: headers() });
23048
- if (!resp.ok) {
23049
- console.error(`[AzureDevOps] Failed to resolve bot identity: ${resp.status}`);
23050
- return null;
23051
- }
23052
- const data = await resp.json();
23053
- const id = data.authenticatedUser?.id;
23054
- if (!id)
23055
- return null;
23056
- cachedBotId = { orgUrl: orgUrl2, id };
23057
- return id;
23121
+ return (await loadBotIdentity(orgUrl2)).id;
23058
23122
  } catch (err) {
23059
- console.error(`[AzureDevOps] Error resolving bot identity:`, err);
23123
+ console.error(`[AzureDevOps] Failed to resolve bot identity:`, err);
23060
23124
  return null;
23061
23125
  }
23062
23126
  }
23127
+ async function resolveAzureDevOpsBotIdentity(orgBaseUrl) {
23128
+ const fromEnv = process.env.AZURE_DEVOPS_BOT_ID?.trim() || null;
23129
+ const orgUrl2 = credentialedOrgUrl(orgBaseUrl);
23130
+ if (!orgUrl2)
23131
+ return { id: fromEnv, uniqueName: null };
23132
+ const identity = await loadBotIdentity(orgUrl2);
23133
+ return { id: fromEnv ?? identity.id, uniqueName: identity.uniqueName };
23134
+ }
23063
23135
  function resetAzureDevOpsBotIdCache() {
23064
- cachedBotId = null;
23136
+ cachedBotIdentity = null;
23065
23137
  }
23066
23138
  async function likeAzureDevOpsComment(ref, threadId, commentId) {
23067
23139
  const url = `${pullRequestBase(ref)}/threads/${threadId}/comments/${commentId}/likes?api-version=${API_VERSION}`;
@@ -23074,6 +23146,156 @@ async function likeAzureDevOpsComment(ref, threadId, commentId) {
23074
23146
  console.error(`[AzureDevOps] Error liking comment:`, err);
23075
23147
  }
23076
23148
  }
23149
+ // src/azure-devops/boards-sync.ts
23150
+ init_db3();
23151
+
23152
+ // src/be/db-queries/tracker.ts
23153
+ init_date_utils();
23154
+ init_db3();
23155
+ function normalizeTrackerSync(row) {
23156
+ return {
23157
+ ...row,
23158
+ lastSyncedAt: normalizeDateRequired(row.lastSyncedAt),
23159
+ createdAt: normalizeDateRequired(row.createdAt)
23160
+ };
23161
+ }
23162
+ function normalizeTrackerAgentMapping(row) {
23163
+ return {
23164
+ ...row,
23165
+ createdAt: normalizeDateRequired(row.createdAt)
23166
+ };
23167
+ }
23168
+ async function getTrackerSync(provider, entityType, swarmId) {
23169
+ const row = await getDbClient().get("SELECT * FROM tracker_sync WHERE provider = ? AND entityType = ? AND swarmId = ?", [provider, entityType, swarmId]);
23170
+ return row ? normalizeTrackerSync(row) : null;
23171
+ }
23172
+ async function getTrackerSyncByExternalId(provider, entityType, externalId) {
23173
+ const row = await getDbClient().get("SELECT * FROM tracker_sync WHERE provider = ? AND entityType = ? AND externalId = ?", [provider, entityType, externalId]);
23174
+ return row ? normalizeTrackerSync(row) : null;
23175
+ }
23176
+ async function createTrackerSyncIfAbsent(data) {
23177
+ const insertResult = await getDbClient().get(`INSERT INTO tracker_sync (provider, entityType, providerEntityType, swarmId, externalId, externalIdentifier, externalUrl, lastSyncOrigin, lastDeliveryId, syncDirection)
23178
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
23179
+ ON CONFLICT (provider, entityType, externalId) DO NOTHING
23180
+ RETURNING *`, [
23181
+ data.provider,
23182
+ data.entityType,
23183
+ data.providerEntityType ?? null,
23184
+ data.swarmId,
23185
+ data.externalId,
23186
+ data.externalIdentifier ?? null,
23187
+ data.externalUrl ?? null,
23188
+ data.lastSyncOrigin ?? null,
23189
+ data.lastDeliveryId ?? null,
23190
+ data.syncDirection ?? "inbound"
23191
+ ]);
23192
+ if (insertResult) {
23193
+ return { inserted: true, sync: normalizeTrackerSync(insertResult) };
23194
+ }
23195
+ const existing = await getTrackerSyncByExternalId(data.provider, data.entityType, data.externalId);
23196
+ if (!existing) {
23197
+ throw new Error(`[tracker] createTrackerSyncIfAbsent: ON CONFLICT fired but no existing row found for (${data.provider}, ${data.entityType}, ${data.externalId})`);
23198
+ }
23199
+ return { inserted: false, sync: existing };
23200
+ }
23201
+ async function updateTrackerSyncSwarmId(id, swarmId) {
23202
+ await getDbClient().run("UPDATE tracker_sync SET swarmId = ? WHERE id = ?", [swarmId, id]);
23203
+ }
23204
+ async function repointTrackerSyncBySwarmId(oldSwarmId, newSwarmId) {
23205
+ const result = await getDbClient().run("UPDATE tracker_sync SET swarmId = ? WHERE swarmId = ?", [
23206
+ newSwarmId,
23207
+ oldSwarmId
23208
+ ]);
23209
+ return Number(result.changes ?? 0);
23210
+ }
23211
+ async function createTrackerSync(data) {
23212
+ const result = await getDbClient().get(`INSERT INTO tracker_sync (provider, entityType, providerEntityType, swarmId, externalId, externalIdentifier, externalUrl, lastSyncOrigin, lastDeliveryId, syncDirection)
23213
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
23214
+ RETURNING *`, [
23215
+ data.provider,
23216
+ data.entityType,
23217
+ data.providerEntityType ?? null,
23218
+ data.swarmId,
23219
+ data.externalId,
23220
+ data.externalIdentifier ?? null,
23221
+ data.externalUrl ?? null,
23222
+ data.lastSyncOrigin ?? null,
23223
+ data.lastDeliveryId ?? null,
23224
+ data.syncDirection ?? "inbound"
23225
+ ]);
23226
+ return normalizeTrackerSync(result);
23227
+ }
23228
+ async function updateTrackerSync(id, data) {
23229
+ const sets = [];
23230
+ const values = [];
23231
+ if (data.lastSyncedAt !== undefined) {
23232
+ sets.push("lastSyncedAt = ?");
23233
+ values.push(data.lastSyncedAt);
23234
+ }
23235
+ if (data.lastSyncOrigin !== undefined) {
23236
+ sets.push("lastSyncOrigin = ?");
23237
+ values.push(data.lastSyncOrigin);
23238
+ }
23239
+ if (data.lastDeliveryId !== undefined) {
23240
+ sets.push("lastDeliveryId = ?");
23241
+ values.push(data.lastDeliveryId);
23242
+ }
23243
+ if (data.syncDirection !== undefined) {
23244
+ sets.push("syncDirection = ?");
23245
+ values.push(data.syncDirection);
23246
+ }
23247
+ if (data.externalUrl !== undefined) {
23248
+ sets.push("externalUrl = ?");
23249
+ values.push(data.externalUrl);
23250
+ }
23251
+ if (data.externalIdentifier !== undefined) {
23252
+ sets.push("externalIdentifier = ?");
23253
+ values.push(data.externalIdentifier);
23254
+ }
23255
+ if (sets.length === 0)
23256
+ return;
23257
+ values.push(id);
23258
+ await getDbClient().run(`UPDATE tracker_sync SET ${sets.join(", ")} WHERE id = ?`, values);
23259
+ }
23260
+ async function deleteTrackerSync(id) {
23261
+ await getDbClient().run("DELETE FROM tracker_sync WHERE id = ?", [id]);
23262
+ }
23263
+ async function hasTrackerDelivery(provider, deliveryId) {
23264
+ if (!deliveryId)
23265
+ return false;
23266
+ const row = await getDbClient().get("SELECT 1 AS hit FROM tracker_sync WHERE provider = ? AND lastDeliveryId = ? LIMIT 1", [provider, deliveryId]);
23267
+ return !!row;
23268
+ }
23269
+ async function markTrackerDelivery(provider, entityType, externalId, deliveryId) {
23270
+ await getDbClient().run("UPDATE tracker_sync SET lastDeliveryId = ? WHERE provider = ? AND entityType = ? AND externalId = ?", [deliveryId, provider, entityType, externalId]);
23271
+ }
23272
+ async function getAllTrackerSyncs(provider, entityType) {
23273
+ const conditions = [];
23274
+ const values = [];
23275
+ if (provider) {
23276
+ conditions.push("provider = ?");
23277
+ values.push(provider);
23278
+ }
23279
+ if (entityType) {
23280
+ conditions.push("entityType = ?");
23281
+ values.push(entityType);
23282
+ }
23283
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
23284
+ const rows = await getDbClient().query(`SELECT * FROM tracker_sync ${where} ORDER BY createdAt DESC`, values);
23285
+ return rows.map(normalizeTrackerSync);
23286
+ }
23287
+ async function createTrackerAgentMapping(data) {
23288
+ const result = await getDbClient().get(`INSERT INTO tracker_agent_mapping (provider, agentId, externalUserId, agentName)
23289
+ VALUES (?, ?, ?, ?)
23290
+ RETURNING *`, [data.provider, data.agentId, data.externalUserId, data.agentName]);
23291
+ return normalizeTrackerAgentMapping(result);
23292
+ }
23293
+
23294
+ // src/azure-devops/boards-sync.ts
23295
+ init_resolver();
23296
+ init_context_key();
23297
+ init_types();
23298
+
23077
23299
  // src/azure-devops/handlers.ts
23078
23300
  init_db3();
23079
23301
  init_users();
@@ -23210,6 +23432,81 @@ Comment:
23210
23432
  ],
23211
23433
  category: "event"
23212
23434
  });
23435
+ registerTemplate({
23436
+ eventType: "common.command_suggestions.azure_devops_work_item",
23437
+ header: "",
23438
+ defaultBody: 'Workers have the `az` CLI with the azure-devops extension, authenticated with the swarm PAT. Inspect the work item with `az boards work-item show --id {{work_item_id}}`. To reply on it, run `az boards work-item update --id {{work_item_id}} --discussion "<reply>"`.',
23439
+ variables: [{ name: "work_item_id", description: "Work item ID" }],
23440
+ category: "common"
23441
+ });
23442
+ var WORK_ITEM_VARIABLES = [
23443
+ { name: "work_item_id", description: "Work item ID" },
23444
+ { name: "work_item_type", description: "Work item type (Task, Bug, Issue, ...)" },
23445
+ { name: "title", description: "Work item title" },
23446
+ { name: "state", description: "Work item state" },
23447
+ { name: "project", description: "Azure DevOps project name" },
23448
+ { name: "work_item_url", description: "Work item web URL" },
23449
+ {
23450
+ name: "username",
23451
+ description: "Actor identity — resolved canonical name (e.g. 'Luis (azure-devops:luis@example.com)') or the UNKNOWN sentinel"
23452
+ }
23453
+ ];
23454
+ registerTemplate({
23455
+ eventType: "azure-devops.work_item.assigned",
23456
+ header: "[Azure DevOps {{work_item_type}} #{{work_item_id}}] {{title}}",
23457
+ defaultBody: `Project: {{project}}
23458
+ State: {{state}}
23459
+ Triggered by: {{username}} ({{trigger}})
23460
+ URL: {{work_item_url}}
23461
+
23462
+ {{description_section}}{{@template[common.command_suggestions.azure_devops_work_item]}}{{@template[common.delegation_instruction.azure_devops]}}`,
23463
+ variables: [
23464
+ ...WORK_ITEM_VARIABLES,
23465
+ { name: "trigger", description: "Why the task was created (assigned to the bot, mentioned)" },
23466
+ {
23467
+ name: "description_section",
23468
+ description: "Description section (HTML stripped) or empty string"
23469
+ }
23470
+ ],
23471
+ category: "event"
23472
+ });
23473
+ registerTemplate({
23474
+ eventType: "azure-devops.work_item.commented",
23475
+ header: "[Azure DevOps {{work_item_type}} #{{work_item_id}}] {{username}} mentioned bot",
23476
+ defaultBody: `Project: {{project}}
23477
+ Title: {{title}}
23478
+ State: {{state}}
23479
+ URL: {{work_item_url}}
23480
+
23481
+ Comment:
23482
+ {{context}}{{existing_task_note}}
23483
+
23484
+ {{@template[common.command_suggestions.azure_devops_work_item]}}{{@template[common.delegation_instruction.azure_devops]}}`,
23485
+ variables: [
23486
+ ...WORK_ITEM_VARIABLES,
23487
+ { name: "context", description: "Comment text with the bot mention removed" },
23488
+ { name: "existing_task_note", description: "Note about an active task, or empty string" }
23489
+ ],
23490
+ category: "event"
23491
+ });
23492
+ registerTemplate({
23493
+ eventType: "azure-devops.work_item.followup",
23494
+ header: "[Azure DevOps {{work_item_type}} #{{work_item_id}}] Follow-up: {{title}}",
23495
+ defaultBody: `Project: {{project}}
23496
+ State: {{state}}
23497
+ Trigger: {{trigger}} by {{username}}
23498
+ URL: {{work_item_url}}
23499
+
23500
+ {{user_message}}
23501
+
23502
+ {{@template[common.command_suggestions.azure_devops_work_item]}}{{@template[common.delegation_instruction.azure_devops]}}`,
23503
+ variables: [
23504
+ ...WORK_ITEM_VARIABLES,
23505
+ { name: "trigger", description: "What re-engaged the swarm" },
23506
+ { name: "user_message", description: "Comment text, or empty string" }
23507
+ ],
23508
+ category: "event"
23509
+ });
23213
23510
 
23214
23511
  // src/azure-devops/handlers.ts
23215
23512
  var processedEvents2 = new Map;
@@ -23305,6 +23602,10 @@ async function resolveAzureDevOpsSender(identity, sampleEventType, sampleContext
23305
23602
  await linkIdentity(linked.id, "azure-devops", externalId, AZURE_DEVOPS_WEBHOOK_ACTOR);
23306
23603
  return linked.id;
23307
23604
  }
23605
+ await recordUnmappedIdentity(externalId, sampleEventType, sampleContext);
23606
+ return;
23607
+ }
23608
+ async function recordUnmappedIdentity(externalId, sampleEventType, sampleContext) {
23308
23609
  await upsertKv({
23309
23610
  namespace: UNMAPPED_NAMESPACE,
23310
23611
  key: `${externalId}:meta`,
@@ -23317,7 +23618,18 @@ async function resolveAzureDevOpsSender(identity, sampleEventType, sampleContext
23317
23618
  expiresAt: Date.now() + UNMAPPED_TTL_MS
23318
23619
  });
23319
23620
  await incrKv(UNMAPPED_NAMESPACE, `${externalId}:count`, 1);
23320
- return;
23621
+ }
23622
+ async function authorizeAzureDevOpsActor(identity, sampleEventType, sampleContext) {
23623
+ const externalId = externalIdOf(identity);
23624
+ const known = await findUserByExternalId("azure-devops", externalId) ?? (externalId.includes("@") ? await findUserByEmail(externalId) : null);
23625
+ if (known)
23626
+ return known.id;
23627
+ const allowed = (process.env.AZURE_DEVOPS_ALLOWED_ACTORS ?? "").split(",").map((name) => name.trim().toLowerCase()).filter(Boolean);
23628
+ if (allowed.includes(externalId.toLowerCase())) {
23629
+ return await resolveAzureDevOpsSender(identity, sampleEventType, sampleContext) ?? null;
23630
+ }
23631
+ await recordUnmappedIdentity(externalId, sampleEventType, sampleContext);
23632
+ return null;
23321
23633
  }
23322
23634
  async function renderAzureDevOpsIdentity(identity) {
23323
23635
  return renderIdentity(await resolveIdentity("azure-devops", externalIdOf(identity)));
@@ -23469,6 +23781,460 @@ _Note: There's an active task (${existingTask.id}) for this PR #${pr.pullRequest
23469
23781
  }
23470
23782
  return { created: true, taskId: task.id };
23471
23783
  }
23784
+
23785
+ // src/azure-devops/html.ts
23786
+ var ENTITIES = {
23787
+ "&amp;": "&",
23788
+ "&lt;": "<",
23789
+ "&gt;": ">",
23790
+ "&quot;": '"',
23791
+ "&#39;": "'",
23792
+ "&nbsp;": " "
23793
+ };
23794
+ function htmlToText(html) {
23795
+ if (!html)
23796
+ return "";
23797
+ return html.replace(/<br\s*\/?>|<\/(?:div|p|li|h[1-6])>/gi, `
23798
+ `).replace(/<[^>]*>/g, "").replace(/&(?:amp|lt|gt|quot|#39|nbsp);/g, (entity) => ENTITIES[entity] ?? entity).replace(/[ \t]+/g, " ").replace(/ ?\n ?/g, `
23799
+ `).replace(/\n{3,}/g, `
23800
+
23801
+ `).trim();
23802
+ }
23803
+
23804
+ // src/azure-devops/boards-sync.ts
23805
+ var PROVIDER = "azure-devops";
23806
+ var DELETED_REASON = "Azure DevOps work item deleted";
23807
+ var DESCRIPTION_LIMIT = 4000;
23808
+ function hasFields(value) {
23809
+ return typeof value === "object" && value !== null;
23810
+ }
23811
+ function workItemOf(event) {
23812
+ const resource = event?.resource;
23813
+ if (typeof event?.id !== "string" || typeof resource?.id !== "number")
23814
+ return null;
23815
+ return hasFields(resource.fields) ? resource : null;
23816
+ }
23817
+ function updatedPayloadOf(event) {
23818
+ const resource = event?.resource;
23819
+ if (typeof event?.id !== "string" || typeof resource?.workItemId !== "number")
23820
+ return null;
23821
+ return hasFields(resource.revision?.fields) ? resource : null;
23822
+ }
23823
+ function parseIdentityString(value) {
23824
+ if (typeof value !== "string" || !value.trim())
23825
+ return null;
23826
+ const match = value.match(/^(.*?)\s*<([^>]+)>\s*$/);
23827
+ const displayName = (match?.[1] || value).trim();
23828
+ const uniqueName = match?.[2]?.trim();
23829
+ return { id: uniqueName ?? displayName, displayName, uniqueName };
23830
+ }
23831
+ async function resolveBot(orgUrl2) {
23832
+ return await resolveAzureDevOpsBotIdentity(orgUrl2);
23833
+ }
23834
+ function isBotIdentity(identity, bot) {
23835
+ if (!identity)
23836
+ return false;
23837
+ if (bot.id && identity.id.toLowerCase() === bot.id.toLowerCase())
23838
+ return true;
23839
+ const name = identity.uniqueName?.toLowerCase();
23840
+ return !!name && !!bot.uniqueName && name === bot.uniqueName.toLowerCase();
23841
+ }
23842
+ function isBotString(value, bot) {
23843
+ return isBotIdentity(parseIdentityString(value), bot);
23844
+ }
23845
+ function pickerMentionPattern(botId) {
23846
+ return new RegExp(`<a\\b[^>]*data-vss-mention="version:[\\d.]+,${escapeRegExp(botId)}"[^>]*>.*?</a>`, "gi");
23847
+ }
23848
+ function plainMentionPatterns(bot) {
23849
+ const names = [AZURE_DEVOPS_BOT_NAME];
23850
+ const local = bot.uniqueName?.split("@")[0];
23851
+ if (local)
23852
+ names.push(local);
23853
+ return names.map((name) => new RegExp(`@${escapeRegExp(name)}(?![\\w-])`, "gi"));
23854
+ }
23855
+ function inspectMention(html, bot) {
23856
+ if (!html)
23857
+ return { mentioned: false, text: "" };
23858
+ let withoutPicker = html;
23859
+ let mentioned = false;
23860
+ if (bot.id) {
23861
+ const re = pickerMentionPattern(bot.id);
23862
+ mentioned = re.test(html);
23863
+ withoutPicker = html.replace(re, "");
23864
+ }
23865
+ let text = htmlToText(withoutPicker);
23866
+ const plain = plainMentionPatterns(bot);
23867
+ if (plain.some((re) => re.test(text)) || detectMention(text, null)) {
23868
+ mentioned = true;
23869
+ }
23870
+ for (const re of plain)
23871
+ text = text.replace(re, "");
23872
+ return { mentioned, text: text.trim() };
23873
+ }
23874
+ function orgFor(event) {
23875
+ const containers = event.resourceContainers;
23876
+ const fromUrl = event.resource?.url?.split("/_apis/")[0];
23877
+ const candidates = [
23878
+ containers?.account?.baseUrl,
23879
+ containers?.collection?.baseUrl,
23880
+ fromUrl?.includes("://") ? fromUrl : undefined
23881
+ ].map((url2) => normalizeOrgUrl(url2)).filter((url2) => !!url2);
23882
+ const configured = getAzureDevOpsOrgUrl();
23883
+ const url = candidates[0] ?? configured;
23884
+ if (!url || !isTrustedOrgUrl(url))
23885
+ return null;
23886
+ const key = orgKeyOf(url);
23887
+ if (!key || candidates.some((c) => orgKeyOf(c) !== key))
23888
+ return null;
23889
+ return { url, key };
23890
+ }
23891
+ function dropUntrustedOrg(eventType) {
23892
+ console.warn(`[AzureDevOps] Dropping ${eventType} event from an untrusted organization`);
23893
+ return { created: false };
23894
+ }
23895
+ function trackerKey(org, workItemId) {
23896
+ return `${org.key}#${workItemId}`;
23897
+ }
23898
+ function organizationOf(orgUrl2) {
23899
+ if (!orgUrl2)
23900
+ return "unknown";
23901
+ try {
23902
+ const url = new URL(orgUrl2);
23903
+ const segment = url.pathname.split("/").find(Boolean);
23904
+ return (segment ?? url.hostname.split(".")[0] ?? "unknown").replace(/:/g, "_");
23905
+ } catch {
23906
+ return "unknown";
23907
+ }
23908
+ }
23909
+ function workItemUrl(ctx) {
23910
+ const project = ctx.fields["System.TeamProject"];
23911
+ const base = ctx.org.url;
23912
+ return project ? `${base}/${encodeURIComponent(project)}/_workitems/edit/${ctx.workItemId}` : `${base}/_workitems/edit/${ctx.workItemId}`;
23913
+ }
23914
+ var RECEIPT_NAMESPACE = "integration:azure-devops:deliveries";
23915
+ var RECEIPT_TTL_MS = 7 * 24 * 60 * 60 * 1000;
23916
+ var inFlight = new Map;
23917
+ function withReceipt(key, fn) {
23918
+ const pending = inFlight.get(key);
23919
+ if (pending)
23920
+ return pending.then(() => ({ created: false }));
23921
+ const attempt = (async () => {
23922
+ if (await getKv(RECEIPT_NAMESPACE, key) || await hasTrackerDelivery(PROVIDER, key)) {
23923
+ return { created: false };
23924
+ }
23925
+ const result = await fn();
23926
+ await upsertKv({
23927
+ namespace: RECEIPT_NAMESPACE,
23928
+ key,
23929
+ value: { handledAt: new Date().toISOString() },
23930
+ valueType: "json",
23931
+ expiresAt: Date.now() + RECEIPT_TTL_MS
23932
+ });
23933
+ return result;
23934
+ })().finally(() => {
23935
+ inFlight.delete(key);
23936
+ });
23937
+ inFlight.set(key, attempt);
23938
+ return attempt;
23939
+ }
23940
+ var workItemLocks = new Map;
23941
+ async function withWorkItemLock(key, fn) {
23942
+ const run = (workItemLocks.get(key) ?? Promise.resolve()).then(fn);
23943
+ const tail = run.catch(() => {});
23944
+ workItemLocks.set(key, tail);
23945
+ try {
23946
+ return await run;
23947
+ } finally {
23948
+ if (workItemLocks.get(key) === tail)
23949
+ workItemLocks.delete(key);
23950
+ }
23951
+ }
23952
+ async function handleDelivery(org, eventId, workItemId, fn, extraReceiptKey) {
23953
+ const locked = () => withWorkItemLock(trackerKey(org, workItemId), fn);
23954
+ return await withReceipt(eventId, () => extraReceiptKey ? withReceipt(extraReceiptKey, locked) : locked());
23955
+ }
23956
+ var TRIGGER_LABEL = {
23957
+ assigned: "work item assigned to the bot",
23958
+ mentioned_description: "bot mentioned in the description",
23959
+ mentioned_comment: "bot mentioned in a comment",
23960
+ restored: "work item restored"
23961
+ };
23962
+ async function createWorkItemTask(ctx, trigger, opts) {
23963
+ const { fields } = ctx;
23964
+ const description = htmlToText(fields["System.Description"]).slice(0, DESCRIPTION_LIMIT);
23965
+ const common = {
23966
+ work_item_id: ctx.workItemId,
23967
+ work_item_type: fields["System.WorkItemType"] ?? "Work item",
23968
+ title: fields["System.Title"] ?? "(no title)",
23969
+ state: fields["System.State"] ?? "unknown",
23970
+ project: fields["System.TeamProject"] ?? "unknown",
23971
+ work_item_url: workItemUrl(ctx),
23972
+ username: ctx.actor ? await renderAzureDevOpsIdentity(ctx.actor) : "UNKNOWN"
23973
+ };
23974
+ const templateName = opts.followup ? "azure-devops.work_item.followup" : trigger === "mentioned_comment" ? "azure-devops.work_item.commented" : "azure-devops.work_item.assigned";
23975
+ const variables = templateName === "azure-devops.work_item.followup" ? { ...common, trigger: TRIGGER_LABEL[trigger], user_message: opts.commentText ?? "" } : templateName === "azure-devops.work_item.commented" ? {
23976
+ ...common,
23977
+ context: opts.commentText ?? "",
23978
+ existing_task_note: opts.existingTaskId ? `
23979
+
23980
+ _Note: There's an active task (${opts.existingTaskId}) for this work item._` : ""
23981
+ } : {
23982
+ ...common,
23983
+ trigger: TRIGGER_LABEL[trigger],
23984
+ description_section: description ? `Description:
23985
+ ${description}
23986
+
23987
+ ` : ""
23988
+ };
23989
+ const result = resolveTemplate(templateName, variables);
23990
+ if (result.skipped)
23991
+ return null;
23992
+ const lead = await findLeadAgent2();
23993
+ const task = await createTaskWithSiblingAwareness(result.text, {
23994
+ agentId: lead?.id ?? null,
23995
+ routingReason: lead ? "skill" : undefined,
23996
+ routingSource: lead ? "engine_default" : undefined,
23997
+ source: "azure-devops",
23998
+ taskType: "azure-devops-work-item",
23999
+ requestedByUserId: opts.requestedByUserId,
24000
+ parentTaskId: opts.parentTaskId,
24001
+ contextKey: azureDevOpsWorkItemContextKey({
24002
+ organization: organizationOf(ctx.org.url),
24003
+ workItemId: ctx.workItemId
24004
+ })
24005
+ }, { origin: "webhook" });
24006
+ return task.id;
24007
+ }
24008
+ async function authorizeActor(ctx, trigger) {
24009
+ const userId = ctx.actor ? await authorizeAzureDevOpsActor(ctx.actor, "work_item", `${trigger} #${ctx.workItemId}`) : null;
24010
+ if (!userId) {
24011
+ console.warn(`[AzureDevOps] Ignoring ${TRIGGER_LABEL[trigger]} on work item #${ctx.workItemId}: actor is not a known swarm user`);
24012
+ }
24013
+ return userId;
24014
+ }
24015
+ async function routeToTask(ctx, trigger, commentText) {
24016
+ const requestedByUserId = await authorizeActor(ctx, trigger);
24017
+ if (!requestedByUserId)
24018
+ return { created: false };
24019
+ const externalId = trackerKey(ctx.org, ctx.workItemId);
24020
+ const claim = await createTrackerSyncIfAbsent({
24021
+ provider: PROVIDER,
24022
+ entityType: "task",
24023
+ providerEntityType: "WorkItem",
24024
+ swarmId: `pending:${PROVIDER}:${externalId}`,
24025
+ externalId,
24026
+ externalIdentifier: `${ctx.fields["System.TeamProject"] ?? "unknown"}#${ctx.workItemId}`,
24027
+ externalUrl: workItemUrl(ctx),
24028
+ lastSyncOrigin: "external",
24029
+ syncDirection: "inbound"
24030
+ });
24031
+ const mentioned = trigger === "mentioned_comment" || trigger === "mentioned_description";
24032
+ if (claim.inserted) {
24033
+ let taskId2 = null;
24034
+ try {
24035
+ taskId2 = await createWorkItemTask(ctx, trigger, {
24036
+ followup: false,
24037
+ requestedByUserId,
24038
+ commentText
24039
+ });
24040
+ if (taskId2) {
24041
+ await updateTrackerSyncSwarmId(claim.sync.id, taskId2);
24042
+ await markTrackerDelivery(PROVIDER, "task", externalId, ctx.eventId);
24043
+ }
24044
+ } finally {
24045
+ if (!taskId2)
24046
+ await deleteTrackerSync(claim.sync.id);
24047
+ }
24048
+ return taskId2 ? { created: true, taskId: taskId2 } : { created: false };
24049
+ }
24050
+ const prior = claim.sync.swarmId && !claim.sync.swarmId.startsWith("pending:") ? await getTaskById(claim.sync.swarmId) : null;
24051
+ if (prior && !isTerminalTaskStatus(prior.status)) {
24052
+ if (!mentioned) {
24053
+ console.log(`[AzureDevOps] Work item #${ctx.workItemId} re-triggered but task ${prior.id} is ${prior.status}, ignoring`);
24054
+ return { created: false };
24055
+ }
24056
+ const taskId2 = await createWorkItemTask(ctx, trigger, {
24057
+ followup: false,
24058
+ requestedByUserId,
24059
+ commentText,
24060
+ parentTaskId: prior.id,
24061
+ existingTaskId: prior.id
24062
+ });
24063
+ if (taskId2)
24064
+ await markTrackerDelivery(PROVIDER, "task", externalId, ctx.eventId);
24065
+ return taskId2 ? { created: true, taskId: taskId2 } : { created: false };
24066
+ }
24067
+ const taskId = await createWorkItemTask(ctx, trigger, {
24068
+ followup: true,
24069
+ requestedByUserId,
24070
+ commentText
24071
+ });
24072
+ if (!taskId)
24073
+ return { created: false };
24074
+ await updateTrackerSyncSwarmId(claim.sync.id, taskId);
24075
+ await markTrackerDelivery(PROVIDER, "task", externalId, ctx.eventId);
24076
+ return { created: true, taskId };
24077
+ }
24078
+ async function triggerFromFields(fields, bot) {
24079
+ if (isBotString(fields["System.AssignedTo"], bot))
24080
+ return "assigned";
24081
+ return inspectMention(fields["System.Description"], bot).mentioned ? "mentioned_description" : null;
24082
+ }
24083
+ async function handleWorkItemCreated(event) {
24084
+ const item = workItemOf(event);
24085
+ if (!item) {
24086
+ warnMalformed(event);
24087
+ return { created: false };
24088
+ }
24089
+ const org = orgFor(event);
24090
+ if (!org)
24091
+ return dropUntrustedOrg(event.eventType);
24092
+ return await handleDelivery(org, event.id, item.id, async () => {
24093
+ const bot = await resolveBot(org.url);
24094
+ const actor = parseIdentityString(item.fields["System.ChangedBy"]);
24095
+ if (isBotIdentity(actor, bot))
24096
+ return { created: false };
24097
+ const trigger = await triggerFromFields(item.fields, bot);
24098
+ if (!trigger)
24099
+ return { created: false };
24100
+ return await routeToTask({
24101
+ eventId: event.id,
24102
+ eventType: event.eventType,
24103
+ workItemId: item.id,
24104
+ fields: item.fields,
24105
+ org,
24106
+ actor
24107
+ }, trigger);
24108
+ });
24109
+ }
24110
+ async function handleWorkItemUpdated(event) {
24111
+ const update = updatedPayloadOf(event);
24112
+ if (!update) {
24113
+ warnMalformed(event);
24114
+ return { created: false };
24115
+ }
24116
+ const change = update.fields?.["System.AssignedTo"];
24117
+ if (!change)
24118
+ return { created: false };
24119
+ const org = orgFor(event);
24120
+ if (!org)
24121
+ return dropUntrustedOrg(event.eventType);
24122
+ return await handleDelivery(org, event.id, update.workItemId, async () => {
24123
+ const bot = await resolveBot(org.url);
24124
+ if (!isBotString(change.newValue, bot) || isBotString(change.oldValue, bot)) {
24125
+ return { created: false };
24126
+ }
24127
+ if (isBotIdentity(update.revisedBy ?? null, bot))
24128
+ return { created: false };
24129
+ return await routeToTask({
24130
+ eventId: event.id,
24131
+ eventType: event.eventType,
24132
+ workItemId: update.workItemId,
24133
+ fields: update.revision.fields,
24134
+ org,
24135
+ actor: update.revisedBy ?? null
24136
+ }, "assigned");
24137
+ });
24138
+ }
24139
+ async function handleWorkItemCommented(event) {
24140
+ const item = workItemOf(event);
24141
+ if (!item) {
24142
+ warnMalformed(event);
24143
+ return { created: false };
24144
+ }
24145
+ const ref = item.commentVersionRef;
24146
+ if (ref && ref.version > 1)
24147
+ return { created: false };
24148
+ const org = orgFor(event);
24149
+ if (!org)
24150
+ return dropUntrustedOrg(event.eventType);
24151
+ const commentKey = ref ? `comment:${trackerKey(org, item.id)}:${ref.commentId}` : undefined;
24152
+ return await handleDelivery(org, event.id, item.id, async () => {
24153
+ const bot = await resolveBot(org.url);
24154
+ const actor = parseIdentityString(item.fields["System.ChangedBy"]);
24155
+ if (isBotIdentity(actor, bot))
24156
+ return { created: false };
24157
+ const { mentioned, text } = inspectMention(item.fields["System.History"], bot);
24158
+ if (!mentioned)
24159
+ return { created: false };
24160
+ return await routeToTask({
24161
+ eventId: event.id,
24162
+ eventType: event.eventType,
24163
+ workItemId: item.id,
24164
+ fields: item.fields,
24165
+ org,
24166
+ actor
24167
+ }, "mentioned_comment", text);
24168
+ }, commentKey);
24169
+ }
24170
+ async function handleWorkItemDeleted(event) {
24171
+ const item = workItemOf(event);
24172
+ if (!item) {
24173
+ warnMalformed(event);
24174
+ return { created: false };
24175
+ }
24176
+ const org = orgFor(event);
24177
+ if (!org)
24178
+ return dropUntrustedOrg(event.eventType);
24179
+ return await handleDelivery(org, event.id, item.id, async () => {
24180
+ const externalId = trackerKey(org, item.id);
24181
+ const sync = await getTrackerSyncByExternalId(PROVIDER, "task", externalId);
24182
+ if (!sync)
24183
+ return { created: false };
24184
+ const task = sync.swarmId && !sync.swarmId.startsWith("pending:") ? await getTaskById(sync.swarmId) : null;
24185
+ if (task && !isTerminalTaskStatus(task.status)) {
24186
+ await cancelTask(task.id, DELETED_REASON);
24187
+ console.log(`[AzureDevOps] Cancelled task ${task.id} (work item #${item.id} deleted)`);
24188
+ }
24189
+ await markTrackerDelivery(PROVIDER, "task", externalId, event.id);
24190
+ return { created: false };
24191
+ });
24192
+ }
24193
+ async function handleWorkItemRestored(event) {
24194
+ const item = workItemOf(event);
24195
+ if (!item) {
24196
+ warnMalformed(event);
24197
+ return { created: false };
24198
+ }
24199
+ const org = orgFor(event);
24200
+ if (!org)
24201
+ return dropUntrustedOrg(event.eventType);
24202
+ return await handleDelivery(org, event.id, item.id, async () => {
24203
+ const bot = await resolveBot(org.url);
24204
+ const actor = parseIdentityString(item.fields["System.ChangedBy"]);
24205
+ const ctx = {
24206
+ eventId: event.id,
24207
+ eventType: event.eventType,
24208
+ workItemId: item.id,
24209
+ fields: item.fields,
24210
+ org,
24211
+ actor
24212
+ };
24213
+ const externalId = trackerKey(org, item.id);
24214
+ const sync = await getTrackerSyncByExternalId(PROVIDER, "task", externalId);
24215
+ if (!sync) {
24216
+ if (isBotIdentity(actor, bot))
24217
+ return { created: false };
24218
+ const trigger = await triggerFromFields(item.fields, bot);
24219
+ return trigger ? await routeToTask(ctx, trigger) : { created: false };
24220
+ }
24221
+ const task = sync.swarmId && !sync.swarmId.startsWith("pending:") ? await getTaskById(sync.swarmId) : null;
24222
+ const cancelledByDelete = task?.status === "cancelled" && task.failureReason === DELETED_REASON;
24223
+ if (!cancelledByDelete || !isBotString(item.fields["System.AssignedTo"], bot)) {
24224
+ await markTrackerDelivery(PROVIDER, "task", externalId, event.id);
24225
+ return { created: false };
24226
+ }
24227
+ const requestedByUserId = await authorizeActor(ctx, "restored");
24228
+ if (!requestedByUserId)
24229
+ return { created: false };
24230
+ const taskId = await createWorkItemTask(ctx, "restored", { followup: true, requestedByUserId });
24231
+ if (!taskId)
24232
+ return { created: false };
24233
+ await updateTrackerSyncSwarmId(sync.id, taskId);
24234
+ await markTrackerDelivery(PROVIDER, "task", externalId, event.id);
24235
+ return { created: true, taskId };
24236
+ });
24237
+ }
23472
24238
  // src/http/core.ts
23473
24239
  init_db3();
23474
24240
 
@@ -25858,6 +26624,7 @@ async function handlePipeline(event) {
25858
26624
  return { created: true, taskId: task.id };
25859
26625
  }
25860
26626
  // src/jira/adf.ts
26627
+ init_node_env();
25861
26628
  function isNode(value) {
25862
26629
  return !!value && typeof value === "object";
25863
26630
  }
@@ -25924,7 +26691,7 @@ function extractText(adf) {
25924
26691
  return;
25925
26692
  }
25926
26693
  default: {
25927
- if (type) {
26694
+ if (getNodeEnv() !== "production" && type) {
25928
26695
  console.log(`[jira.adf] unknown node type: ${type}`);
25929
26696
  }
25930
26697
  for (const child of asNodeArray(node.content))
@@ -25958,148 +26725,6 @@ init_oauth();
25958
26725
  init_constants();
25959
26726
  init_env_flag();
25960
26727
 
25961
- // src/be/db-queries/tracker.ts
25962
- init_date_utils();
25963
- init_db3();
25964
- function normalizeTrackerSync(row) {
25965
- return {
25966
- ...row,
25967
- lastSyncedAt: normalizeDateRequired(row.lastSyncedAt),
25968
- createdAt: normalizeDateRequired(row.createdAt)
25969
- };
25970
- }
25971
- function normalizeTrackerAgentMapping(row) {
25972
- return {
25973
- ...row,
25974
- createdAt: normalizeDateRequired(row.createdAt)
25975
- };
25976
- }
25977
- async function getTrackerSync(provider, entityType, swarmId) {
25978
- const row = await getDbClient().get("SELECT * FROM tracker_sync WHERE provider = ? AND entityType = ? AND swarmId = ?", [provider, entityType, swarmId]);
25979
- return row ? normalizeTrackerSync(row) : null;
25980
- }
25981
- async function getTrackerSyncByExternalId(provider, entityType, externalId) {
25982
- const row = await getDbClient().get("SELECT * FROM tracker_sync WHERE provider = ? AND entityType = ? AND externalId = ?", [provider, entityType, externalId]);
25983
- return row ? normalizeTrackerSync(row) : null;
25984
- }
25985
- async function createTrackerSyncIfAbsent(data) {
25986
- const insertResult = await getDbClient().get(`INSERT INTO tracker_sync (provider, entityType, providerEntityType, swarmId, externalId, externalIdentifier, externalUrl, lastSyncOrigin, lastDeliveryId, syncDirection)
25987
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
25988
- ON CONFLICT (provider, entityType, externalId) DO NOTHING
25989
- RETURNING *`, [
25990
- data.provider,
25991
- data.entityType,
25992
- data.providerEntityType ?? null,
25993
- data.swarmId,
25994
- data.externalId,
25995
- data.externalIdentifier ?? null,
25996
- data.externalUrl ?? null,
25997
- data.lastSyncOrigin ?? null,
25998
- data.lastDeliveryId ?? null,
25999
- data.syncDirection ?? "inbound"
26000
- ]);
26001
- if (insertResult) {
26002
- return { inserted: true, sync: normalizeTrackerSync(insertResult) };
26003
- }
26004
- const existing = await getTrackerSyncByExternalId(data.provider, data.entityType, data.externalId);
26005
- if (!existing) {
26006
- throw new Error(`[tracker] createTrackerSyncIfAbsent: ON CONFLICT fired but no existing row found for (${data.provider}, ${data.entityType}, ${data.externalId})`);
26007
- }
26008
- return { inserted: false, sync: existing };
26009
- }
26010
- async function updateTrackerSyncSwarmId(id, swarmId) {
26011
- await getDbClient().run("UPDATE tracker_sync SET swarmId = ? WHERE id = ?", [swarmId, id]);
26012
- }
26013
- async function repointTrackerSyncBySwarmId(oldSwarmId, newSwarmId) {
26014
- const result = await getDbClient().run("UPDATE tracker_sync SET swarmId = ? WHERE swarmId = ?", [
26015
- newSwarmId,
26016
- oldSwarmId
26017
- ]);
26018
- return Number(result.changes ?? 0);
26019
- }
26020
- async function createTrackerSync(data) {
26021
- const result = await getDbClient().get(`INSERT INTO tracker_sync (provider, entityType, providerEntityType, swarmId, externalId, externalIdentifier, externalUrl, lastSyncOrigin, lastDeliveryId, syncDirection)
26022
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
26023
- RETURNING *`, [
26024
- data.provider,
26025
- data.entityType,
26026
- data.providerEntityType ?? null,
26027
- data.swarmId,
26028
- data.externalId,
26029
- data.externalIdentifier ?? null,
26030
- data.externalUrl ?? null,
26031
- data.lastSyncOrigin ?? null,
26032
- data.lastDeliveryId ?? null,
26033
- data.syncDirection ?? "inbound"
26034
- ]);
26035
- return normalizeTrackerSync(result);
26036
- }
26037
- async function updateTrackerSync(id, data) {
26038
- const sets = [];
26039
- const values = [];
26040
- if (data.lastSyncedAt !== undefined) {
26041
- sets.push("lastSyncedAt = ?");
26042
- values.push(data.lastSyncedAt);
26043
- }
26044
- if (data.lastSyncOrigin !== undefined) {
26045
- sets.push("lastSyncOrigin = ?");
26046
- values.push(data.lastSyncOrigin);
26047
- }
26048
- if (data.lastDeliveryId !== undefined) {
26049
- sets.push("lastDeliveryId = ?");
26050
- values.push(data.lastDeliveryId);
26051
- }
26052
- if (data.syncDirection !== undefined) {
26053
- sets.push("syncDirection = ?");
26054
- values.push(data.syncDirection);
26055
- }
26056
- if (data.externalUrl !== undefined) {
26057
- sets.push("externalUrl = ?");
26058
- values.push(data.externalUrl);
26059
- }
26060
- if (data.externalIdentifier !== undefined) {
26061
- sets.push("externalIdentifier = ?");
26062
- values.push(data.externalIdentifier);
26063
- }
26064
- if (sets.length === 0)
26065
- return;
26066
- values.push(id);
26067
- await getDbClient().run(`UPDATE tracker_sync SET ${sets.join(", ")} WHERE id = ?`, values);
26068
- }
26069
- async function deleteTrackerSync(id) {
26070
- await getDbClient().run("DELETE FROM tracker_sync WHERE id = ?", [id]);
26071
- }
26072
- async function hasTrackerDelivery(provider, deliveryId) {
26073
- if (!deliveryId)
26074
- return false;
26075
- const row = await getDbClient().get("SELECT 1 AS hit FROM tracker_sync WHERE provider = ? AND lastDeliveryId = ? LIMIT 1", [provider, deliveryId]);
26076
- return !!row;
26077
- }
26078
- async function markTrackerDelivery(provider, entityType, externalId, deliveryId) {
26079
- await getDbClient().run("UPDATE tracker_sync SET lastDeliveryId = ? WHERE provider = ? AND entityType = ? AND externalId = ?", [deliveryId, provider, entityType, externalId]);
26080
- }
26081
- async function getAllTrackerSyncs(provider, entityType) {
26082
- const conditions = [];
26083
- const values = [];
26084
- if (provider) {
26085
- conditions.push("provider = ?");
26086
- values.push(provider);
26087
- }
26088
- if (entityType) {
26089
- conditions.push("entityType = ?");
26090
- values.push(entityType);
26091
- }
26092
- const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
26093
- const rows = await getDbClient().query(`SELECT * FROM tracker_sync ${where} ORDER BY createdAt DESC`, values);
26094
- return rows.map(normalizeTrackerSync);
26095
- }
26096
- async function createTrackerAgentMapping(data) {
26097
- const result = await getDbClient().get(`INSERT INTO tracker_agent_mapping (provider, agentId, externalUserId, agentName)
26098
- VALUES (?, ?, ?, ?)
26099
- RETURNING *`, [data.provider, data.agentId, data.externalUserId, data.agentName]);
26100
- return normalizeTrackerAgentMapping(result);
26101
- }
26102
-
26103
26728
  // src/jira/outbound.ts
26104
26729
  init_secret_scrubber();
26105
26730
  init_event_bus();
@@ -26411,7 +27036,7 @@ var TTL_MS = 30 * 24 * 60 * 60 * 1000;
26411
27036
  function namespace(kind) {
26412
27037
  return `integration:unmapped:${kind}`;
26413
27038
  }
26414
- async function recordUnmappedIdentity(kind, externalId, meta2) {
27039
+ async function recordUnmappedIdentity2(kind, externalId, meta2) {
26415
27040
  const ns = namespace(kind);
26416
27041
  const now = new Date().toISOString();
26417
27042
  const expiresAt = Date.now() + TTL_MS;
@@ -26462,7 +27087,7 @@ async function resolveJiraActor(accountId, email, name, sampleEventType, sampleC
26462
27087
  }
26463
27088
  return user.id;
26464
27089
  }
26465
- await recordUnmappedIdentity("jira", accountId, { sampleEventType, sampleContext });
27090
+ await recordUnmappedIdentity2("jira", accountId, { sampleEventType, sampleContext });
26466
27091
  return;
26467
27092
  }
26468
27093
  async function renderJiraIdentity(accountId) {
@@ -26826,7 +27451,7 @@ async function notifySlack(text) {
26826
27451
  return;
26827
27452
  }
26828
27453
  try {
26829
- const { getSlackApp: getSlackApp2 } = await import("./app-wmf0m843.js");
27454
+ const { getSlackApp: getSlackApp2 } = await import("./app-km9qnv2f.js");
26830
27455
  const app = getSlackApp2();
26831
27456
  if (!app) {
26832
27457
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -26897,7 +27522,7 @@ async function deleteJiraWebhook(webhookId) {
26897
27522
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
26898
27523
  }
26899
27524
  async function overwriteWebhookIds(next) {
26900
- const { getDbClient: getDbClient2 } = await import("./db-4w7tmt1g.js");
27525
+ const { getDbClient: getDbClient2 } = await import("./db-qfpq4bt7.js");
26901
27526
  await getDbClient2().transaction(async (tx) => {
26902
27527
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
26903
27528
  if (!row) {
@@ -100117,6 +100742,7 @@ init_zod_openapi();
100117
100742
 
100118
100743
  // src/http/route-def.ts
100119
100744
  init_zod();
100745
+ init_node_env();
100120
100746
  init_secret_scrubber();
100121
100747
 
100122
100748
  // src/http/utils.ts
@@ -100514,7 +101140,7 @@ function describeRequestRoute(method, pathSegments, hasQueryString = false, hasT
100514
101140
  const first = pathSegments[0];
100515
101141
  return { spanName: first ? `${m} /${first}` : m };
100516
101142
  }
100517
- var VALIDATE_RESPONSES = true;
101143
+ var VALIDATE_RESPONSES = getNodeEnv() === "test" || getNodeEnv() === "development" || process.env.VALIDATE_HTTP_RESPONSES === "true";
100518
101144
  function route(def) {
100519
101145
  routeRegistry.push(def);
100520
101146
  return {
@@ -100526,7 +101152,9 @@ function route(def) {
100526
101152
  const result = schema.safeParse(data);
100527
101153
  if (!result.success) {
100528
101154
  const detail = `Response schema violation: ${def.method.toUpperCase()} ${def.path} ${code} — ` + result.error.issues.map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`).join("; ");
100529
- if (false) {}
101155
+ if (getNodeEnv() === "test") {
101156
+ throw new Error(detail);
101157
+ }
100530
101158
  console.error(`[route-def] ${scrubSecrets(detail)}`);
100531
101159
  }
100532
101160
  }
@@ -100727,7 +101355,7 @@ async function reloadGlobalConfigsAndIntegrations() {
100727
101355
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
100728
101356
  }
100729
101357
  async function reloadGlobalConfigsAndIntegrationsInner() {
100730
- const { getEmbeddingProvider: getEmbeddingProvider2, resetEmbeddingProvider } = await import("./index-ffqzqgwb.js");
101358
+ const { getEmbeddingProvider: getEmbeddingProvider2, resetEmbeddingProvider } = await import("./index-jd7sejm2.js");
100731
101359
  const wasEmbeddingsConfigured = getEmbeddingProvider2().isConfigured();
100732
101360
  const updated = await loadGlobalConfigsIntoEnv(true);
100733
101361
  await syncTelemetryEnabled("settings").catch((err) => {
@@ -100743,10 +101371,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
100743
101371
  integrations.push("embeddings");
100744
101372
  }
100745
101373
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
100746
- import("./boot-reembed-1de4f4aj.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
101374
+ import("./boot-reembed-swwzdgd7.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
100747
101375
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
100748
101376
  });
100749
- import("./boot-reembed-4ymn9atn.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
101377
+ import("./boot-reembed-16rv9843.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
100750
101378
  console.error("[config-reload] script backfill failed (non-fatal):", err);
100751
101379
  });
100752
101380
  }
@@ -101926,7 +102554,7 @@ function setPreloadedTools(server, names) {
101926
102554
  async function applyPreToolCall(name, args, requestInfo, inputSchema) {
101927
102555
  if (requestInfo.callOrigin !== "mcp")
101928
102556
  return { args };
101929
- const dispatcher = await import("./dispatcher-5sd69y14.js");
102557
+ const dispatcher = await import("./dispatcher-x0x7qfcq.js");
101930
102558
  const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
101931
102559
  validateModify: async (data) => {
101932
102560
  const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
@@ -102968,7 +103596,7 @@ function reconcile(args) {
102968
103596
  });
102969
103597
  });
102970
103598
  }
102971
- var inFlight = new Map;
103599
+ var inFlight2 = new Map;
102972
103600
  function passBase(args) {
102973
103601
  return {
102974
103602
  model: args.model,
@@ -103047,7 +103675,7 @@ async function executePass(args) {
103047
103675
  }
103048
103676
  async function runPass(args) {
103049
103677
  const key = `${args.appId}:${args.model}:${args.sourceName}`;
103050
- if (inFlight.has(key)) {
103678
+ if (inFlight2.has(key)) {
103051
103679
  return scrubObject({
103052
103680
  ...passBase({
103053
103681
  model: args.model,
@@ -103061,12 +103689,12 @@ async function runPass(args) {
103061
103689
  });
103062
103690
  }
103063
103691
  const pass = executePass(args);
103064
- inFlight.set(key, pass);
103692
+ inFlight2.set(key, pass);
103065
103693
  try {
103066
103694
  return await pass;
103067
103695
  } finally {
103068
- if (inFlight.get(key) === pass)
103069
- inFlight.delete(key);
103696
+ if (inFlight2.get(key) === pass)
103697
+ inFlight2.delete(key);
103070
103698
  }
103071
103699
  }
103072
103700
  function noPairIssue(input) {
@@ -109349,6 +109977,17 @@ var registerDeferTaskTool = (server) => {
109349
109977
  const { tz: requesterTz, isFallback: isFallbackTz } = await resolveRequesterTimezone(task.requestedByUserId);
109350
109978
  try {
109351
109979
  const committed = await getDbClient().transaction(async () => {
109980
+ if (watchedTaskIds.length) {
109981
+ const existing = await getDbClient().get(`SELECT w.scheduleId, s.parentTaskId FROM deferred_task_waits w
109982
+ JOIN scheduled_tasks s ON s.id = w.scheduleId
109983
+ JOIN deferred_task_wait_members m ON m.scheduleId = w.scheduleId
109984
+ WHERE w.status = 'pending' AND s.enabled = 1 AND s.targetAgentId = ?
109985
+ AND m.taskId IN (${watchedTaskIds.map(() => "?").join(", ")})
109986
+ LIMIT 1`, [agent.id, ...watchedTaskIds]);
109987
+ if (existing) {
109988
+ throw new DeferAbortedError(`Pending watcher ${existing.scheduleId} (task ${existing.parentTaskId}) already watches these tasks for this agent.`);
109989
+ }
109990
+ }
109352
109991
  const watchedAgentNames = [];
109353
109992
  for (const watchedId of watchedTaskIds) {
109354
109993
  if (watchedId === taskId)
@@ -110501,7 +111140,8 @@ init_db3();
110501
111140
  var RESERVED_FAMILIES = new Map([
110502
111141
  ["apps", "namespace is reserved for swarm apps; use the app row endpoints"],
110503
111142
  ["comb", "namespace is reserved for Comb; use POST /api/comb/review-batches"],
110504
- ["worker", "namespace is reserved for worker nudges"]
111143
+ ["worker", "namespace is reserved for worker nudges"],
111144
+ ["slack-external-alert", "namespace is reserved for Slack external channel alerts"]
110505
111145
  ]);
110506
111146
  function reservedNamespaceError(namespace2) {
110507
111147
  return RESERVED_FAMILIES.get(namespace2.split(":", 1)[0] ?? "") ?? null;
@@ -124910,57 +125550,6 @@ init_zod();
124910
125550
  init_db3();
124911
125551
  init_rbac();
124912
125552
 
124913
- // src/slack/channel-join.ts
124914
- var logger = console;
124915
- function slackErrorData(error) {
124916
- if (!(error instanceof Error))
124917
- return;
124918
- return error.data;
124919
- }
124920
- function slackCode(error) {
124921
- const d = slackErrorData(error);
124922
- return typeof d?.error === "string" ? d.error : undefined;
124923
- }
124924
- function slackMissingScopeMessage(error) {
124925
- const data = slackErrorData(error);
124926
- if (data?.error !== "missing_scope" || typeof data.needed !== "string")
124927
- return;
124928
- const needed = data.needed.trim();
124929
- if (!needed)
124930
- return;
124931
- return `Slack requires the \`${needed}\` scope. Add it to slack-manifest.json, apply the updated manifest to the Slack app, then reinstall the app to the workspace for the change to take effect.`;
124932
- }
124933
- async function isKnownExternalChannel(client, channelId) {
124934
- try {
124935
- const resp = await client.conversations.info({ channel: channelId });
124936
- const ch = resp.channel ?? {};
124937
- return ch.is_ext_shared === true || ch.is_pending_ext_shared === true;
124938
- } catch (error) {
124939
- logger.warn(`[Slack] conversations.info failed for ${channelId}; attempting join fallback:`, error);
124940
- return false;
124941
- }
124942
- }
124943
- async function withAutoJoin(client, channelId, fn) {
124944
- try {
124945
- return await fn();
124946
- } catch (error) {
124947
- if (slackCode(error) !== "not_in_channel")
124948
- throw error;
124949
- if (await isKnownExternalChannel(client, channelId)) {
124950
- throw new Error(`Cannot auto-join external channel ${channelId} — invite the bot with /invite @<bot-name> first.`);
124951
- }
124952
- try {
124953
- await client.conversations.join({ channel: channelId });
124954
- } catch (joinError) {
124955
- if (slackCode(joinError) === "method_not_supported_for_channel_type") {
124956
- throw new Error(`Cannot access private channel ${channelId} — invite the bot with /invite @<bot-name> first.`);
124957
- }
124958
- throw joinError;
124959
- }
124960
- return await fn();
124961
- }
124962
- }
124963
-
124964
125553
  // src/slack/channel-lifecycle.ts
124965
125554
  function normalizeChannelName(name) {
124966
125555
  const normalized = name.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^[-_]+|[-_]+$/g, "").slice(0, 80).replace(/[-_]+$/g, "");
@@ -126024,6 +126613,10 @@ var registerSlackPostTool = (server) => {
126024
126613
  if (!app) {
126025
126614
  return toolErr("Slack not configured.");
126026
126615
  }
126616
+ const blockReason = await getChannelBlockReason(app.client, channelId);
126617
+ if (blockReason) {
126618
+ return toolErr(externalChannelToolError(channelId, blockReason));
126619
+ }
126027
126620
  try {
126028
126621
  const slackMessage = markdownToSlack(message);
126029
126622
  const sourceTask = requestInfo.sourceTaskId ? await getTaskById(requestInfo.sourceTaskId) : undefined;
@@ -126190,6 +126783,12 @@ var registerSlackReadTool = (server) => {
126190
126783
  if (!app) {
126191
126784
  return toolErr("Slack not configured.", { data: { messages: [] } });
126192
126785
  }
126786
+ const blockReason = await getChannelBlockReason(app.client, slackChannelId);
126787
+ if (blockReason) {
126788
+ return toolErr(externalChannelToolError(slackChannelId, blockReason), {
126789
+ data: { messages: [] }
126790
+ });
126791
+ }
126193
126792
  try {
126194
126793
  const client = app.client;
126195
126794
  let rawMessages = [];
@@ -126382,6 +126981,10 @@ var registerSlackReplyTool = (server) => {
126382
126981
  if (!app) {
126383
126982
  return toolErr("Slack not configured.");
126384
126983
  }
126984
+ const blockReason = await getChannelBlockReason(app.client, slackChannelId);
126985
+ if (blockReason) {
126986
+ return toolErr(externalChannelToolError(slackChannelId, blockReason));
126987
+ }
126385
126988
  try {
126386
126989
  const citations = taskId ? await getTaskCitations(taskId) : [];
126387
126990
  const slackMessage = renderTaskCitations(markdownToSlack(message), citations, "slack", false);
@@ -126499,6 +127102,10 @@ var registerSlackStartThreadTool = (server) => {
126499
127102
  if (!app) {
126500
127103
  return toolErr("Slack not configured.");
126501
127104
  }
127105
+ const blockReason = await getChannelBlockReason(app.client, channelId);
127106
+ if (blockReason) {
127107
+ return toolErr(externalChannelToolError(channelId, blockReason));
127108
+ }
126502
127109
  try {
126503
127110
  const slackMessage = markdownToSlack(message);
126504
127111
  const messageBlocks = blocks ?? [
@@ -126586,6 +127193,10 @@ var registerSlackUpdateTool = (server) => {
126586
127193
  if (!app) {
126587
127194
  return toolErr("Slack not configured.");
126588
127195
  }
127196
+ const blockReason = await getChannelBlockReason(app.client, channelId);
127197
+ if (blockReason) {
127198
+ return toolErr(externalChannelToolError(channelId, blockReason));
127199
+ }
126589
127200
  try {
126590
127201
  const ts = parseSlackTs(messageTs);
126591
127202
  const slackMessage = markdownToSlack(message);
@@ -126758,6 +127369,10 @@ var registerSlackUploadFileTool = (server) => {
126758
127369
  if (!app) {
126759
127370
  return toolErr("Slack not configured.");
126760
127371
  }
127372
+ const blockReason = await getChannelBlockReason(app.client, slackChannelId);
127373
+ if (blockReason) {
127374
+ return toolErr(externalChannelToolError(slackChannelId, blockReason));
127375
+ }
126761
127376
  if (!filePath && !content) {
126762
127377
  return toolErr("Must provide either filePath or content (base64).");
126763
127378
  }
@@ -132592,7 +133207,7 @@ class NotifyExecutor extends BaseExecutor {
132592
133207
  }
132593
133208
  }
132594
133209
  case "slack": {
132595
- const { getSlackApp: getSlackApp2 } = await import("./app-wmf0m843.js");
133210
+ const { getSlackApp: getSlackApp2 } = await import("./app-km9qnv2f.js");
132596
133211
  const app = getSlackApp2();
132597
133212
  if (!app) {
132598
133213
  return {
@@ -133401,4 +134016,4 @@ async function initWorkflows() {
133401
134016
  logOpenWebhookTriggers();
133402
134017
  }
133403
134018
 
133404
- export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, handleWebhookTrigger, logOpenWebhookTriggers, handleEventTrigger, handleScheduleTrigger, verifyHmacSignature, WebhookError, snapshotWorkflow, snapshotAndUpdateWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry, initWorkflows, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow, parseSkillContent, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, duplicateGuardedQueryKey, warnIfCorsAllowsAnyOrigin, isOriginAllowedForCredentials, allowedCredentialRedirect, setCorsHeaders, parseQueryParams, getPathSegments, wireHttpSpanLifecycle, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, writeUnhandledError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, runtimeInstanceHeader, describeRequestRoute, route, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError, isRegistered, isExtensionAgentId, getExtensionBridgeToken, resolveBridgeCallOrigin, extensionIdForAgent, runContext, registerLoaded, unregister, listRegistered, dispatchPre, dispatchPost, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, repointTrackerSyncBySwarmId, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, parseCookieHeader, extractAndVerifyCookie, issuePageSessionCookie, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, MemoryKeyError, refreshLinks, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, indexMemoryContent, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };
134019
+ export { DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, isJSONRPCRequest, isJSONRPCResultResponse, isJSONRPCErrorResponse, JSONRPCMessageSchema, isInitializeRequest, McpServer, isGitHubEnabled, initGitHub, verifyWebhookSignature, isAgentMailEnabled, initAgentMail, verifyAgentMailWebhook, resolveIdentity, renderIdentity, createAdditiveBuffer, listHarnessModelSupport, recordHarnessModelSupport, agentRanModel, getAgentHarnessCliVersion, setAgentHarnessCliVersion, sanitizeModelTierOverrides, parseModelTierOverridesHeader, setAgentModelTierOverrides, previewModelTiers, recordClaimModelResolution, harnessModelErrorFor, poolTaskRunsOnHarness, explicitModelError, explicitModelErrorForAgent, referencedBundlePaths, skillDirs, TaskCreationBlockedError, recordUnmappedIdentity2 as recordUnmappedIdentity, MAX_TASK_ATTACHMENT_BYTES, recordTaskAttachmentUpload, buildEffectiveText, bufferedFileFailures, fetchSlackFiles, createSlackTaskWithFiles, notifySlackFileFailures, isRuntimePoolWakeable, isAgentReachable, hasOtherUserMention, broadcastMatches, routeMessage, extractTaskFromMessage, extractSlackMessageText, recoverIncompleteRuns, startRetryPoller, stopRetryPoller, validateTemplateVariables, instantiateTemplate, handleWebhookTrigger, logOpenWebhookTriggers, handleEventTrigger, handleScheduleTrigger, verifyHmacSignature, WebhookError, snapshotWorkflow, snapshotAndUpdateWorkflow, startWaitPoller, stopWaitPoller, RawLlmConfigSchema, RawLlmOutputSchema, executeRawLlm, getExecutorRegistry, initWorkflows, dispatchScheduleTarget, calculateNextRun, startScheduler, stopScheduler, runScheduleNow, parseSkillContent, ExtensionAssetConflictError, ExtensionOwnershipError, getExtensionFiles, getExtensionById, getExtensionByName, listExtensions, listExtensionVersions, updateExtensionMeta, listExtensionRuns, SDK_ALLOWLIST, mcpToolNameForSdkMethod, mcpOverflowAuthError, hasKvViewArgs, resolveKvView, toolErr, createToolRegistrar, duplicateGuardedQueryKey, warnIfCorsAllowsAnyOrigin, isOriginAllowedForCredentials, allowedCredentialRedirect, setCorsHeaders, parseQueryParams, getPathSegments, wireHttpSpanLifecycle, safeRequestUrlForLog, agentWithCapacity, parseBody, BODY_TOO_LARGE, enforceContentLengthCap, json, jsonError, writeUnhandledError, triggerSchemaErrorResponse, deriveApiBaseUrl, httpServerSemconvAttributes, runtimeInstanceHeader, describeRequestRoute, route, handleMcpBridge, Redacted, SCRIPT_SDK_RESPONSE_LIMIT_BYTES, readScriptSdkJsonResponse, ExtensionConfigError, ExtensionLifecycleError, setExtensionLoopbackBaseUrl, enableExtension, disableExtension, activateVersion, ExtensionAssetsInvalidError, installExtensionWithAssets, uninstallExtension, reloadExtension, loadEnabledExtensions, stopExtensionRuntime, ExtensionAbortedError, isRegistered, isExtensionAgentId, getExtensionBridgeToken, resolveBridgeCallOrigin, extensionIdForAgent, runContext, registerLoaded, unregister, listRegistered, dispatchPre, dispatchPost, stripSiblingBlock, createTaskWithSiblingAwareness, isInboxAllowed, isSenderAllowed, handleMessageReceived, isAzureDevOpsEnabled, initAzureDevOps, verifyAzureDevOpsWebhook, repointTrackerSyncBySwarmId, isAzureDevOpsUrl, canonicalAzureDevOpsRepoUrl, parseAzureDevOpsRepoUrl, createdPullRequestOf, commentedPayloadOf, handlePullRequestCreated, handlePullRequestCommented, handleWorkItemCreated, handleWorkItemUpdated, handleWorkItemCommented, handleWorkItemDeleted, handleWorkItemRestored, AGENT_MAX_TASKS_CONFIG_KEY, reconcileAgentMaxTasksPolicy, resetAgentMaxTasksMirror, upsertSwarmConfigWithPolicyMirror, runtimeStaleThresholdMinutes, upsertRuntimeInstance, getRuntimeInstanceById, insertProvisioningRuntime, markRuntimeTerminated, touchRuntimeInstance, countActiveRuntimeInstancesForAgent, listRuntimeInstancesForAgent, setRuntimeCredentialReady, reconcileAgentStatusFromRuntimes, agentsWithLiveRuntime, expireStaleRuntimeInstances, listRuntimeInstancesForPool, enqueueAuditRow, enqueueAdmissionRow, flushAuditBuffer, startAuditWriter, stopAuditWriter, startAuditGc, stopAuditGc, getTelemetryIngestAnchor, initApiTelemetry, syncTelemetryEnabled, handlePullRequest, handleIssue, handleComment, handlePullRequestReview, handleCheckRun, handleCheckSuite, handleWorkflowRun, isGitLabEnabled, initGitLab, verifyGitLabWebhook, handleMergeRequest, handleIssue2 as handleIssue1, handleNote, handlePipeline, getJiraMetadata, updateJiraMetadata, clearJiraMetadata, registerJiraWebhook, deleteJiraWebhook, isJiraEnabled, initJira, handleJiraWebhook, handleAgentSessionEvent, handleIssueUpdate, handleIssueDelete, handleAgentSessionPrompted, isLinearEnabled, initLinear, parseCookieHeader, extractAndVerifyCookie, issuePageSessionCookie, resolveHttpRequestAuth, loadGlobalConfigsIntoEnv, reloadGlobalConfigsAndIntegrations, scheduleIntegrationsReload, handleCore, userCtx, resolveTaskAuditUserId, resolveHttpAuditUserId, resolveHttpFavoriteOwner, handleApps, cancelApprovalRequest, cancelApprovalRequestAndRun, getUserCommsPrefs, getTaskDetailsInputSchema, getTaskDetailsOutputSchema, getTaskDetailsHandler, cancelTaskInputSchema, cancelTaskOutputSchema, cancelTaskHandler, executeReadOnlyQuery, assertSelectOnlyQuery, handleDbQuery, snapshotMetric, AssetKeyAuthorizationError, authorizeAssetKeyWrite, snapshotPage, assertOAuthAppUrlsSafe, assertOAuthEgressUrlSafe, listOAuthPresets, listOAuthPresetIds, getOAuthPreset, hydrateOAuthAppFromPreset, scopedResourceScopeIdSchema, resolveScopedResourceId, dedupeMemoryDocumentIds, recordMemoryAccesses, recordRetrievals, ExplicitSelfDuplicateError, applyRating, shouldPersistAutomaticTaskMemory, REBOOT_RETRY_PIN_TAG, getPinCandidateAgent, resolveLeadOnlyRecoveryAssignment, getResumeGeneration, getNextResumeGeneration, inheritedModelSelection, createWorkerTaskFollowUp, createResumeFollowUp, createRerouteDecisionTask, createPoolStarvationDecisionTask, guardTerminalTaskResultWrite, getTasksInputSchema, getTasksOutputSchema, getTasksHandler, reservedNamespaceError, reservedRoomKeyError, updateMcpServerChecked, updateTouchesStdioExecution, MemoryKeyError, refreshLinks, canReadMemory, getLinksForMemory, expandCandidatesWithGraph, indexMemoryContent, isApiDraining, drainApi, markKapsoMessageRead, sendKapsoReaction, getKapsoConfig, getKapsoNumberMapping, markKapsoMessageSeen, changesAllowMerge, updateSwarmRepoChecked, getCombConfig, resolveRoomNamespace, roomRequestInfo, authorizeRoomNamespace, RoomOperationSchema, removeAwarenessStates, roomTopic, decodeRoomSnapshot, roomView, getRoom, changeRoom, applyRoomUpdate, resetRoom, sweepRooms, closeRooms, removeNamespaceRooms, MEMORY_KEYS_DEFAULT_PREFIX, MEMORY_KEYS_MAX_LIMIT, estimateTokens, posteriorMean, listMemoryKeys, checkChunkIntegrity, getMemoryChunks, getPosteriorsByIds, createEvent, createEventsBatch, getEventCountsFiltered, getEventsFiltered, mergeScheduleTiming, validateRecurringTiming, checkOutputSchemaShape, sendTaskOutputSchema, sendTaskHandler, steerTaskUserInputSchema, steerTaskOutputSchema, steerTaskHandler, canClaim, emitBudgetRefusalSideEffects, workflowModelErrors, patchWorkflowDefinition, resolveScriptsOnlyMode, ALL_CAPABILITIES, hasCapability, getEnabledCapabilities, createServer };