@desplega.ai/agent-swarm 1.130.0 → 1.131.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 (122) hide show
  1. package/README.md +1 -1
  2. package/dist/{actions-73ee723n.js → actions-w53mbns9.js} +7 -7
  3. package/dist/{anthropic-messages-3xgme8my.js → anthropic-messages-rjmd2e7n.js} +5 -5
  4. package/dist/{app-hz5c2xay.js → app-m9gwqsqv.js} +4 -4
  5. package/dist/{assistant-08mr16yp.js → assistant-bp65m6f3.js} +9 -9
  6. package/dist/{azure-openai-responses-xa4sh9f6.js → azure-openai-responses-c0yjmbfd.js} +8 -5
  7. package/dist/{boot-reembed-5bgan3cd.js → boot-reembed-62p0at2k.js} +4 -4
  8. package/dist/{boot-reembed-z7ykyeq8.js → boot-reembed-xmfp6wdh.js} +5 -5
  9. package/dist/{boot-scrub-logs-b2rjk8mv.js → boot-scrub-logs-rr8q2dms.js} +3 -3
  10. package/dist/{claude-adapter-qr0k17km.js → claude-adapter-2y47mrkd.js} +6 -6
  11. package/dist/{cli-s21zzx4b.js → cli-0rcyq6d9.js} +447 -183
  12. package/dist/{cli-brebbsen.js → cli-2q72qz2s.js} +9 -6
  13. package/dist/{cli-e5p3es48.js → cli-3kf51j15.js} +1 -1
  14. package/dist/{cli-vgexpfsr.js → cli-57khth04.js} +6 -3
  15. package/dist/{cli-h3e66g5b.js → cli-5kx36evn.js} +1 -1
  16. package/dist/{cli-n9yxcnvk.js → cli-5n6e5yfn.js} +29 -7
  17. package/dist/{cli-tp519bjz.js → cli-5v4rw6yd.js} +2 -2
  18. package/dist/{cli-dakxgk70.js → cli-5ze9rv97.js} +4 -4
  19. package/dist/{cli-ch7t5v7n.js → cli-6map995v.js} +9 -4
  20. package/dist/{cli-mgerp0vs.js → cli-70xqj0z3.js} +2 -2
  21. package/dist/{cli-7v5dhmc8.js → cli-72q8m8gk.js} +6 -6
  22. package/dist/{cli-yj7z99vp.js → cli-78xwvkhj.js} +2 -2
  23. package/dist/{cli-t5tsq67k.js → cli-9dr5qzc0.js} +39 -4
  24. package/dist/{cli-73bvdyxr.js → cli-a40rnf71.js} +6 -6
  25. package/dist/{cli-s18zzkfp.js → cli-a4jzdpa3.js} +44 -7
  26. package/dist/{cli-w10fkrf1.js → cli-akdvwc9v.js} +354 -115
  27. package/dist/{cli-hntzdchd.js → cli-bqw0mt1n.js} +1 -1
  28. package/dist/{cli-mhr8tq3v.js → cli-cdeg08wx.js} +1 -1
  29. package/dist/{cli-qcsjdppx.js → cli-cvgjwnh1.js} +7 -7
  30. package/dist/{cli-z9q7pb38.js → cli-d2tfkcga.js} +4 -4
  31. package/dist/{cli-r62me33w.js → cli-d3x3x1c9.js} +2 -2
  32. package/dist/{cli-6nh2qxvh.js → cli-darcwax3.js} +1 -1
  33. package/dist/{cli-326083vb.js → cli-e7ckcg4v.js} +12 -12
  34. package/dist/{cli-fs153s3x.js → cli-efxfnq6q.js} +3 -3
  35. package/dist/{cli-xg2eezyv.js → cli-f1am9szv.js} +1 -1
  36. package/dist/{cli-2pa5w9b6.js → cli-fywms69x.js} +1 -1
  37. package/dist/{cli-1mj7yz1r.js → cli-g6b8x1h8.js} +1 -1
  38. package/dist/{cli-epsvdckx.js → cli-gm9cbhbq.js} +20 -10
  39. package/dist/{cli-tfw3c0y1.js → cli-nm5gtp1x.js} +2 -2
  40. package/dist/{cli-q8zwffx0.js → cli-pm6xbh84.js} +128 -35
  41. package/dist/{cli-m8fs5ttq.js → cli-psh3c4va.js} +1 -1
  42. package/dist/{cli-1px8pn1s.js → cli-qv61hp37.js} +2 -2
  43. package/dist/{cli-mf009e0j.js → cli-rzbpmxdr.js} +1 -1
  44. package/dist/{cli-vr2f46zj.js → cli-t1xze5qh.js} +1 -1
  45. package/dist/{cli-qbb2ten8.js → cli-t55yw3a1.js} +2 -2
  46. package/dist/{cli-haanc4qd.js → cli-t76vw5db.js} +22 -22
  47. package/dist/{cli-4n4mdv21.js → cli-xpxde7rm.js} +7 -3
  48. package/dist/{cli-xdrmxvd4.js → cli-yw8vghx2.js} +46 -10
  49. package/dist/cli.js +22 -22
  50. package/dist/{codex-adapter-6pc50x9q.js → codex-adapter-d24q75wk.js} +4 -4
  51. package/dist/{codex-hook-amndawyb.js → codex-hook-hq54t9ft.js} +2 -2
  52. package/dist/{codex-session-runner-tpg8hyj7.js → codex-session-runner-g50vcsex.js} +4 -4
  53. package/dist/{commands-yfpwt11g.js → commands-c3nrc5hg.js} +3 -3
  54. package/dist/{db-jn499nmp.js → db-nt7fg3tw.js} +3 -3
  55. package/dist/{google-generative-ai-txgg2q58.js → google-generative-ai-hysrd8qx.js} +7 -5
  56. package/dist/{google-vertex-t663s1c3.js → google-vertex-p5arrga0.js} +7 -5
  57. package/dist/{handlers-eev4nng0.js → handlers-fkr6swat.js} +9 -9
  58. package/dist/{hook-sn7pj75w.js → hook-77wpvnjc.js} +4 -4
  59. package/dist/{hook-9fkwkf3m.js → hook-g019yehy.js} +5 -5
  60. package/dist/{http-xdbbtmhx.js → http-jewj0syk.js} +202 -79
  61. package/dist/{index-c0qedjh6.js → index-6gm5he8h.js} +9 -9
  62. package/dist/{index-5fdsemf0.js → index-7n2xpbd4.js} +155 -37
  63. package/dist/{index-9vnkprkh.js → index-hfvggd0z.js} +10 -10
  64. package/dist/{index-fnack5vh.js → index-hp1kdbjj.js} +11 -11
  65. package/dist/{keepalive-fc7a2hw9.js → keepalive-j0fjvqfd.js} +5 -5
  66. package/dist/{lead-1fva34y9.js → lead-1n8x30xe.js} +28 -28
  67. package/dist/{maintenance-0rdb12vf.js → maintenance-gvev11sa.js} +5 -5
  68. package/dist/{mistral-conversations-4swenhmf.js → mistral-conversations-81fwav0j.js} +2 -2
  69. package/dist/{oauth-refresh-sweep-f9rptqbt.js → oauth-refresh-sweep-s9ecsvh0.js} +4 -4
  70. package/dist/{onboard-9zn0fx2m.js → onboard-pvm5b38w.js} +2 -2
  71. package/dist/{openai-codex-responses-xetseqvt.js → openai-codex-responses-5g27pd6f.js} +43 -23
  72. package/dist/{openai-completions-5r2g5axa.js → openai-completions-3vkmfz2a.js} +55 -11
  73. package/dist/{openai-responses-ce67hd23.js → openai-responses-dg4t7j7a.js} +8 -5
  74. package/dist/{openrouter-images-pzfp22jb.js → openrouter-images-g3gm8931.js} +1 -1
  75. package/dist/{otel-impl-thnttmbn.js → otel-impl-p6jvgd9c.js} +1 -1
  76. package/dist/{pi-mono-adapter-bpfrn6d7.js → pi-mono-adapter-t091s27g.js} +17114 -7514
  77. package/dist/{pricing-refresh-n0ve0kh6.js → pricing-refresh-k49rcyed.js} +5 -5
  78. package/dist/{rbac-roles-bbwb4wrm.js → rbac-roles-30pspvy7.js} +5 -5
  79. package/dist/{rbac-roles-w45bhahg.js → rbac-roles-cr80g96t.js} +4 -4
  80. package/dist/{render-v2-d675cp9r.js → render-v2-xm457ng1.js} +4 -4
  81. package/dist/{seed-pricing-47q77nw4.js → seed-pricing-yhpv35fr.js} +4 -4
  82. package/dist/{setup-3vnv2m43.js → setup-nytnmwwr.js} +2 -2
  83. package/dist/{worker-7shsr8hk.js → worker-msytr2cw.js} +28 -28
  84. package/openapi.json +342 -10
  85. package/package.json +6 -6
  86. package/src/apps/store.ts +13 -4
  87. package/src/assets/key.ts +8 -1
  88. package/src/be/asset-key-audit.ts +3 -1
  89. package/src/be/db-queries/mcp-oauth.ts +26 -0
  90. package/src/be/db.ts +42 -1
  91. package/src/be/migrations/129_asset_keys_apps_scripts.sql +161 -0
  92. package/src/be/scripts/db.ts +5 -2
  93. package/src/be/seed-skills/index.ts +7 -0
  94. package/src/http/assets.ts +120 -29
  95. package/src/http/mcp-oauth.ts +69 -1
  96. package/src/http/users.ts +45 -0
  97. package/src/oauth/ensure-mcp-token.ts +7 -1
  98. package/src/oauth/mcp-wrapper.ts +247 -24
  99. package/src/providers/pi-mono-adapter.ts +1 -1
  100. package/src/tests/asset-key-api.test.ts +48 -2
  101. package/src/tests/asset-key-invariants.test.ts +92 -0
  102. package/src/tests/asset-key-migration.test.ts +174 -8
  103. package/src/tests/asset-key-normalization.test.ts +2 -0
  104. package/src/tests/mcp-oauth-dcr-reuse.test.ts +95 -0
  105. package/src/tests/mcp-oauth-ensure-token.test.ts +23 -0
  106. package/src/tests/mcp-oauth-manual-client.test.ts +135 -2
  107. package/src/tests/mcp-oauth-wrapper.test.ts +380 -0
  108. package/src/tests/rbac-admission-e2e.test.ts +68 -0
  109. package/src/tests/script-connections.test.ts +3 -0
  110. package/src/tests/whoami-route.test.ts +127 -0
  111. package/src/tests/workflow-engine-v2.test.ts +80 -7
  112. package/src/tests/workflow-swarm-script.test.ts +104 -0
  113. package/src/tools/workflows/create-workflow.ts +4 -1
  114. package/src/types.ts +18 -5
  115. package/src/utils/template.ts +8 -1
  116. package/src/workflows/engine.ts +27 -4
  117. package/src/workflows/executors/swarm-script.ts +28 -0
  118. package/src/workflows/retry-poller.ts +19 -2
  119. package/templates/skills/asset-namespaces/content.md +2 -2
  120. package/templates/skills/scheduled-task-resilience/SKILL.md +102 -0
  121. package/templates/skills/scheduled-task-resilience/config.json +14 -0
  122. package/templates/skills/scheduled-task-resilience/content.md +97 -0
@@ -152,7 +152,7 @@ import {
152
152
  withRemoteContext,
153
153
  withSpanContext,
154
154
  writeSkillsToFilesystem
155
- } from "./cli-haanc4qd.js";
155
+ } from "./cli-t76vw5db.js";
156
156
  import"./cli-1z7048dy.js";
157
157
  import {
158
158
  Anthropic
@@ -173,34 +173,34 @@ import {
173
173
  checkHeartbeatChecklist,
174
174
  runHeartbeatSweep,
175
175
  stopHeartbeat
176
- } from "./cli-z9q7pb38.js";
176
+ } from "./cli-d2tfkcga.js";
177
177
  import {
178
178
  createResumeFollowUp,
179
179
  createWorkerTaskFollowUp
180
- } from "./cli-tfw3c0y1.js";
180
+ } from "./cli-nm5gtp1x.js";
181
181
  import {
182
182
  calculateNextRun,
183
183
  dispatchScheduleTarget,
184
184
  ensure,
185
185
  initialize,
186
186
  require_dist
187
- } from "./cli-dakxgk70.js";
187
+ } from "./cli-5ze9rv97.js";
188
188
  import {
189
189
  getModelsCatalog
190
- } from "./cli-qbb2ten8.js";
190
+ } from "./cli-t55yw3a1.js";
191
191
  import {
192
192
  normalizeModelKey
193
- } from "./cli-vr2f46zj.js";
193
+ } from "./cli-t1xze5qh.js";
194
194
  import {
195
195
  getUserGrant
196
- } from "./cli-tp519bjz.js";
196
+ } from "./cli-5v4rw6yd.js";
197
197
  import {
198
198
  can,
199
199
  clearAuditSink,
200
200
  decideToolAdmission,
201
201
  isRbacEnabled,
202
202
  setAuditSink
203
- } from "./cli-hntzdchd.js";
203
+ } from "./cli-bqw0mt1n.js";
204
204
  import {
205
205
  ensureAgentFsCredentialsForAgent,
206
206
  extractArgsJsonSchema,
@@ -210,11 +210,12 @@ import {
210
210
  scriptSdkTypesWithGeneratedApis,
211
211
  scriptStdlibTypesWithGeneratedApis,
212
212
  typecheckScript
213
- } from "./cli-fs153s3x.js";
213
+ } from "./cli-efxfnq6q.js";
214
214
  import {
215
215
  collectScriptReferences,
216
+ getApp,
216
217
  listAppRecords
217
- } from "./cli-brebbsen.js";
218
+ } from "./cli-2q72qz2s.js";
218
219
  import {
219
220
  RawLlmConfigSchema,
220
221
  RawLlmOutputSchema,
@@ -234,7 +235,7 @@ import {
234
235
  validateDefinition,
235
236
  validateJsonSchema,
236
237
  verifyHmacSignature
237
- } from "./cli-xdrmxvd4.js";
238
+ } from "./cli-yw8vghx2.js";
238
239
  import"./cli-3dpj7atn.js";
239
240
  import {
240
241
  ConnectionAuthInputSchema,
@@ -242,6 +243,7 @@ import {
242
243
  MIN_SCRIPT_WALL_CLOCK_MS,
243
244
  applyMcpOAuthRefresh,
244
245
  assertUrlSafe,
246
+ authMethodForStoredClient,
245
247
  buildAuthorizeUrl,
246
248
  buildSandboxedCommand,
247
249
  buildScriptCredentialBindingsWithFailures,
@@ -281,6 +283,7 @@ import {
281
283
  listScripts,
282
284
  listVendoredOpenapiEntries,
283
285
  markMcpOAuthTokenStatus,
286
+ normalizeTokenEndpointAuthMethod,
284
287
  oauthAppToProviderConfig,
285
288
  publicEndpointSsrfOptions,
286
289
  readStreamCapped,
@@ -289,10 +292,12 @@ import {
289
292
  refreshScriptConnection,
290
293
  registerClient,
291
294
  require_typescript,
295
+ resolveAdvertisedTokenEndpointAuthMethod,
292
296
  revokeMcpToken,
293
297
  rotateScriptApiSecret,
294
298
  runScript,
295
299
  sandboxSpawnEnv,
300
+ selectDcrTokenEndpointAuthMethod,
296
301
  setMcpServerAuthMethod,
297
302
  setScriptConnectionEnabled,
298
303
  updateScriptApi,
@@ -300,14 +305,14 @@ import {
300
305
  upsertMcpOAuthToken,
301
306
  upsertScriptByName,
302
307
  upsertScriptConnection
303
- } from "./cli-q8zwffx0.js";
308
+ } from "./cli-pm6xbh84.js";
304
309
  import"./cli-epan13p1.js";
305
310
  import {
306
311
  getApiKey
307
312
  } from "./cli-f14fvzag.js";
308
313
  import {
309
314
  searchScripts
310
- } from "./cli-1px8pn1s.js";
315
+ } from "./cli-qv61hp37.js";
311
316
  import {
312
317
  CANDIDATE_SET_MULTIPLIER,
313
318
  getEmbeddingProvider,
@@ -315,7 +320,7 @@ import {
315
320
  init_constants as init_constants2,
316
321
  init_reranker,
317
322
  rerank
318
- } from "./cli-mf009e0j.js";
323
+ } from "./cli-rzbpmxdr.js";
319
324
  import"./cli-0258203w.js";
320
325
  import {
321
326
  acquireOAuthRefreshLock,
@@ -340,14 +345,14 @@ import {
340
345
  updateAuthorizationIdentity,
341
346
  updateOAuthAppById,
342
347
  upsertAuthorization
343
- } from "./cli-1mj7yz1r.js";
348
+ } from "./cli-g6b8x1h8.js";
344
349
  import"./cli-fad8m16k.js";
345
350
  import {
346
351
  FilesError,
347
352
  getFileStorageProvider,
348
353
  normalizeFilesError
349
354
  } from "./cli-bnx54kxv.js";
350
- import"./cli-r62me33w.js";
355
+ import"./cli-d3x3x1c9.js";
351
356
  import {
352
357
  findUserById,
353
358
  fingerprintApiKey,
@@ -363,15 +368,15 @@ import {
363
368
  resolveUserByToken,
364
369
  revokeToken,
365
370
  unlinkIdentity
366
- } from "./cli-m8fs5ttq.js";
371
+ } from "./cli-psh3c4va.js";
367
372
  import {
368
373
  createTaskWithSiblingAwareness
369
- } from "./cli-mhr8tq3v.js";
374
+ } from "./cli-cdeg08wx.js";
370
375
  import {
371
376
  getSlackApp,
372
377
  startSlackApp,
373
378
  stopSlackApp
374
- } from "./cli-qcsjdppx.js";
379
+ } from "./cli-cvgjwnh1.js";
375
380
  import"./cli-k9qkf1hw.js";
376
381
  import"./cli-b0p7rfnd.js";
377
382
  import"./cli-t930g0xh.js";
@@ -749,7 +754,7 @@ import {
749
754
  upsertSwarmConfig,
750
755
  validateConfigValue,
751
756
  withFavoriteFlags
752
- } from "./cli-s18zzkfp.js";
757
+ } from "./cli-a4jzdpa3.js";
753
758
  import {
754
759
  getAllTemplateDefinitions,
755
760
  getTemplateDefinition,
@@ -762,7 +767,7 @@ import {
762
767
  isEnvFlagEnabled,
763
768
  isSteeringEnabled,
764
769
  resolveTemplate
765
- } from "./cli-4n4mdv21.js";
770
+ } from "./cli-xpxde7rm.js";
766
771
  import {
767
772
  MAX_PROFILE_FILE_LENGTH,
768
773
  getAppUrl,
@@ -784,7 +789,7 @@ import {
784
789
  import {
785
790
  init_package,
786
791
  package_default
787
- } from "./cli-7v5dhmc8.js";
792
+ } from "./cli-72q8m8gk.js";
788
793
  import {
789
794
  array,
790
795
  exports_external,
@@ -799,20 +804,20 @@ import {
799
804
  } from "./cli-9aryf9tv.js";
800
805
  import {
801
806
  bedrockProviderModule
802
- } from "./cli-t5tsq67k.js";
807
+ } from "./cli-9dr5qzc0.js";
803
808
  import"./cli-cwy5hqbq.js";
804
809
  import {
805
810
  setBedrockProviderModule
806
- } from "./cli-6nh2qxvh.js";
811
+ } from "./cli-darcwax3.js";
807
812
  import"./cli-jvv0g8bh.js";
808
813
  import"./cli-r6kqqbj0.js";
809
- import"./cli-ch7t5v7n.js";
814
+ import"./cli-6map995v.js";
810
815
  import"./cli-4wgngmwv.js";
811
816
  import"./cli-vapyk8sw.js";
812
817
  import"./cli-zyxs93y9.js";
813
- import"./cli-vgexpfsr.js";
818
+ import"./cli-57khth04.js";
814
819
  import"./cli-y2apkfe2.js";
815
- import"./cli-w10fkrf1.js";
820
+ import"./cli-akdvwc9v.js";
816
821
  import"./cli-8wrympd7.js";
817
822
  import"./cli-7sgrxg9a.js";
818
823
  import"./cli-3fj60etf.js";
@@ -2619,7 +2624,7 @@ var listAssetsRoute = route({
2619
2624
  tags: ["Assets"],
2620
2625
  query: exports_external.object({
2621
2626
  keyPrefix: AssetKeySchema.optional(),
2622
- types: exports_external.string().optional().describe("Comma-separated task,workflow,schedule,page,file list"),
2627
+ types: exports_external.string().optional().describe("Comma-separated task,workflow,schedule,page,app,script,file list"),
2623
2628
  limit: exports_external.coerce.number().int().min(1).max(1000).optional()
2624
2629
  }),
2625
2630
  responses: {
@@ -2659,6 +2664,41 @@ function ensureOperator(req, res) {
2659
2664
  jsonError(res, "Operator access required", 403);
2660
2665
  return false;
2661
2666
  }
2667
+ var moveAssetBodySchema = exports_external.object({ key: AssetKeySchema });
2668
+ var moveAssetSuccessSchema = exports_external.object({
2669
+ entityType: AssetEntityTypeSchema,
2670
+ id: exports_external.string(),
2671
+ key: AssetKeySchema
2672
+ });
2673
+ var moveAssetResponses = {
2674
+ 200: { description: "Asset namespace updated", schema: moveAssetSuccessSchema },
2675
+ 400: { description: "Invalid namespace" },
2676
+ 403: { description: "Move not authorized" },
2677
+ 404: { description: "Asset not found" },
2678
+ 409: { description: "Moves blocked until audit warnings are repaired" }
2679
+ };
2680
+ var moveAppAssetRoute = route({
2681
+ method: "patch",
2682
+ path: "/api/assets/app/{id}/key",
2683
+ pattern: ["api", "assets", "app", null, "key"],
2684
+ summary: "Move an app to another logical namespace",
2685
+ tags: ["Assets"],
2686
+ params: exports_external.object({ id: exports_external.string().min(1) }),
2687
+ body: moveAssetBodySchema,
2688
+ responses: moveAssetResponses,
2689
+ rbac: { permission: "app.manage" }
2690
+ });
2691
+ var moveScriptAssetRoute = route({
2692
+ method: "patch",
2693
+ path: "/api/assets/script/{id}/key",
2694
+ pattern: ["api", "assets", "script", null, "key"],
2695
+ summary: "Move a script to another logical namespace",
2696
+ tags: ["Assets"],
2697
+ params: exports_external.object({ id: exports_external.string().min(1) }),
2698
+ body: moveAssetBodySchema,
2699
+ responses: moveAssetResponses,
2700
+ rbac: { permission: "script.global.write" }
2701
+ });
2662
2702
  var moveAssetRoute = route({
2663
2703
  method: "patch",
2664
2704
  path: "/api/assets/{entityType}/{id}/key",
@@ -2667,25 +2707,23 @@ var moveAssetRoute = route({
2667
2707
  description: "Updates namespace metadata only. Provider-backed files keep the same provider key, org, and drive; no remote move occurs. Personal keys are labels, not a privacy guarantee.",
2668
2708
  tags: ["Assets"],
2669
2709
  params: exports_external.object({ entityType: AssetEntityTypeSchema, id: exports_external.string().min(1) }),
2670
- body: exports_external.object({ key: AssetKeySchema }),
2671
- responses: {
2672
- 200: {
2673
- description: "Asset namespace updated",
2674
- schema: exports_external.object({
2675
- entityType: AssetEntityTypeSchema,
2676
- id: exports_external.string(),
2677
- key: AssetKeySchema
2678
- })
2679
- },
2680
- 400: { description: "Invalid namespace" },
2681
- 403: { description: "Move not authorized" },
2682
- 404: { description: "Asset not found" },
2683
- 409: { description: "Moves blocked until audit warnings are repaired" }
2684
- },
2710
+ body: moveAssetBodySchema,
2711
+ responses: moveAssetResponses,
2685
2712
  rbac: {
2686
- ungated: "preserves each entity's current mutation posture; task moves additionally use task.fs.mutate, file moves require operator authentication, and personal destinations require a matching trusted user"
2713
+ ungated: "preserves each entity's current mutation posture; task moves use task.fs.mutate, app moves use app.manage, scripts preserve agent ownership/global-lead rules, file moves require operator authentication, and personal destinations require a matching trusted user"
2687
2714
  }
2688
2715
  });
2716
+ function assetMovePrincipal(req, myAgentId) {
2717
+ const auth = getRequestAuth(req);
2718
+ if (auth?.kind === "operator")
2719
+ return { kind: "operator" };
2720
+ if (auth?.kind === "user")
2721
+ return { kind: "user", userId: auth.userId };
2722
+ if (!myAgentId)
2723
+ return null;
2724
+ const agent = getAgentById(myAgentId);
2725
+ return { kind: "agent", agentId: myAgentId, isLead: agent?.isLead ?? false };
2726
+ }
2689
2727
  function canMutateTaskNamespace(task, myAgentId, req) {
2690
2728
  const resource = {
2691
2729
  kind: "task",
@@ -2693,20 +2731,32 @@ function canMutateTaskNamespace(task, myAgentId, req) {
2693
2731
  agentId: task.agentId,
2694
2732
  creatorAgentId: task.creatorAgentId
2695
2733
  };
2696
- const auth = getRequestAuth(req);
2697
- let principal;
2698
- if (auth?.kind === "operator") {
2699
- principal = { kind: "operator" };
2700
- } else if (auth?.kind === "user") {
2701
- principal = { kind: "user", userId: auth.userId };
2702
- } else {
2703
- if (!myAgentId)
2704
- return false;
2705
- const agent = getAgentById(myAgentId);
2706
- principal = { kind: "agent", agentId: myAgentId, isLead: agent?.isLead ?? false };
2707
- }
2734
+ const principal = assetMovePrincipal(req, myAgentId);
2735
+ if (!principal)
2736
+ return false;
2708
2737
  return can({ principal, verb: "task.fs.mutate", resource, source: "http" }).allow;
2709
2738
  }
2739
+ function canManageAppNamespace(id, req, myAgentId) {
2740
+ const principal = assetMovePrincipal(req, myAgentId);
2741
+ return !!principal && can({ principal, verb: "app.manage", resource: { kind: "app", appId: id }, source: "http" }).allow;
2742
+ }
2743
+ function canManageScriptNamespace(script, req, myAgentId) {
2744
+ const principal = assetMovePrincipal(req, myAgentId);
2745
+ if (!principal)
2746
+ return false;
2747
+ if (principal.kind === "operator")
2748
+ return true;
2749
+ if (principal.kind !== "agent")
2750
+ return false;
2751
+ if (script.scope === "agent")
2752
+ return script.scopeId === principal.agentId;
2753
+ return can({
2754
+ principal,
2755
+ verb: "script.global.write",
2756
+ resource: { kind: "owned", scope: "global" },
2757
+ source: "http"
2758
+ }).allow;
2759
+ }
2710
2760
  async function handleAssets(req, res, pathSegments, queryParams, myAgentId) {
2711
2761
  if (keyAuditRoute.match(req.method, pathSegments)) {
2712
2762
  const parsed = await keyAuditRoute.parse(req, res, pathSegments, queryParams);
@@ -2768,7 +2818,7 @@ async function handleAssets(req, res, pathSegments, queryParams, myAgentId) {
2768
2818
  }
2769
2819
  return true;
2770
2820
  }
2771
- if (moveAssetRoute.match(req.method, pathSegments)) {
2821
+ if (moveAppAssetRoute.match(req.method, pathSegments) || moveScriptAssetRoute.match(req.method, pathSegments) || moveAssetRoute.match(req.method, pathSegments)) {
2772
2822
  const parsed = await moveAssetRoute.parse(req, res, pathSegments, queryParams);
2773
2823
  if (!parsed)
2774
2824
  return true;
@@ -2785,6 +2835,27 @@ async function handleAssets(req, res, pathSegments, queryParams, myAgentId) {
2785
2835
  return true;
2786
2836
  }
2787
2837
  }
2838
+ if (parsed.params.entityType === "app") {
2839
+ if (!getApp(parsed.params.id)) {
2840
+ jsonError(res, "Asset not found", 404);
2841
+ return true;
2842
+ }
2843
+ if (!canManageAppNamespace(parsed.params.id, req, myAgentId)) {
2844
+ jsonError(res, "Not authorized to move this app namespace", 403);
2845
+ return true;
2846
+ }
2847
+ }
2848
+ if (parsed.params.entityType === "script") {
2849
+ const script = getScriptById(parsed.params.id);
2850
+ if (!script) {
2851
+ jsonError(res, "Asset not found", 404);
2852
+ return true;
2853
+ }
2854
+ if (!canManageScriptNamespace(script, req, myAgentId)) {
2855
+ jsonError(res, "Not authorized to move this script namespace", 403);
2856
+ return true;
2857
+ }
2858
+ }
2788
2859
  try {
2789
2860
  const actor = resolveHttpAuditUserId(req, myAgentId);
2790
2861
  const key = authorizeAssetKeyWrite(parsed.body.key, actor);
@@ -6589,7 +6660,8 @@ var DiscoveryResultSchema = exports_external.object({
6589
6660
  scopes: exports_external.array(exports_external.string()),
6590
6661
  requiresOAuth: exports_external.literal(true),
6591
6662
  dcrSupported: exports_external.boolean(),
6592
- bearerMethodsSupported: exports_external.array(exports_external.string()).nullable()
6663
+ bearerMethodsSupported: exports_external.array(exports_external.string()).nullable(),
6664
+ tokenEndpointAuthMethodsSupported: exports_external.array(exports_external.string()).nullable()
6593
6665
  });
6594
6666
  var MetadataResponseSchema = exports_external.union([
6595
6667
  exports_external.object({ requiresOAuth: exports_external.literal(false) }),
@@ -6645,7 +6717,8 @@ function manualClientFromToken(token) {
6645
6717
  authorizeUrl: token.authorizeUrl,
6646
6718
  tokenUrl: token.tokenUrl,
6647
6719
  revocationUrl: token.revocationUrl,
6648
- scopes: splitScopes(token.scope)
6720
+ scopes: splitScopes(token.scope),
6721
+ tokenEndpointAuthMethod: authMethodForStoredClient(token.tokenEndpointAuthMethod)
6649
6722
  };
6650
6723
  }
6651
6724
  async function discoverForMcp(resourceUrl) {
@@ -6667,7 +6740,8 @@ async function discoverForMcp(resourceUrl) {
6667
6740
  scopes: prmd.scopes_supported ?? as.scopes_supported ?? [],
6668
6741
  requiresOAuth: true,
6669
6742
  dcrSupported: !!as.registration_endpoint,
6670
- bearerMethodsSupported: prmd.bearer_methods_supported ?? null
6743
+ bearerMethodsSupported: prmd.bearer_methods_supported ?? null,
6744
+ tokenEndpointAuthMethodsSupported: as.token_endpoint_auth_methods_supported ?? null
6671
6745
  };
6672
6746
  }
6673
6747
  function getMcpOrError(res, mcpServerId) {
@@ -6824,7 +6898,8 @@ var manualClientRoute = route({
6824
6898
  authorizeUrl: exports_external.string().url().optional(),
6825
6899
  tokenUrl: exports_external.string().url().optional(),
6826
6900
  revocationUrl: exports_external.string().url().optional(),
6827
- scopes: exports_external.array(exports_external.string()).optional()
6901
+ scopes: exports_external.array(exports_external.string()).optional(),
6902
+ tokenEndpointAuthMethod: exports_external.enum(["client_secret_basic", "client_secret_post", "none"]).optional()
6828
6903
  }),
6829
6904
  responses: {
6830
6905
  200: {
@@ -6886,7 +6961,8 @@ async function runAuthorizeFlow(res, mcpServerId, server, q, userId) {
6886
6961
  authorizeUrl: discovery.authorizeUrl,
6887
6962
  tokenUrl: discovery.tokenUrl,
6888
6963
  revocationUrl: discovery.revocationUrl,
6889
- scopes: reusable.scopes.length > 0 ? reusable.scopes : discovery.scopes
6964
+ scopes: reusable.scopes.length > 0 ? reusable.scopes : discovery.scopes,
6965
+ tokenEndpointAuthMethod: authMethodForStoredClient(reusable.tokenEndpointAuthMethod)
6890
6966
  };
6891
6967
  }
6892
6968
  }
@@ -6900,15 +6976,17 @@ async function runAuthorizeFlow(res, mcpServerId, server, q, userId) {
6900
6976
  return null;
6901
6977
  }
6902
6978
  const scopes2 = q.scopes ? splitScopes(q.scopes) : discovery.scopes;
6979
+ const requestedAuthMethod = selectDcrTokenEndpointAuthMethod(discovery.tokenEndpointAuthMethodsSupported ?? undefined);
6903
6980
  const dcr = await registerClient(discovery.registrationEndpoint, {
6904
6981
  client_name: `agent-swarm (${server.name})`,
6905
6982
  redirect_uris: [callbackRedirectUri()],
6906
6983
  grant_types: ["authorization_code", "refresh_token"],
6907
6984
  response_types: ["code"],
6908
- token_endpoint_auth_method: "client_secret_basic",
6985
+ token_endpoint_auth_method: requestedAuthMethod,
6909
6986
  application_type: "web",
6910
6987
  scope: scopes2.join(" ") || undefined
6911
6988
  });
6989
+ const registeredAuthMethod = dcr.token_endpoint_auth_method ? resolveAdvertisedTokenEndpointAuthMethod(dcr.token_endpoint_auth_method, "returned") : requestedAuthMethod;
6912
6990
  registeredScopes = scopes2;
6913
6991
  client = {
6914
6992
  clientId: dcr.client_id,
@@ -6918,7 +6996,8 @@ async function runAuthorizeFlow(res, mcpServerId, server, q, userId) {
6918
6996
  authorizeUrl: discovery.authorizeUrl,
6919
6997
  tokenUrl: discovery.tokenUrl,
6920
6998
  revocationUrl: discovery.revocationUrl,
6921
- scopes: scopes2
6999
+ scopes: scopes2,
7000
+ tokenEndpointAuthMethod: registeredAuthMethod
6922
7001
  };
6923
7002
  }
6924
7003
  const scopes = q.scopes ? splitScopes(q.scopes) : client.scopes;
@@ -6957,6 +7036,7 @@ async function runAuthorizeFlow(res, mcpServerId, server, q, userId) {
6957
7036
  registeredScopes,
6958
7037
  dcrClientId: client.clientId,
6959
7038
  dcrClientSecret: client.clientSecret,
7039
+ tokenEndpointAuthMethod: client.tokenEndpointAuthMethod,
6960
7040
  redirectUri: callbackRedirectUri(),
6961
7041
  finalRedirect: q.redirect ?? null
6962
7042
  });
@@ -6996,6 +7076,7 @@ async function completeMcpOAuthCallback(res, query) {
6996
7076
  tokenUrl: pending.tokenUrl,
6997
7077
  clientId: pending.dcrClientId ?? "",
6998
7078
  clientSecret: pending.dcrClientSecret ?? undefined,
7079
+ tokenEndpointAuthMethod: authMethodForStoredClient(pending.tokenEndpointAuthMethod),
6999
7080
  redirectUri: pending.redirectUri,
7000
7081
  code: query.code,
7001
7082
  codeVerifier: pending.codeVerifier,
@@ -7021,6 +7102,7 @@ async function completeMcpOAuthCallback(res, query) {
7021
7102
  registeredScopes: pending.registeredScopes ?? undefined,
7022
7103
  dcrClientId: pending.dcrClientId,
7023
7104
  dcrClientSecret: pending.dcrClientSecret,
7105
+ tokenEndpointAuthMethod: authMethodForStoredClient(pending.tokenEndpointAuthMethod),
7024
7106
  clientSource,
7025
7107
  lastRefreshedAt: new Date().toISOString()
7026
7108
  });
@@ -7166,6 +7248,7 @@ async function handleMcpOAuth(req, res, pathSegments, queryParams) {
7166
7248
  tokenUrl: existing.tokenUrl,
7167
7249
  clientId: existing.dcrClientId ?? "",
7168
7250
  clientSecret: existing.dcrClientSecret ?? undefined,
7251
+ tokenEndpointAuthMethod: authMethodForStoredClient(existing.tokenEndpointAuthMethod),
7169
7252
  refreshToken: existing.refreshToken,
7170
7253
  resource: existing.resourceUrl
7171
7254
  });
@@ -7208,7 +7291,8 @@ async function handleMcpOAuth(req, res, pathSegments, queryParams) {
7208
7291
  token: token.accessToken,
7209
7292
  tokenTypeHint: "access_token",
7210
7293
  clientId: token.dcrClientId ?? "",
7211
- clientSecret: token.dcrClientSecret ?? undefined
7294
+ clientSecret: token.dcrClientSecret ?? undefined,
7295
+ tokenEndpointAuthMethod: authMethodForStoredClient(token.tokenEndpointAuthMethod)
7212
7296
  });
7213
7297
  } catch (err) {
7214
7298
  console.warn("[mcp-oauth] revocation call failed (continuing with local delete):", err instanceof Error ? err.message : err);
@@ -7234,6 +7318,8 @@ async function handleMcpOAuth(req, res, pathSegments, queryParams) {
7234
7318
  let authorizationServerIssuer = overrides.authorizationServerIssuer ?? null;
7235
7319
  let resourceUrl = server.url;
7236
7320
  let scopes = overrides.scopes ?? [];
7321
+ let tokenEndpointAuthMethod = overrides.tokenEndpointAuthMethod ? normalizeTokenEndpointAuthMethod(overrides.tokenEndpointAuthMethod) : undefined;
7322
+ let advertisedAuthMethods = null;
7237
7323
  if (!authorizeUrl || !tokenUrl) {
7238
7324
  const discovery = await discoverForMcp(server.url);
7239
7325
  if (!discovery) {
@@ -7247,6 +7333,11 @@ async function handleMcpOAuth(req, res, pathSegments, queryParams) {
7247
7333
  resourceUrl = discovery.resourceUrl;
7248
7334
  if (scopes.length === 0)
7249
7335
  scopes = discovery.scopes;
7336
+ advertisedAuthMethods = discovery.tokenEndpointAuthMethodsSupported;
7337
+ }
7338
+ if (!tokenEndpointAuthMethod) {
7339
+ const postUnsupported = advertisedAuthMethods !== null && advertisedAuthMethods.length > 0 && !advertisedAuthMethods.includes("client_secret_post");
7340
+ tokenEndpointAuthMethod = postUnsupported ? selectDcrTokenEndpointAuthMethod(advertisedAuthMethods ?? undefined) : authMethodForStoredClient(undefined);
7250
7341
  }
7251
7342
  if (!authorizationServerIssuer) {
7252
7343
  jsonError(res, "authorizationServerIssuer is required when endpoints are provided manually.", 400);
@@ -7265,6 +7356,7 @@ async function handleMcpOAuth(req, res, pathSegments, queryParams) {
7265
7356
  revocationUrl,
7266
7357
  dcrClientId: overrides.clientId,
7267
7358
  dcrClientSecret: overrides.clientSecret ?? null,
7359
+ tokenEndpointAuthMethod,
7268
7360
  clientSource: "manual",
7269
7361
  status: "error",
7270
7362
  lastErrorMessage: "Manual client pre-registered; awaiting authorize flow."
@@ -20766,6 +20858,7 @@ async function handleTrackers(req, res, pathSegments) {
20766
20858
  init_zod();
20767
20859
  init_db();
20768
20860
  init_types();
20861
+ init_request_auth_context();
20769
20862
 
20770
20863
  // src/http/operator-actor.ts
20771
20864
  init_request_auth_context();
@@ -20852,6 +20945,24 @@ var UnmappedIdentitySchema = exports_external.object({
20852
20945
  sampleEventType: exports_external.string().nullable(),
20853
20946
  sampleContext: exports_external.unknown().nullable()
20854
20947
  });
20948
+ var whoamiRoute = route({
20949
+ method: "get",
20950
+ path: "/api/whoami",
20951
+ pattern: ["api", "whoami"],
20952
+ summary: "Resolve the authenticated principal behind the presented bearer",
20953
+ tags: ["Users"],
20954
+ responses: {
20955
+ 200: {
20956
+ description: "Authenticated principal",
20957
+ schema: exports_external.object({
20958
+ kind: exports_external.enum(["operator", "user"]),
20959
+ user: exports_external.union([UserSchema, exports_external.null()])
20960
+ })
20961
+ },
20962
+ 401: { description: "Unauthorized" }
20963
+ },
20964
+ auth: { apiKey: true }
20965
+ });
20855
20966
  var listUsers = route({
20856
20967
  method: "get",
20857
20968
  path: "/api/users",
@@ -21165,6 +21276,18 @@ function collectUnmappedForKind(kind, limit) {
21165
21276
  return Array.from(byId.values());
21166
21277
  }
21167
21278
  async function handleUsers(req, res, pathSegments, queryParams) {
21279
+ if (whoamiRoute.match(req.method, pathSegments)) {
21280
+ const parsed = await whoamiRoute.parse(req, res, pathSegments, queryParams);
21281
+ if (!parsed)
21282
+ return true;
21283
+ const auth = getRequestAuth(req);
21284
+ if (auth?.kind === "user") {
21285
+ whoamiRoute.respond(res, 200, { kind: "user", user: auth.user });
21286
+ } else {
21287
+ whoamiRoute.respond(res, 200, { kind: "operator", user: null });
21288
+ }
21289
+ return true;
21290
+ }
21168
21291
  if (listUsers.match(req.method, pathSegments)) {
21169
21292
  const parsed = await listUsers.parse(req, res, pathSegments, queryParams);
21170
21293
  if (!parsed)
@@ -23345,14 +23468,14 @@ async function shutdown() {
23345
23468
  sessionsProcessed: getServerSessionsProcessed()
23346
23469
  });
23347
23470
  if (hasCapability("scheduling")) {
23348
- const { stopScheduler } = await import("./index-9vnkprkh.js");
23471
+ const { stopScheduler } = await import("./index-hfvggd0z.js");
23349
23472
  stopScheduler();
23350
23473
  }
23351
23474
  stopHeartbeat();
23352
23475
  stopScriptRunSupervisor();
23353
23476
  await stopSlackApp();
23354
23477
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
23355
- const { stopOAuthKeepalive } = await import("./keepalive-fc7a2hw9.js");
23478
+ const { stopOAuthKeepalive } = await import("./keepalive-j0fjvqfd.js");
23356
23479
  await stopOAuthKeepalive();
23357
23480
  }
23358
23481
  stopOAuthPendingGc();
@@ -23414,15 +23537,15 @@ try {
23414
23537
  console.warn("[startup] CAPABILITIES upgrade seed failed (non-fatal):", err);
23415
23538
  }
23416
23539
  try {
23417
- const { seedPricingFromModelsDev } = await import("./seed-pricing-47q77nw4.js");
23540
+ const { seedPricingFromModelsDev } = await import("./seed-pricing-yhpv35fr.js");
23418
23541
  seedPricingFromModelsDev();
23419
- const { startPricingRefreshLoop } = await import("./pricing-refresh-n0ve0kh6.js");
23542
+ const { startPricingRefreshLoop } = await import("./pricing-refresh-k49rcyed.js");
23420
23543
  startPricingRefreshLoop();
23421
23544
  } catch (err) {
23422
23545
  console.error("[startup] Failed to seed pricing rows:", err);
23423
23546
  }
23424
23547
  try {
23425
- const { ensureRbacSeedsSynced } = await import("./rbac-roles-bbwb4wrm.js");
23548
+ const { ensureRbacSeedsSynced } = await import("./rbac-roles-30pspvy7.js");
23426
23549
  ensureRbacSeedsSynced();
23427
23550
  } catch (err) {
23428
23551
  console.error("[startup] Failed to sync RBAC seed rows:", err);
@@ -23430,7 +23553,7 @@ try {
23430
23553
  throw err;
23431
23554
  }
23432
23555
  try {
23433
- const { runAllSeeders } = await import("./index-5fdsemf0.js");
23556
+ const { runAllSeeders } = await import("./index-7n2xpbd4.js");
23434
23557
  await runAllSeeders({ scriptEmbeddingMode: "skip" });
23435
23558
  } catch (err) {
23436
23559
  console.error("[startup] Failed to seed built-in entities:", err);
@@ -23466,35 +23589,35 @@ httpServer.listen(port, async () => {
23466
23589
  initWorkflows();
23467
23590
  startScriptRunSupervisor(getMcpBaseUrl());
23468
23591
  if (hasCapability("scheduling")) {
23469
- const { startScheduler } = await import("./index-9vnkprkh.js");
23470
- const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-c0qedjh6.js");
23592
+ const { startScheduler } = await import("./index-hfvggd0z.js");
23593
+ const { getExecutorRegistry: getExecutorRegistry2 } = await import("./index-6gm5he8h.js");
23471
23594
  const intervalMs = Number(process.env.SCHEDULER_INTERVAL_MS) || 1e4;
23472
23595
  startScheduler(getExecutorRegistry2(), intervalMs, {
23473
23596
  runId: globalState.__runId
23474
23597
  });
23475
23598
  }
23476
23599
  if (!isEnvFlagEnabled("HEARTBEAT_DISABLE", false)) {
23477
- const { startHeartbeat } = await import("./index-fnack5vh.js");
23600
+ const { startHeartbeat } = await import("./index-hp1kdbjj.js");
23478
23601
  const heartbeatMs = Number(process.env.HEARTBEAT_INTERVAL_MS) || 90000;
23479
23602
  startHeartbeat(heartbeatMs);
23480
23603
  }
23481
23604
  if (process.env.OAUTH_KEEPALIVE_DISABLE !== "true") {
23482
- const { startOAuthKeepalive } = await import("./keepalive-fc7a2hw9.js");
23605
+ const { startOAuthKeepalive } = await import("./keepalive-j0fjvqfd.js");
23483
23606
  startOAuthKeepalive();
23484
23607
  }
23485
23608
  if (process.env.OAUTH_REFRESH_SWEEP_DISABLE !== "true") {
23486
- const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-f9rptqbt.js");
23609
+ const { startOAuthRefreshSweep } = await import("./oauth-refresh-sweep-s9ecsvh0.js");
23487
23610
  startOAuthRefreshSweep();
23488
23611
  }
23489
23612
  startOAuthPendingGc();
23490
23613
  startMemoryGc();
23491
- import("./boot-reembed-5bgan3cd.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
23614
+ import("./boot-reembed-62p0at2k.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
23492
23615
  console.error("[boot-reembed] startup backfill failed (non-fatal):", err);
23493
23616
  });
23494
- import("./boot-reembed-z7ykyeq8.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
23617
+ import("./boot-reembed-xmfp6wdh.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
23495
23618
  console.error("[boot-reembed-scripts] startup backfill failed (non-fatal):", err);
23496
23619
  });
23497
- import("./boot-scrub-logs-b2rjk8mv.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
23620
+ import("./boot-scrub-logs-rr8q2dms.js").then(({ runBootScrubLogs }) => runBootScrubLogs()).catch((err) => {
23498
23621
  console.error("[boot-scrub-logs] startup scrub failed (non-fatal):", err);
23499
23622
  });
23500
23623
  }).on("error", (err) => {