@desplega.ai/agent-swarm 1.150.0 → 1.152.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 (311) hide show
  1. package/README.md +11 -0
  2. package/dist/{acp-adapter-d5mzggyk.js → acp-adapter-d05sg0q4.js} +5 -5
  3. package/dist/{actions-wn6ew0p7.js → actions-4sc0v342.js} +38 -11
  4. package/dist/{anthropic-messages-ec35ktvx.js → anthropic-messages-2y8nktar.js} +16 -16
  5. package/dist/{app-dty7p9hg.js → app-2d0v6kt6.js} +7 -7
  6. package/dist/{assistant-q4vhgjtx.js → assistant-zs6wdnrf.js} +41 -16
  7. package/dist/{azure-openai-responses-g85jv7m8.js → azure-openai-responses-f38x2avq.js} +13 -13
  8. package/dist/{boot-reembed-n15q6s9x.js → boot-reembed-3dwdnnsr.js} +13 -15
  9. package/dist/{boot-reembed-92292pgf.js → boot-reembed-vhh33520.js} +8 -8
  10. package/dist/{boot-scrub-logs-44pc955m.js → boot-scrub-logs-e1fnabcg.js} +5 -5
  11. package/dist/{claude-adapter-cjegjbje.js → claude-adapter-h58xqzzd.js} +12 -13
  12. package/dist/{claude-managed-adapter-p3ts5m9m.js → claude-managed-adapter-dsmkcrjy.js} +3 -3
  13. package/dist/{claude-sdk-session-7ywbn12v.js → claude-sdk-session-pbaczbgt.js} +12 -13
  14. package/dist/{cli-9gqddmxs.js → cli-4fqn2vpg.js} +8 -8
  15. package/dist/{cli-mzb0n642.js → cli-4wppfkcm.js} +350 -20
  16. package/dist/{cli-h505yhex.js → cli-5bqt4gwa.js} +2 -2
  17. package/dist/{cli-hbagregr.js → cli-5p007m2q.js} +88 -13
  18. package/dist/{cli-3ckzxdt1.js → cli-6k2athpf.js} +94 -81
  19. package/dist/{cli-3mh119qv.js → cli-72vksk1n.js} +9855 -693
  20. package/dist/{cli-taym3dmg.js → cli-87hdfyde.js} +13 -13
  21. package/dist/{cli-zthatyrx.js → cli-8fy9dmpv.js} +5 -5
  22. package/dist/{cli-asvrh7kj.js → cli-9xvdm3bx.js} +1 -1
  23. package/dist/{cli-72xdszyx.js → cli-awb59f08.js} +2 -2
  24. package/dist/{cli-vr6qj104.js → cli-cs9z1hw3.js} +1 -1
  25. package/dist/{cli-kt7wevqh.js → cli-cwvey7n1.js} +164 -56
  26. package/dist/{cli-5my3bjsd.js → cli-d3p82erb.js} +7 -7
  27. package/dist/{cli-7kwmt3r5.js → cli-evgy5w3y.js} +9 -3
  28. package/dist/{cli-111ey3ra.js → cli-f1f9n77e.js} +5 -5
  29. package/dist/{cli-ttje5a4z.js → cli-fhdssm2v.js} +105 -56
  30. package/dist/{cli-a45d5v9b.js → cli-fm4ytsdk.js} +2 -2
  31. package/dist/{cli-qp69dd5d.js → cli-gacq5hg8.js} +116 -14
  32. package/dist/{cli-hmyynq9b.js → cli-ht5rs63n.js} +1 -1
  33. package/dist/{cli-dyx0237s.js → cli-j4nv2wqy.js} +2 -4
  34. package/dist/{cli-gm0fhz13.js → cli-jh9txj4n.js} +2 -1
  35. package/dist/{cli-8chp8xab.js → cli-nd5s3m4y.js} +2 -2
  36. package/dist/{cli-zd21jrrc.js → cli-p2hx1pxm.js} +9872 -424
  37. package/dist/cli-pf9q3696.js +172 -0
  38. package/dist/{cli-7fesa1ky.js → cli-pgj4a5fb.js} +1 -1
  39. package/dist/{cli-07jd68a1.js → cli-re8z5p8p.js} +1 -1
  40. package/dist/{cli-ryz8q8p1.js → cli-t1mykkng.js} +40 -40
  41. package/dist/{cli-ck1vqzdj.js → cli-t6axtdcg.js} +9 -4
  42. package/dist/{cli-1mx65de9.js → cli-wbyk465z.js} +1 -1
  43. package/dist/{cli-kyysm7m3.js → cli-wp7cejrg.js} +1 -1
  44. package/dist/{cli-n75jt793.js → cli-z61ykvam.js} +6 -5
  45. package/dist/{cli-ceb5y160.js → cli-zdcdh02m.js} +1 -1
  46. package/dist/{cli-cmp8g3sw.js → cli-zfzznn7c.js} +45 -9
  47. package/dist/cli.js +22 -21
  48. package/dist/{codex-adapter-rn3aq7jm.js → codex-adapter-v3cz462q.js} +8 -9
  49. package/dist/{codex-hook-gthcmm0g.js → codex-hook-8jexc34x.js} +2 -2
  50. package/dist/{codex-session-runner-bge0cbsw.js → codex-session-runner-de1a5g5z.js} +8 -9
  51. package/dist/{commands-26phw0pc.js → commands-wfqqpn95.js} +5 -5
  52. package/dist/{db-jxjx6s1b.js → db-9zzv5y05.js} +5 -5
  53. package/dist/dispatcher-hfm1jbgx.js +74 -0
  54. package/dist/{google-generative-ai-tsskx7te.js → google-generative-ai-ndjmj5fa.js} +7 -7
  55. package/dist/{google-vertex-pkhpkbq9.js → google-vertex-fr665tqs.js} +10 -10
  56. package/dist/handlers-wrrhsack.js +65 -0
  57. package/dist/{hook-jw0ztn96.js → hook-9skye8zd.js} +9 -10
  58. package/dist/{hook-t6fqsggw.js → hook-fgjv62k5.js} +9 -10
  59. package/dist/{http-hyc7s57s.js → http-7grttjfq.js} +1434 -579
  60. package/dist/{index-bcyx5djw.js → index-29gxx9ar.js} +25 -17
  61. package/dist/{index-wtwpthe1.js → index-30pz2h9w.js} +25 -19
  62. package/dist/{index-1d9r6a74.js → index-4ek1df87.js} +26 -20
  63. package/dist/{index-sfhaq59d.js → index-myfwqqyq.js} +120 -102
  64. package/dist/index-pfhzrh1d.js +25 -0
  65. package/dist/{keepalive-fbsak4ya.js → keepalive-j75m2m7k.js} +7 -7
  66. package/dist/{lead-rdzdm627.js → lead-a1hpjt0a.js} +41 -49
  67. package/dist/{maintenance-25z1c1vf.js → maintenance-tngjzqdq.js} +8 -8
  68. package/dist/{node-209sxmg3.js → node-x1g4v0pq.js} +9 -9
  69. package/dist/{oauth-refresh-sweep-j3d7gtse.js → oauth-refresh-sweep-em1fn044.js} +6 -6
  70. package/dist/{onboard-dkcwrc75.js → onboard-fv7ezvwx.js} +13 -4
  71. package/dist/{openai-codex-responses-pm5gnyfa.js → openai-codex-responses-wy6a43wd.js} +11 -11
  72. package/dist/{openai-responses-vwvk1taj.js → openai-responses-6xwf7bzg.js} +13 -13
  73. package/dist/{opencode-adapter-dce4wskd.js → opencode-adapter-28axqa09.js} +4 -4
  74. package/dist/{otel-impl-8rgyy3j8.js → otel-impl-6vbb568y.js} +1 -1
  75. package/dist/{pi-mono-adapter-4s2bbkgq.js → pi-mono-adapter-jcqt71cg.js} +14 -16
  76. package/dist/{pricing-refresh-9cek71nq.js → pricing-refresh-nmm949an.js} +7 -7
  77. package/dist/{rbac-roles-vk8mqp9v.js → rbac-roles-0fz5qryx.js} +7 -7
  78. package/dist/{rbac-roles-z98s2ypy.js → rbac-roles-xtp05syf.js} +13 -9
  79. package/dist/{render-v2-3j26g0qh.js → render-v2-fpb8whme.js} +7 -7
  80. package/dist/{seed-pricing-7rxhcnzm.js → seed-pricing-zwa8bs3t.js} +6 -6
  81. package/dist/{setup-e2t7vz0c.js → setup-3ybwbdpd.js} +2 -2
  82. package/dist/{work-objects-8d3nd3x2.js → work-objects-rmayxcx7.js} +41 -16
  83. package/dist/{worker-0x9fn7nq.js → worker-rng4jhnh.js} +41 -49
  84. package/openapi.json +1351 -265
  85. package/package.json +2 -1
  86. package/src/agentmail/handlers.ts +95 -71
  87. package/src/be/db-client.ts +5 -0
  88. package/src/be/db.ts +12 -4
  89. package/src/be/extensions/db.ts +461 -0
  90. package/src/be/extensions/validate.ts +107 -0
  91. package/src/be/memory/boot-reembed.ts +17 -12
  92. package/src/be/memory/index.ts +12 -0
  93. package/src/be/memory/providers/openai-embedding.ts +4 -0
  94. package/src/be/memory/types.ts +2 -0
  95. package/src/be/migrations/155_extensions.sql +66 -0
  96. package/src/be/migrations/156_inbox_item_state_read_at.sql +7 -0
  97. package/src/be/rbac-roles.ts +3 -2
  98. package/src/be/scripts/typecheck.ts +56 -38
  99. package/src/be/seed-skills/index.ts +7 -0
  100. package/src/be/swarm-config-guard.ts +10 -2
  101. package/src/commands/onboard/compose-generator.ts +14 -2
  102. package/src/commands/onboard/env-generator.ts +7 -0
  103. package/src/commands/runner.ts +1 -1
  104. package/src/extensions/apply-task-create.ts +135 -0
  105. package/src/extensions/bundle-path.ts +10 -0
  106. package/src/extensions/contract-runtime.ts +7 -0
  107. package/src/extensions/contract-types.generated.ts +4 -0
  108. package/src/extensions/contract.ts +270 -0
  109. package/src/extensions/ctx.ts +186 -0
  110. package/src/extensions/dispatcher.ts +479 -0
  111. package/src/extensions/identity.ts +44 -0
  112. package/src/extensions/lifecycle.ts +303 -0
  113. package/src/extensions/loader.ts +207 -0
  114. package/src/extensions/post-bridge.ts +161 -0
  115. package/src/github/handlers.ts +185 -149
  116. package/src/gitlab/handlers.ts +97 -81
  117. package/src/heartbeat/heartbeat.ts +152 -83
  118. package/src/http/agents.ts +1 -1
  119. package/src/http/all-routes.ts +1 -0
  120. package/src/http/apps.ts +14 -10
  121. package/src/http/core.ts +34 -0
  122. package/src/http/extensions.ts +552 -0
  123. package/src/http/inbox-state.ts +2 -0
  124. package/src/http/index.ts +25 -0
  125. package/src/http/mcp-bridge.ts +96 -62
  126. package/src/http/mcp.ts +1 -1
  127. package/src/http/status.ts +6 -4
  128. package/src/http/tasks.ts +51 -35
  129. package/src/integrations/kapso/inbound.ts +15 -11
  130. package/src/jira/sync.ts +26 -18
  131. package/src/linear/sync.ts +26 -18
  132. package/src/prompts/session-templates.ts +5 -4
  133. package/src/rbac/admission.ts +1 -1
  134. package/src/rbac/elevated-agents.ts +24 -0
  135. package/src/rbac/legacy-policy.ts +47 -6
  136. package/src/rbac/permissions.ts +8 -0
  137. package/src/scheduler/deferred-task-waits.ts +133 -51
  138. package/src/scheduler/schedule-task.ts +50 -24
  139. package/src/scheduler/scheduler.ts +4 -2
  140. package/src/scripts-runtime/executors/native.ts +5 -1
  141. package/src/scripts-runtime/executors/types.ts +5 -0
  142. package/src/scripts-runtime/import-allowlist.ts +79 -19
  143. package/src/scripts-runtime/sdk-allowlist.ts +8 -0
  144. package/src/scripts-runtime/swarm-config.ts +8 -0
  145. package/src/scripts-runtime/swarm-sdk.ts +3 -0
  146. package/src/scripts-runtime/types/stdlib.d.ts +13 -0
  147. package/src/scripts-runtime/types/swarm-extension.d.ts +562 -0
  148. package/src/scripts-runtime/types/swarm-sdk.d.ts +13 -0
  149. package/src/server.ts +18 -0
  150. package/src/slack/HEURISTICS.md +1 -1
  151. package/src/slack/actions.ts +21 -17
  152. package/src/slack/blocks.ts +1 -1
  153. package/src/slack/handlers.ts +98 -5
  154. package/src/slack/inbound-files.ts +6 -2
  155. package/src/slack/render-v2.ts +181 -39
  156. package/src/slack/responses.ts +7 -4
  157. package/src/slack/router.ts +13 -3
  158. package/src/slack/steering.ts +3 -3
  159. package/src/slack/task-output.ts +21 -0
  160. package/src/slack/watcher.ts +3 -2
  161. package/src/slack/work-objects.ts +2 -1
  162. package/src/tasks/errors.ts +9 -0
  163. package/src/tasks/sibling-awareness.ts +35 -1
  164. package/src/tasks/worker-follow-up.ts +64 -12
  165. package/src/tests/base-prompt.test.ts +1 -0
  166. package/src/tests/deferred-task-wake.test.ts +161 -9
  167. package/src/tests/docs-index-footprint.test.js +3 -3
  168. package/src/tests/env-flag.test.ts +1 -0
  169. package/src/tests/extensions-db.test.ts +216 -0
  170. package/src/tests/extensions-dispatcher.test.ts +275 -0
  171. package/src/tests/extensions-example-heartbeat-remediate.test.ts +69 -0
  172. package/src/tests/extensions-example-mcp-install.test.ts +63 -0
  173. package/src/tests/extensions-example-no-exclamation-marks.test.ts +72 -0
  174. package/src/tests/extensions-example-rewrite-and-suppress.test.ts +70 -0
  175. package/src/tests/extensions-example-route-slack-channel.test.ts +217 -0
  176. package/src/tests/extensions-heartbeat.test.ts +291 -0
  177. package/src/tests/extensions-http.test.ts +512 -0
  178. package/src/tests/extensions-lead-equivalence.test.ts +70 -0
  179. package/src/tests/extensions-lifecycle.test.ts +209 -0
  180. package/src/tests/extensions-loader.test.ts +95 -0
  181. package/src/tests/extensions-mcp-tools.test.ts +353 -0
  182. package/src/tests/extensions-pre-task.test.ts +487 -0
  183. package/src/tests/extensions-run-context.test.ts +41 -0
  184. package/src/tests/extensions-tool-call.test.ts +288 -0
  185. package/src/tests/extensions-validate.test.ts +196 -0
  186. package/src/tests/fixtures/extensions/bad-import/hooks.ts +8 -0
  187. package/src/tests/fixtures/extensions/bad-import/manifest.json +9 -0
  188. package/src/tests/fixtures/extensions/bad-return-shape/hooks.ts +10 -0
  189. package/src/tests/fixtures/extensions/bad-return-shape/manifest.json +9 -0
  190. package/src/tests/fixtures/extensions/block-tasks-from-source/hooks.ts +22 -0
  191. package/src/tests/fixtures/extensions/block-tasks-from-source/manifest.json +9 -0
  192. package/src/tests/fixtures/extensions/ignore-channel/hooks.ts +22 -0
  193. package/src/tests/fixtures/extensions/ignore-channel/manifest.json +9 -0
  194. package/src/tests/fixtures/extensions/load.ts +10 -0
  195. package/src/tests/fixtures/extensions/minimal/hooks.ts +7 -0
  196. package/src/tests/fixtures/extensions/minimal/manifest.json +9 -0
  197. package/src/tests/fixtures/extensions/never-fail-long-tasks/hooks.ts +11 -0
  198. package/src/tests/fixtures/extensions/never-fail-long-tasks/manifest.json +9 -0
  199. package/src/tests/fixtures/extensions/no-exclamation-marks/hooks.ts +23 -0
  200. package/src/tests/fixtures/extensions/no-exclamation-marks/manifest.json +9 -0
  201. package/src/tests/fixtures/extensions/post-logger/hooks.ts +9 -0
  202. package/src/tests/fixtures/extensions/post-logger/manifest.json +9 -0
  203. package/src/tests/fixtures/extensions/priority-a/hooks.ts +7 -0
  204. package/src/tests/fixtures/extensions/priority-a/manifest.json +9 -0
  205. package/src/tests/fixtures/extensions/priority-b/hooks.ts +7 -0
  206. package/src/tests/fixtures/extensions/priority-b/manifest.json +9 -0
  207. package/src/tests/fixtures/extensions/record-only-on-tag/hooks.ts +16 -0
  208. package/src/tests/fixtures/extensions/record-only-on-tag/manifest.json +9 -0
  209. package/src/tests/fixtures/extensions/reserved-assets/hooks.ts +5 -0
  210. package/src/tests/fixtures/extensions/reserved-assets/manifest.json +10 -0
  211. package/src/tests/fixtures/extensions/rewrite-progress-prefix/hooks.ts +22 -0
  212. package/src/tests/fixtures/extensions/rewrite-progress-prefix/manifest.json +9 -0
  213. package/src/tests/fixtures/extensions/rewrite-task-priority/hooks.ts +7 -0
  214. package/src/tests/fixtures/extensions/rewrite-task-priority/manifest.json +9 -0
  215. package/src/tests/fixtures/extensions/route-channel-to-agent/hooks.ts +26 -0
  216. package/src/tests/fixtures/extensions/route-channel-to-agent/manifest.json +9 -0
  217. package/src/tests/fixtures/extensions/slow/hooks.ts +10 -0
  218. package/src/tests/fixtures/extensions/slow/manifest.json +9 -0
  219. package/src/tests/fixtures/extensions/suppress-lead-follow-up/hooks.ts +12 -0
  220. package/src/tests/fixtures/extensions/suppress-lead-follow-up/manifest.json +9 -0
  221. package/src/tests/fixtures/extensions/throws/hooks.ts +12 -0
  222. package/src/tests/fixtures/extensions/throws/manifest.json +9 -0
  223. package/src/tests/fixtures/extensions/worker-runtime/hooks.ts +5 -0
  224. package/src/tests/fixtures/extensions/worker-runtime/manifest.json +9 -0
  225. package/src/tests/fixtures/store-progress-malformed-output.json +4 -0
  226. package/src/tests/memory-edit-authorization.test.ts +32 -0
  227. package/src/tests/multi-runtime-enabled-stats.test.ts +2 -2
  228. package/src/tests/multi-runtime-registration.test.ts +14 -14
  229. package/src/tests/onboard-compose.test.ts +44 -0
  230. package/src/tests/preload.ts +5 -0
  231. package/src/tests/rbac-admission-e2e.test.ts +35 -4
  232. package/src/tests/rbac-admission.test.ts +18 -3
  233. package/src/tests/rbac-e2e-helpers.ts +18 -0
  234. package/src/tests/rbac-engine.test.ts +39 -0
  235. package/src/tests/rbac-mcp-admission-e2e.test.ts +22 -4
  236. package/src/tests/realtime-room-auth.test.ts +1 -1
  237. package/src/tests/reload-config.test.ts +61 -0
  238. package/src/tests/routing-affinity-inventory.test.ts +1 -1
  239. package/src/tests/script-connections.test.ts +2 -0
  240. package/src/tests/scripts-boot-reembed.test.ts +4 -0
  241. package/src/tests/scripts-embeddings.test.ts +4 -0
  242. package/src/tests/scripts-import-allowlist.test.ts +44 -1
  243. package/src/tests/scripts-mcp-e2e.test.ts +80 -0
  244. package/src/tests/scripts-only-gating.test.ts +6 -0
  245. package/src/tests/scripts-runtime-identity.test.ts +1 -1
  246. package/src/tests/slack-blocks.test.ts +12 -1
  247. package/src/tests/slack-render-v2.test.ts +100 -5
  248. package/src/tests/slack-router.test.ts +17 -2
  249. package/src/tests/slack-steering.test.ts +19 -0
  250. package/src/tests/slack-task-output.test.ts +36 -0
  251. package/src/tests/status.test.ts +12 -0
  252. package/src/tests/steering-enabled.test.ts +6 -8
  253. package/src/tests/store-progress-attachments-handler.test.ts +100 -1
  254. package/src/tests/swarm-config-reserved-keys.test.ts +6 -1
  255. package/src/tests/task-tool-preload-mcp.test.ts +4 -1
  256. package/src/tests/tool-annotations.test.ts +1 -1
  257. package/src/tests/tool-registrar-no-input.test.ts +42 -1
  258. package/src/tools/defer-task.ts +1 -1
  259. package/src/tools/extension-activate-version.ts +38 -0
  260. package/src/tools/extension-common.ts +85 -0
  261. package/src/tools/extension-delete.ts +29 -0
  262. package/src/tools/extension-disable.ts +36 -0
  263. package/src/tools/extension-enable.ts +36 -0
  264. package/src/tools/extension-install.ts +65 -0
  265. package/src/tools/extension-list.ts +66 -0
  266. package/src/tools/script-common.ts +43 -18
  267. package/src/tools/send-task.ts +69 -107
  268. package/src/tools/store-progress.ts +30 -0
  269. package/src/tools/task-action.ts +43 -22
  270. package/src/tools/task-tool-ctx.ts +2 -0
  271. package/src/tools/tool-config.ts +7 -1
  272. package/src/tools/utils.ts +140 -16
  273. package/src/types.ts +133 -0
  274. package/src/utils/multi-runtime.ts +2 -2
  275. package/src/utils/steering-enabled.ts +4 -4
  276. package/src/workflows/executors/agent-task.ts +13 -3
  277. package/templates/extensions/README.md +17 -0
  278. package/templates/extensions/notify-on-complete/README.md +11 -0
  279. package/templates/extensions/notify-on-complete/hooks.ts +61 -0
  280. package/templates/extensions/notify-on-complete/manifest.json +7 -0
  281. package/templates/extensions/require-ticket-ref/README.md +11 -0
  282. package/templates/extensions/require-ticket-ref/hooks.ts +30 -0
  283. package/templates/extensions/require-ticket-ref/manifest.json +7 -0
  284. package/templates/extensions/require-verification-note/README.md +11 -0
  285. package/templates/extensions/require-verification-note/hooks.ts +32 -0
  286. package/templates/extensions/require-verification-note/manifest.json +7 -0
  287. package/templates/skills/agent-browser/SKILL.md +84 -0
  288. package/templates/skills/agent-browser/content.md +21 -0
  289. package/templates/skills/scheduling/content.md +2 -0
  290. package/templates/skills/swarm-extensions/config.json +14 -0
  291. package/templates/skills/swarm-extensions/content.md +120 -0
  292. package/dist/cli-b8x19vbh.js +0 -823
  293. package/dist/cli-n1yj5fd5.js +0 -164
  294. package/dist/cli-q04q68be.js +0 -3066
  295. package/dist/cli-qgm2pfpq.js +0 -6377
  296. package/dist/cli-rnsr8asm.js +0 -4323
  297. package/dist/cli-rwp3ksm7.js +0 -545
  298. package/dist/cli-xjb9wghj.js +0 -668
  299. package/dist/cli-xvkmedgn.js +0 -332
  300. package/dist/cli-ydk0wjj8.js +0 -338
  301. package/dist/handlers-vr1djg4n.js +0 -41
  302. package/dist/{claude-managed-setup-f5pmsyrp.js → claude-managed-setup-48dwg9bv.js} +3 -3
  303. package/dist/{cli-81r683bv.js → cli-ch38q5z4.js} +0 -0
  304. package/dist/{cli-wk0gjrn3.js → cli-kj76p1ez.js} +6 -6
  305. package/dist/{cli-c71mg51n.js → cli-r2fpe7cx.js} +5 -5
  306. package/dist/{cli-8qx7jnrk.js → cli-y6x0gqtg.js} +16 -16
  307. package/dist/{index-aa3sa6s8.js → index-2wsdsnmm.js} +1 -1
  308. package/dist/{mistral-conversations-4ryk7h83.js → mistral-conversations-qhr84ph3.js} +9 -9
  309. package/dist/{openai-completions-qdcmkfnr.js → openai-completions-32rdwmze.js} +17 -17
  310. package/dist/{openrouter-images-qx18fyp8.js → openrouter-images-9f9ek4rw.js} +3 -3
  311. package/dist/{pi-messages-79jvzz1d.js → pi-messages-b1mbr6gp.js} +4 -4
@@ -0,0 +1,172 @@
1
+ // src/prompts/memories.ts
2
+ var SIMILARITY_THRESHOLD = 0.4;
3
+ var RATE_TOOL_HINT = `
4
+
5
+ When a memory above genuinely helps you solve this task — or actively
6
+ misleads you — call \`memory_rate\` with the memory id and useful=true/false.
7
+ This trains the swarm to surface better memories next time. Use sparingly:
8
+ 2-5 ratings per task is plenty.`;
9
+ function renderMemoriesPrompt(memories) {
10
+ const useful = memories.filter((m) => m.similarity > SIMILARITY_THRESHOLD);
11
+ if (useful.length === 0)
12
+ return null;
13
+ const memoryContext = useful.map((m) => `- **${m.name}** (id: ${m.id}): ${m.content.substring(0, 300)}`).join(`
14
+ `);
15
+ let prompt = `
16
+
17
+ ### Relevant Past Knowledge
18
+
19
+ These memories from your previous sessions may be useful. Use \`memory-get\` with the memory ID to retrieve full details.
20
+
21
+ ${memoryContext}
22
+ `;
23
+ if (isExplicitSelfRaterEnabled()) {
24
+ prompt += RATE_TOOL_HINT;
25
+ }
26
+ return prompt;
27
+ }
28
+ function isExplicitSelfRaterEnabled() {
29
+ const ratersEnabled = (process.env.MEMORY_RATERS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
30
+ return ratersEnabled.includes("explicit-self");
31
+ }
32
+
33
+ // src/utils/skill-fs-writer.ts
34
+ import { existsSync, mkdirSync, readdirSync, rmSync, writeFileSync } from "node:fs";
35
+ import { dirname, join } from "node:path";
36
+ var SWARM_MARKER_FILE = ".swarm-managed";
37
+ function reconcileManagedSkillFiles(skillDir, currentRelativeFiles) {
38
+ if (!existsSync(join(skillDir, SWARM_MARKER_FILE)))
39
+ return 0;
40
+ let removed = 0;
41
+ const walk = (dir, relativeDir = "") => {
42
+ let entries;
43
+ try {
44
+ entries = readdirSync(dir, { withFileTypes: true });
45
+ } catch {
46
+ return false;
47
+ }
48
+ let hasEntries = false;
49
+ for (const entry of entries) {
50
+ const relativePath = relativeDir ? `${relativeDir}/${entry.name}` : entry.name;
51
+ const fullPath = join(dir, entry.name);
52
+ if (entry.isDirectory()) {
53
+ const childHasEntries = walk(fullPath, relativePath);
54
+ if (!childHasEntries) {
55
+ try {
56
+ rmSync(fullPath, { recursive: true, force: true });
57
+ } catch {
58
+ hasEntries = true;
59
+ }
60
+ } else {
61
+ hasEntries = true;
62
+ }
63
+ continue;
64
+ }
65
+ if (relativePath === "SKILL.md" || relativePath === SWARM_MARKER_FILE || currentRelativeFiles.has(relativePath)) {
66
+ hasEntries = true;
67
+ continue;
68
+ }
69
+ try {
70
+ rmSync(fullPath, { force: true });
71
+ removed++;
72
+ } catch {
73
+ hasEntries = true;
74
+ }
75
+ }
76
+ return hasEntries;
77
+ };
78
+ walk(skillDir);
79
+ return removed;
80
+ }
81
+ function writeSkillsToFilesystem(entries, harnessType = "all", home) {
82
+ const errors = [];
83
+ let synced = 0;
84
+ let removed = 0;
85
+ const skillDirs = [];
86
+ if (harnessType === "claude" || harnessType === "all") {
87
+ skillDirs.push(join(home, ".claude", "skills"));
88
+ }
89
+ if (harnessType === "pi" || harnessType === "all") {
90
+ skillDirs.push(join(home, ".pi", "agent", "skills"));
91
+ }
92
+ if (harnessType === "codex" || harnessType === "all") {
93
+ skillDirs.push(join(home, ".codex", "skills"));
94
+ }
95
+ if (harnessType === "opencode" || harnessType === "all") {
96
+ skillDirs.push(join(home, ".opencode", "skills"));
97
+ }
98
+ if (harnessType === "agents" || harnessType === "all") {
99
+ skillDirs.push(join(home, ".agents", "skills"));
100
+ }
101
+ for (const dir of skillDirs) {
102
+ mkdirSync(dir, { recursive: true });
103
+ }
104
+ const writtenNames = new Set;
105
+ for (const skill of entries) {
106
+ if (!skill.isActive || !skill.isEnabled)
107
+ continue;
108
+ if (skill.isComplex && skill.files.length === 0)
109
+ continue;
110
+ if (!skill.content)
111
+ continue;
112
+ const safeName = skill.name.replace(/[^a-zA-Z0-9_-]/g, "_");
113
+ if (!safeName)
114
+ continue;
115
+ writtenNames.add(safeName);
116
+ const currentBundledFilePaths = new Set(skill.files.filter((file) => !file.isBinary).map((file) => file.path));
117
+ for (const baseDir of skillDirs) {
118
+ const skillDir = join(baseDir, safeName);
119
+ const skillFile = join(skillDir, "SKILL.md");
120
+ const markerFile = join(skillDir, SWARM_MARKER_FILE);
121
+ try {
122
+ mkdirSync(skillDir, { recursive: true });
123
+ removed += reconcileManagedSkillFiles(skillDir, currentBundledFilePaths);
124
+ writeFileSync(skillFile, skill.content, "utf-8");
125
+ writeFileSync(markerFile, "", "utf-8");
126
+ synced++;
127
+ } catch (err) {
128
+ const msg = err instanceof Error ? err.message : "Unknown error";
129
+ errors.push(`${skill.name} -> ${skillDir}: ${msg}`);
130
+ console.error(`[skill-fs-writer] Failed to write SKILL.md for ${skill.name} to ${skillDir}: ${msg}`);
131
+ }
132
+ for (const file of skill.files) {
133
+ if (file.isBinary) {
134
+ console.log(`[skill-fs-writer] Skipping binary skill file ${skill.name}/${file.path}`);
135
+ continue;
136
+ }
137
+ const targetPath = join(skillDir, file.path);
138
+ try {
139
+ mkdirSync(dirname(targetPath), { recursive: true });
140
+ writeFileSync(targetPath, file.content, "utf-8");
141
+ } catch (err) {
142
+ const msg = err instanceof Error ? err.message : "Unknown error";
143
+ errors.push(`${skill.name}/${file.path} -> ${targetPath}: ${msg}`);
144
+ console.error(`[skill-fs-writer] Failed to write bundled file ${skill.name}/${file.path} to ${targetPath}: ${msg}`);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ for (const baseDir of skillDirs) {
150
+ if (!existsSync(baseDir))
151
+ continue;
152
+ try {
153
+ const existing = readdirSync(baseDir, { withFileTypes: true });
154
+ for (const entry of existing) {
155
+ if (!entry.isDirectory())
156
+ continue;
157
+ if (writtenNames.has(entry.name))
158
+ continue;
159
+ const skillDir = join(baseDir, entry.name);
160
+ if (!existsSync(join(skillDir, SWARM_MARKER_FILE)))
161
+ continue;
162
+ try {
163
+ rmSync(skillDir, { recursive: true, force: true });
164
+ removed++;
165
+ } catch {}
166
+ }
167
+ } catch {}
168
+ }
169
+ return { synced, removed, errors };
170
+ }
171
+
172
+ export { SIMILARITY_THRESHOLD, renderMemoriesPrompt, writeSkillsToFilesystem };
@@ -2,7 +2,7 @@ import {
2
2
  init_resolver,
3
3
  init_session_templates,
4
4
  resolveTemplateAsync
5
- } from "./cli-n75jt793.js";
5
+ } from "./cli-z61ykvam.js";
6
6
 
7
7
  // src/prompts/steering-delivery.ts
8
8
  init_session_templates();
@@ -6,7 +6,7 @@ import {
6
6
  // src/utils/multi-runtime.ts
7
7
  init_env_flag();
8
8
  function isMultiRuntimeEnabled(env = process.env) {
9
- return parseEnvFlag(env.MULTI_RUNTIME_ENABLED, false);
9
+ return parseEnvFlag(env.MULTI_RUNTIME_ENABLED, true);
10
10
  }
11
11
  function swarmRuntimeInstanceId(env = process.env) {
12
12
  return env.SWARM_RUNTIME_INSTANCE_ID || undefined;
@@ -1,27 +1,22 @@
1
- import {
2
- checkOpencodeCredentials
3
- } from "./cli-5my3bjsd.js";
4
1
  import {
5
2
  renderSteeringDelivery
6
- } from "./cli-7fesa1ky.js";
7
- import {
8
- checkCodexCredentials,
9
- codexUserHome
10
- } from "./cli-taym3dmg.js";
3
+ } from "./cli-pgj4a5fb.js";
11
4
  import {
12
5
  checkClaudeManagedCredentials
13
- } from "./cli-wk0gjrn3.js";
6
+ } from "./cli-kj76p1ez.js";
14
7
  import {
15
8
  checkDevinCredentials
16
9
  } from "./cli-9b13ggd1.js";
17
10
  import {
18
- renderMemoriesPrompt,
19
- resolveScriptsOnlyMode,
20
- writeSkillsToFilesystem
21
- } from "./cli-3mh119qv.js";
11
+ checkOpencodeCredentials
12
+ } from "./cli-d3p82erb.js";
22
13
  import {
23
14
  checkClaudeCredentials
24
- } from "./cli-zthatyrx.js";
15
+ } from "./cli-8fy9dmpv.js";
16
+ import {
17
+ checkCodexCredentials,
18
+ codexUserHome
19
+ } from "./cli-87hdfyde.js";
25
20
  import {
26
21
  MAX_RATE_LIMIT_RESET_MS,
27
22
  isCodexCreditsExhaustedMessage,
@@ -33,8 +28,13 @@ import {
33
28
  getContextWindowSize
34
29
  } from "./cli-s25avqg9.js";
35
30
  import {
31
+ renderMemoriesPrompt,
32
+ writeSkillsToFilesystem
33
+ } from "./cli-pf9q3696.js";
34
+ import {
35
+ resolveScriptsOnlyMode,
36
36
  validateJsonSchema
37
- } from "./cli-rnsr8asm.js";
37
+ } from "./cli-72vksk1n.js";
38
38
  import {
39
39
  authJsonToCredentialSelection,
40
40
  credentialsToAuthJson,
@@ -49,6 +49,16 @@ import {
49
49
  import {
50
50
  getApiKey
51
51
  } from "./cli-f14fvzag.js";
52
+ import {
53
+ ensure,
54
+ initOtel,
55
+ initialize,
56
+ injectTraceContext,
57
+ isPollTracingEnabled,
58
+ startSpan,
59
+ withSpan,
60
+ withSpanContext
61
+ } from "./cli-cwvey7n1.js";
52
62
  import {
53
63
  buildContextPreamble,
54
64
  buildResumeContextPreamble,
@@ -61,17 +71,7 @@ import {
61
71
  syncProfileFilesToServer,
62
72
  writeIdentityBaselines,
63
73
  writeProfileFileFromDb
64
- } from "./cli-a45d5v9b.js";
65
- import {
66
- ensure,
67
- initOtel,
68
- initialize,
69
- injectTraceContext,
70
- isPollTracingEnabled,
71
- startSpan,
72
- withSpan,
73
- withSpanContext
74
- } from "./cli-kt7wevqh.js";
74
+ } from "./cli-fm4ytsdk.js";
75
75
  import {
76
76
  init_task_attachment_links,
77
77
  taskAttachmentFetchCommand
@@ -83,11 +83,7 @@ import {
83
83
  init_types,
84
84
  resolveTaskModelSelection,
85
85
  telemetry
86
- } from "./cli-qp69dd5d.js";
87
- import {
88
- init_credentials,
89
- resolveCredentialPools
90
- } from "./cli-c2mk1kgf.js";
86
+ } from "./cli-gacq5hg8.js";
91
87
  import {
92
88
  generateDefaultClaudeMd,
93
89
  generateDefaultIdentityMd,
@@ -97,7 +93,7 @@ import {
97
93
  init_base_prompt,
98
94
  init_defaults,
99
95
  init_templates
100
- } from "./cli-hmyynq9b.js";
96
+ } from "./cli-ht5rs63n.js";
101
97
  import {
102
98
  configureHttpResolver,
103
99
  init_resolver,
@@ -106,11 +102,15 @@ import {
106
102
  interpolate,
107
103
  isSteeringEnabled,
108
104
  resolveTemplateAsync
109
- } from "./cli-n75jt793.js";
105
+ } from "./cli-z61ykvam.js";
110
106
  import {
111
107
  getMcpBaseUrl,
112
108
  init_constants
113
109
  } from "./cli-dv6cdjs2.js";
110
+ import {
111
+ init_credentials,
112
+ resolveCredentialPools
113
+ } from "./cli-c2mk1kgf.js";
114
114
  import {
115
115
  init_secret_scrubber,
116
116
  scrubSecrets
@@ -151,19 +151,19 @@ async function materializeCodexAuthJson(_slot, creds, deps = {}) {
151
151
  async function createProviderAdapter(provider) {
152
152
  switch (provider) {
153
153
  case "claude": {
154
- const { ClaudeAdapter } = await import("./claude-adapter-cjegjbje.js");
154
+ const { ClaudeAdapter } = await import("./claude-adapter-h58xqzzd.js");
155
155
  return new ClaudeAdapter;
156
156
  }
157
157
  case "pi": {
158
- const { PiMonoAdapter } = await import("./pi-mono-adapter-4s2bbkgq.js");
158
+ const { PiMonoAdapter } = await import("./pi-mono-adapter-jcqt71cg.js");
159
159
  return new PiMonoAdapter;
160
160
  }
161
161
  case "codex": {
162
- const { CodexAdapter } = await import("./codex-adapter-rn3aq7jm.js");
162
+ const { CodexAdapter } = await import("./codex-adapter-v3cz462q.js");
163
163
  return new CodexAdapter;
164
164
  }
165
165
  case "claude-managed": {
166
- const { ClaudeManagedAdapter } = await import("./claude-managed-adapter-p3ts5m9m.js");
166
+ const { ClaudeManagedAdapter } = await import("./claude-managed-adapter-dsmkcrjy.js");
167
167
  return new ClaudeManagedAdapter;
168
168
  }
169
169
  case "devin": {
@@ -171,11 +171,11 @@ async function createProviderAdapter(provider) {
171
171
  return new DevinAdapter;
172
172
  }
173
173
  case "opencode": {
174
- const { OpencodeAdapter } = await import("./opencode-adapter-dce4wskd.js");
174
+ const { OpencodeAdapter } = await import("./opencode-adapter-28axqa09.js");
175
175
  return new OpencodeAdapter;
176
176
  }
177
177
  case "acp": {
178
- const { ACPAdapter } = await import("./acp-adapter-d5mzggyk.js");
178
+ const { ACPAdapter } = await import("./acp-adapter-d05sg0q4.js");
179
179
  return new ACPAdapter;
180
180
  }
181
181
  default:
@@ -588,7 +588,7 @@ var CREDENTIAL_PROVIDER_CHECKERS = {
588
588
  devin: (env) => checkDevinCredentials(env),
589
589
  opencode: (env, opts) => checkOpencodeCredentials(env, opts),
590
590
  pi: async (env, opts) => {
591
- const { checkPiMonoCredentials } = await import("./pi-mono-adapter-4s2bbkgq.js");
591
+ const { checkPiMonoCredentials } = await import("./pi-mono-adapter-jcqt71cg.js");
592
592
  return checkPiMonoCredentials(env, opts);
593
593
  },
594
594
  acp: () => ({ ready: true, missing: [], satisfiedBy: "sdk-delegated" })
@@ -1,13 +1,18 @@
1
1
  import {
2
2
  PermissionVerbSchema
3
- } from "./cli-cmp8g3sw.js";
3
+ } from "./cli-zfzznn7c.js";
4
4
  import {
5
5
  getDb,
6
6
  getDbClient,
7
7
  init_db
8
- } from "./cli-qp69dd5d.js";
8
+ } from "./cli-gacq5hg8.js";
9
+ import {
10
+ init_env_flag,
11
+ isEnvFlagEnabled
12
+ } from "./cli-ej6gbxfb.js";
9
13
 
10
14
  // src/be/rbac-roles.ts
15
+ init_env_flag();
11
16
  init_db();
12
17
  var DEFAULT_ROLE_ID = "rbac-role-admin";
13
18
  var BUILTIN_ROLES = [
@@ -217,8 +222,8 @@ function ensureRbacSeedsSynced(opts) {
217
222
  function describeRbacFlag() {
218
223
  const raw = process.env.RBAC_ENABLED;
219
224
  if (raw === undefined)
220
- return "unset (off)";
221
- return `${raw} (${raw === "true" ? "on" : "off"})`;
225
+ return "unset (on)";
226
+ return `${raw} (${isEnvFlagEnabled("RBAC_ENABLED", true) ? "on" : "off"})`;
222
227
  }
223
228
  function printRolesTable(rows) {
224
229
  const tableRows = rows.map((row) => [
@@ -13,7 +13,7 @@ import {
13
13
  parseClaudeMdPendingRecord,
14
14
  planClaudeMdSync,
15
15
  withFileLock
16
- } from "./cli-a45d5v9b.js";
16
+ } from "./cli-fm4ytsdk.js";
17
17
  import {
18
18
  init_secret_scrubber,
19
19
  scrubSecrets
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  init_package,
3
3
  package_default
4
- } from "./cli-gm0fhz13.js";
4
+ } from "./cli-jh9txj4n.js";
5
5
 
6
6
  // src/commands/shared/client-config.ts
7
7
  init_package();
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  // src/utils/steering-enabled.ts
10
10
  function isSteeringEnabled(env = process.env) {
11
- return parseEnvFlag(env.STEERING_ENABLED, false);
11
+ return parseEnvFlag(env.STEERING_ENABLED, true);
12
12
  }
13
13
  var init_steering_enabled = __esm(() => {
14
14
  init_env_flag();
@@ -272,7 +272,8 @@ Complete with \`store-progress\`: status \`completed\`, and \`output\` naming th
272
272
  Free-text \`output\`: under 120 words by default, with the exceptions in How you write. Link documents instead of inlining them; omit process narration.
273
273
  For a task with \`outputSchema\`, return matching JSON in \`output\`.
274
274
  When you are blocked after real effort, store the blocker with \`store-progress\` and keep working on what you can.
275
- The task has four endings. When you are done: \`completed\`. When the answer needs time (a build, a deploy, a reply): \`defer-task\` with a summary of what you did, when to wake up, and what to check. It completes the task now; the wake-up task continues it. When a person must decide: \`request-human-input\`. When nothing else is possible: \`failed\` with the blocker.
275
+ The task has four endings. When you are done: \`completed\`. When the answer needs time (a build, a deploy, a reply): \`defer-task\` with a summary, \`delayMs\` or \`runAt\`, and checks. It completes the task now; the wake-up task continues it. When a person must decide: \`request-human-input\`. When nothing else is possible: \`failed\` with the blocker.
276
+ For task waits, add \`wakeOn:{event:"settled",taskIds:["<id>"],mode:"all"}\`; the displayed time is a ceiling, not a fixed wake-up.
276
277
  `,
277
278
  variables: [],
278
279
  category: "system"
@@ -292,9 +293,9 @@ Delegate by the shape of the work: a workflow for multi-step or fan-out work, a
292
293
  Research or exploration: tell the worker to use the \`researching\` skill. A large feature: a task for the \`planning\` skill first, then a task for the \`implementing\` skill with \`parentTaskId\`. A small fix: direct implementation.
293
294
  A follow-up that continues earlier work carries \`parentTaskId\`. The worker receives the prior context.
294
295
 
295
- Worker completion/failure triggers a follow-up by default. For longer work, \`defer-task\` with a wake-up or complete this task. Review the worker's answer and complete the follow-up. Escalate only failures needing a person.
296
+ Worker completion/failure triggers a follow-up by default; review the result and complete it. Escalate only failures needing a person. For longer task waits, complete this task or \`defer-task\` with \`wakeOn:{event:"settled",taskIds:["<id>"],mode:"all"}\` alongside \`delayMs\` or \`runAt\`. The displayed time is a ceiling, not a fixed wake-up.
296
297
 
297
- Wait inline via \`wait-for-task\` only for an essential result expected within ~1 minute. Set \`send-task.followUpConfig.disabled=true\`; cap all waits at ~1 minute total. If still running, \`defer-task\` with a wake-up.
298
+ For an essential result expected within ~1 minute, set \`send-task.followUpConfig.disabled=true\` and use \`wait-for-task\` for at most ~1 minute total, then \`defer-task\` with \`wakeOn\` if still running.
298
299
 
299
300
  A task from an unknown user: register them with \`manage-user\`, then continue.
300
301
  Your heartbeat runbook is the \`heartbeatMd\` profile field. Edit it with \`update-profile\`. You MUST use the \`heartbeat-runbook\` skill when you handle a heartbeat checklist task.
@@ -537,7 +538,7 @@ The script authoring contract in the \`swarm-scripts\` skill (entry signature, \
537
538
 
538
539
  **Built-in coordination scripts, USE THESE FIRST (\`script-run\` with \`name\` + \`args\`):**
539
540
  - \`delegate\` {agentName, task, routingReason, routingNote, parentTaskId?} → subtask for an agent by name; returns {taskId}
540
- - \`wait-for-task\` {taskId} → waits up to ~25s for a terminal state; returns {done, status, output}; only for a child expected to finish within about a minute whose result the answer requires. Bound all calls to about a minute total; if still done=false, use \`defer-task\` with a wake-up to collect the result.
541
+ - \`wait-for-task\` {taskId} → waits up to ~25s for a terminal state; returns {done, status, output}; only for a child expected to finish within about a minute whose result the answer requires. Bound all calls to about a minute total; if still done=false, use \`defer-task\` with \`wakeOn:{event:"settled",taskIds:["<id>"],mode:"all"}\` alongside \`delayMs\` or \`runAt\`. The displayed time is a ceiling; matching task outcomes wake you sooner.
541
542
  - \`get-child-outputs\` {parentTaskId} → all children with status+output
542
543
  - \`complete-task\` {taskId, output} → THE way to finish your assigned task
543
544
  - \`report-progress\` {taskId, note} → progress update
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDb,
3
3
  init_db
4
- } from "./cli-qp69dd5d.js";
4
+ } from "./cli-gacq5hg8.js";
5
5
 
6
6
  // src/be/seed-pricing.ts
7
7
  init_db();
@@ -9,6 +9,18 @@ import {
9
9
  _enum
10
10
  } from "./cli-w5e1d1vv.js";
11
11
 
12
+ // src/rbac/elevated-agents.ts
13
+ var leadEquivalentAgentIds = new Set;
14
+ function grantLeadEquivalence(agentId) {
15
+ leadEquivalentAgentIds.add(agentId);
16
+ }
17
+ function revokeLeadEquivalence(agentId) {
18
+ leadEquivalentAgentIds.delete(agentId);
19
+ }
20
+ function hasLeadEquivalence(agentId) {
21
+ return !!agentId && leadEquivalentAgentIds.has(agentId);
22
+ }
23
+
12
24
  // src/rbac/permissions.ts
13
25
  init_zod();
14
26
  var PERMISSIONS = {
@@ -251,6 +263,14 @@ var PERMISSIONS = {
251
263
  "script.api.delete": {
252
264
  description: "Delete an external script API endpoint.",
253
265
  namespace: "script"
266
+ },
267
+ "extension.write": {
268
+ description: "Install, update, or uninstall a swarm extension.",
269
+ namespace: "extension"
270
+ },
271
+ "extension.activate": {
272
+ description: "Enable, disable, or activate a version of a swarm extension.",
273
+ namespace: "extension"
254
274
  }
255
275
  };
256
276
  var PERMISSION_VERBS = Object.keys(PERMISSIONS);
@@ -259,7 +279,7 @@ var PermissionVerbSchema = _enum(PERMISSION_VERBS);
259
279
  // src/rbac/admission.ts
260
280
  init_env_flag();
261
281
  function isRbacEnabled() {
262
- return isEnvFlagEnabled("RBAC_ENABLED", false);
282
+ return isEnvFlagEnabled("RBAC_ENABLED", true);
263
283
  }
264
284
  function decideAdmission(input) {
265
285
  if (input.grant.grantsAll) {
@@ -295,10 +315,24 @@ function decideToolAdmission(input) {
295
315
  return { allow: false, reason: "admission: tool has no permission verb (operator-only)" };
296
316
  }
297
317
  // src/rbac/legacy-policy.ts
318
+ init_env_flag();
319
+ function actsAsLead(principal) {
320
+ return principal.kind === "agent" && (principal.isLead || hasLeadEquivalence(principal.agentId));
321
+ }
298
322
  var leadOnly = {
299
323
  name: "lead-only",
300
324
  denyReason: "requires lead agent",
301
- evaluate: (principal) => principal.kind === "agent" && principal.isLead
325
+ evaluate: (principal) => actsAsLead(principal)
326
+ };
327
+ var leadOrOperatorOrUser = {
328
+ name: "lead-or-operator-or-user",
329
+ denyReason: "requires lead agent, operator, or user authentication",
330
+ evaluate: (principal) => principal.kind === "operator" || principal.kind === "user" || actsAsLead(principal)
331
+ };
332
+ var extensionActivation = {
333
+ name: "extension-activation",
334
+ denyReason: "requires operator/user authentication, or a lead with EXTENSION_ALLOW_LEAD_ACTIVATION enabled",
335
+ evaluate: (principal) => principal.kind === "operator" || principal.kind === "user" || actsAsLead(principal) && isEnvFlagEnabled("EXTENSION_ALLOW_LEAD_ACTIVATION", true)
302
336
  };
303
337
  var leadOrTaskCreator = {
304
338
  name: "lead-or-task-creator",
@@ -306,7 +340,7 @@ var leadOrTaskCreator = {
306
340
  evaluate: (principal, resource) => {
307
341
  if (principal.kind !== "agent")
308
342
  return false;
309
- if (principal.isLead)
343
+ if (actsAsLead(principal))
310
344
  return true;
311
345
  return resource?.kind === "task" && resource.creatorAgentId != null && resource.creatorAgentId === principal.agentId;
312
346
  }
@@ -317,7 +351,7 @@ var leadOrResourceOwner = {
317
351
  evaluate: (principal, resource) => {
318
352
  if (principal.kind !== "agent")
319
353
  return false;
320
- if (principal.isLead)
354
+ if (actsAsLead(principal))
321
355
  return true;
322
356
  return resource?.kind === "owned" && resource.ownerAgentId != null && resource.ownerAgentId === principal.agentId;
323
357
  }
@@ -328,7 +362,7 @@ var leadOrOwnNamespace = {
328
362
  evaluate: (principal, resource) => {
329
363
  if (principal.kind !== "agent")
330
364
  return false;
331
- if (principal.isLead)
365
+ if (actsAsLead(principal))
332
366
  return true;
333
367
  return principal.agentId !== "" && resource?.kind === "kv-namespace" && resource.namespace === `task:agent:${principal.agentId}`;
334
368
  }
@@ -355,7 +389,7 @@ var memoryOwnerOrLeadSwarm = {
355
389
  return false;
356
390
  if (resource.ownerAgentId != null && resource.ownerAgentId === principal.agentId)
357
391
  return true;
358
- return principal.isLead && resource.scope === "swarm";
392
+ return actsAsLead(principal) && resource.scope === "swarm";
359
393
  }
360
394
  };
361
395
  var taskFsMutate = {
@@ -364,7 +398,7 @@ var taskFsMutate = {
364
398
  evaluate: (principal, resource) => {
365
399
  if (principal.kind === "operator" || principal.kind === "user")
366
400
  return true;
367
- if (principal.isLead)
401
+ if (actsAsLead(principal))
368
402
  return true;
369
403
  if (resource?.kind !== "task")
370
404
  return false;
@@ -431,7 +465,9 @@ var LEGACY_POLICY = {
431
465
  "script.api.create": leadOnly,
432
466
  "script.api.update": leadOnly,
433
467
  "script.api.rotate": leadOnly,
434
- "script.api.delete": leadOnly
468
+ "script.api.delete": leadOnly,
469
+ "extension.write": leadOrOperatorOrUser,
470
+ "extension.activate": extensionActivation
435
471
  };
436
472
 
437
473
  // src/rbac/can.ts
@@ -452,4 +488,4 @@ function can(check) {
452
488
  }
453
489
  return decision;
454
490
  }
455
- export { isRbacEnabled, decideAdmission, decideToolAdmission, setAuditSink, clearAuditSink, can, PermissionVerbSchema };
491
+ export { isRbacEnabled, decideAdmission, decideToolAdmission, grantLeadEquivalence, revokeLeadEquivalence, setAuditSink, clearAuditSink, can, PermissionVerbSchema };