@desplega.ai/agent-swarm 2.6.0 → 2.7.1
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.
- package/README.md +2 -0
- package/dist/{acp-adapter-dgfakfpw.js → acp-adapter-8dn5tq56.js} +6 -6
- package/dist/{actions-fbqma8aa.js → actions-3r6gw7dy.js} +18 -18
- package/dist/{amp-adapter-en0jy6hs.js → amp-adapter-wjtq413p.js} +3 -3
- package/dist/{anthropic-messages-txs190dd.js → anthropic-messages-n4cby1rz.js} +4 -4
- package/dist/{app-k8a5cgpp.js → app-d53yhykk.js} +3 -3
- package/dist/{assistant-a16433gr.js → assistant-ksrawj3k.js} +20 -20
- package/dist/{boot-reembed-6c1sjfnr.js → boot-reembed-fxfw17m2.js} +11 -3
- package/dist/{boot-reembed-f4nn561n.js → boot-reembed-k5y5xbj0.js} +15 -8
- package/dist/{boot-scrub-sweep-d4w9gajf.js → boot-scrub-sweep-se41j9fd.js} +3 -3
- package/dist/{boot-seeds-9bmkspyw.js → boot-seeds-r3kwwv8b.js} +4 -4
- package/dist/{claude-adapter-nys1kjxa.js → claude-adapter-ahmyf231.js} +8 -8
- package/dist/{claude-managed-adapter-55207973.js → claude-managed-adapter-5knamegc.js} +3 -3
- package/dist/{claude-managed-setup-3cm35gey.js → claude-managed-setup-mdc7dy6b.js} +3 -3
- package/dist/{claude-sdk-session-nw5yd8cp.js → claude-sdk-session-n5wen9zk.js} +8729 -8600
- package/dist/{cli-683y0b3a.js → cli-0dqtv2jg.js} +2 -2
- package/dist/{cli-a34pr3w1.js → cli-0tww7dnz.js} +2 -2
- package/dist/{cli-w2656ka1.js → cli-0w4e4v58.js} +7 -7
- package/dist/{cli-5sckpqcx.js → cli-2sjm3t4r.js} +1 -1
- package/dist/{cli-gf2850q7.js → cli-3cywb44q.js} +18 -1
- package/dist/{cli-8wkb09q5.js → cli-3k9jej0c.js} +2 -2
- package/dist/{cli-3aqd4jaa.js → cli-3v2cyqb8.js} +3 -3
- package/dist/{cli-emhjcj2y.js → cli-5qt9vzmq.js} +89 -20
- package/dist/{cli-abkm71vr.js → cli-5rp1w4cr.js} +1 -1
- package/dist/{cli-gf95q3bm.js → cli-6vwjsetx.js} +4 -4
- package/dist/{cli-k21gx5ht.js → cli-6w2yrrc0.js} +10 -10
- package/dist/{cli-m70bajzr.js → cli-75tdydgv.js} +1 -1
- package/dist/{cli-5rj83bam.js → cli-8feswf2v.js} +47 -36
- package/dist/{cli-sxgtf5fw.js → cli-8wd3mbyj.js} +1 -1
- package/dist/{cli-ca6banwz.js → cli-9csfthbw.js} +10 -8
- package/dist/{cli-dqygeeh5.js → cli-b41p764a.js} +31 -3
- package/dist/{cli-m5a9m0ak.js → cli-c1t533hh.js} +3 -3
- package/dist/{cli-2sjhpsns.js → cli-c28jxpcv.js} +1 -1
- package/dist/{cli-bqztfyve.js → cli-cb50g9cd.js} +1 -1
- package/dist/{cli-ag2yrnt5.js → cli-d8gaphtr.js} +2 -2
- package/dist/{cli-9abdgn5t.js → cli-dgtfysne.js} +3 -3
- package/dist/{cli-nq677csy.js → cli-dscnhn18.js} +1 -1
- package/dist/{cli-3fwqy71j.js → cli-dv11pgpv.js} +39 -32
- package/dist/{cli-v49fkghp.js → cli-ekptgk2m.js} +6 -6
- package/dist/{cli-c2habvsf.js → cli-f3mzy662.js} +17 -17
- package/dist/{cli-zqne1qcj.js → cli-fk7k8s9x.js} +2 -2
- package/dist/{cli-1tem6ns9.js → cli-gt4h8cxw.js} +3 -2
- package/dist/{cli-vbhgkw9h.js → cli-h3e7bhvn.js} +3 -3
- package/dist/{cli-ffvsj2qw.js → cli-hkxqdmnb.js} +3 -3
- package/dist/{cli-a2rr0fmg.js → cli-hpkvgdad.js} +7 -4
- package/dist/{cli-art7c1zh.js → cli-hq2v4rr5.js} +37 -9
- package/dist/{cli-sqma6vw1.js → cli-k1zb7raw.js} +5 -5
- package/dist/{cli-4rvr7zfx.js → cli-k4awgvzm.js} +5 -0
- package/dist/{cli-3ndmpxxv.js → cli-k7d3hvya.js} +2 -2
- package/dist/{cli-3gfvmzht.js → cli-kbtdftbw.js} +74 -26
- package/dist/{cli-hfeb68z4.js → cli-kj69b9tw.js} +34 -6
- package/dist/{cli-az25fn5f.js → cli-kk9jy4nm.js} +2 -2
- package/dist/{cli-39aet655.js → cli-m52t4cta.js} +1 -1
- package/dist/{cli-cz37jqss.js → cli-mdadewqp.js} +5 -5
- package/dist/{cli-esakngh8.js → cli-nf6k60sn.js} +1 -1
- package/dist/{cli-j6rktc91.js → cli-nzdf09js.js} +1 -1
- package/dist/{cli-rr7zx19j.js → cli-prcyzecg.js} +12 -12
- package/dist/{cli-4hxrf0p4.js → cli-pzafyqtk.js} +393 -62
- package/dist/{cli-g8ka5j4j.js → cli-qvaa1gjp.js} +173 -52
- package/dist/{cli-d2dpf95n.js → cli-rg4b2g6j.js} +1 -1
- package/dist/{cli-kf4jree9.js → cli-rm66vqdz.js} +1 -1
- package/dist/{cli-4rf0f5vg.js → cli-s504c3w7.js} +5 -3
- package/dist/{cli-nn6vx2mq.js → cli-swkx9jm2.js} +7 -5
- package/dist/{cli-g20jjwt4.js → cli-thsaq4pd.js} +16 -16
- package/dist/{cli-aj8djyqt.js → cli-twjnyvs8.js} +2 -2
- package/dist/{cli-03gg9pd1.js → cli-typdpe8g.js} +4 -4
- package/dist/{cli-mtnj4fwa.js → cli-vg8pwmsd.js} +6 -6
- package/dist/{cli-gnsb1zxa.js → cli-vhpckzvp.js} +1 -1
- package/dist/{cli-7enjwya9.js → cli-vz78s5wm.js} +1 -1
- package/dist/{cli-dv97kdzv.js → cli-wdxgsdz5.js} +2 -2
- package/dist/{cli-7a6p4e65.js → cli-wtjg6je3.js} +1 -1
- package/dist/{cli-6y51ryva.js → cli-x3cngb1h.js} +44 -12
- package/dist/{cli-n7asmce6.js → cli-xbz6mcg4.js} +3 -3
- package/dist/{cli-24j1jeeb.js → cli-y4tdxsqb.js} +3 -3
- package/dist/{cli-mvjz5an3.js → cli-yqrsp3ny.js} +7 -7
- package/dist/cli.js +31 -21
- package/dist/{codex-adapter-d95q4qsn.js → codex-adapter-7wepzq15.js} +6 -6
- package/dist/{codex-hook-brpnycn5.js → codex-hook-pbdh4xhx.js} +2 -2
- package/dist/{codex-session-runner-gdwd8h0c.js → codex-session-runner-02sb49e4.js} +6 -6
- package/dist/{commands-jqmgk54b.js → commands-3rcspxct.js} +2 -2
- package/dist/{controller-z3jq589f.js → controller-8ar4avd6.js} +3 -3
- package/dist/{controllers-connect-r2za39ef.js → controllers-connect-ajvh9h0v.js} +19 -19
- package/dist/{cursor-adapter-4mr4jgkw.js → cursor-adapter-gd0sa7bh.js} +1 -1
- package/dist/{db-w36wwb5g.js → db-dv9j7ts5.js} +2 -2
- package/dist/{db-ppv2tze7.js → db-z26vgdvj.js} +3 -3
- package/dist/{dispatcher-pv5h77vf.js → dispatcher-8m0htjq8.js} +17 -17
- package/dist/{dsh-adapter-d4pdpb3r.js → dsh-adapter-y8gyk130.js} +1 -1
- package/dist/{e2b-fn3zacvt.js → e2b-74vg9b7e.js} +1 -1
- package/dist/{e2b-222hsajc.js → e2b-jyay8wzn.js} +1 -1
- package/dist/{easter-egg-3d-4sp4dvmc.js → easter-egg-3d-28f880xx.js} +1 -1
- package/dist/{execute-jev839y1.js → execute-9seb79vh.js} +1 -1
- package/dist/{external-channel-y6nkzhnn.js → external-channel-smz7jyth.js} +2 -2
- package/dist/{getMachineId-bsd-brn0xym3.js → getMachineId-bsd-whfre6gr.js} +3 -3
- package/dist/{getMachineId-darwin-t339sfxm.js → getMachineId-darwin-5zjynb19.js} +3 -3
- package/dist/{getMachineId-linux-5eq95d8b.js → getMachineId-linux-8mksrrsq.js} +3 -3
- package/dist/{getMachineId-unsupported-qavrtc7j.js → getMachineId-unsupported-fxtqsdt2.js} +3 -3
- package/dist/{getMachineId-win-q7fe1wx7.js → getMachineId-win-nzfmz857.js} +3 -3
- package/dist/{grok-adapter-t08b9ntm.js → grok-adapter-z0nnvtbn.js} +7 -7
- package/dist/handlers-pspryh6g.js +41 -0
- package/dist/{heartbeat-vn31xwdk.js → heartbeat-f928aqyp.js} +20 -20
- package/dist/{hook-cpjs8q51.js → hook-d7c605r4.js} +7 -7
- package/dist/{hook-6d0zbvvt.js → hook-q9hv5xf9.js} +5 -5
- package/dist/{http-9c6medda.js → http-q6j4k989.js} +1000 -251
- package/dist/{index-k0yt1tvq.js → index-5nb266jr.js} +17 -17
- package/dist/{index-ysd45kgc.js → index-8fxt5eah.js} +10 -10
- package/dist/{index-zgvqzjsw.js → index-cekzwhez.js} +5 -5
- package/dist/{index-38t35h0n.js → index-ch0c1xff.js} +17 -17
- package/dist/{index-pkma1yf8.js → index-ebnjhxh1.js} +1 -1
- package/dist/{index-yqgbfgaj.js → index-ed8dy8rn.js} +20 -20
- package/dist/{index-qhjf2htm.js → index-ejqdkkqx.js} +262 -96
- package/dist/{index-dr94zbnh.js → index-farm1zsn.js} +32661 -29443
- package/dist/{index-g6k9tctj.js → index-yn1yxg85.js} +1 -1
- package/dist/{keepalive-em0117bp.js → keepalive-zzc3hks1.js} +3 -3
- package/dist/lead-c0pjcaw4.js +79 -0
- package/dist/{maintenance-kbme3qy9.js → maintenance-kqsxzpzx.js} +1 -1
- package/dist/{oauth-refresh-sweep-xysj4yse.js → oauth-refresh-sweep-7qt0g55z.js} +8 -3
- package/dist/{onboard-p6q0vz97.js → onboard-k7x13fqg.js} +121 -8
- package/dist/{opencode-adapter-esv3k9yn.js → opencode-adapter-tqvrtter.js} +5 -5
- package/dist/{otel-impl-54qhqh1z.js → otel-impl-sqkf6k3b.js} +97 -97
- package/dist/{pi-mono-adapter-mymbwhj0.js → pi-mono-adapter-m2qnafxm.js} +89 -14
- package/dist/{pricing-refresh-yb75wv33.js → pricing-refresh-wkpwhgvs.js} +3 -3
- package/dist/{rbac-roles-dexhc9x8.js → rbac-roles-dpn0c0wj.js} +7 -4
- package/dist/{rbac-roles-1vp2mw4p.js → rbac-roles-wk7xd6a6.js} +2 -2
- package/dist/{render-v2-tjay5hhf.js → render-v2-ex2m4g2k.js} +3 -3
- package/dist/{resume-8ayf37g5.js → resume-725g9b0b.js} +7 -7
- package/dist/{runtime-hqe5cqcd.js → runtime-kajas15g.js} +1 -1
- package/dist/{session-access-fdhp987s.js → session-access-0j2ezjje.js} +8 -4
- package/dist/{session-source-backfill-qgtc86z1.js → session-source-backfill-62202awe.js} +2 -2
- package/dist/{setup-4rrmqcq3.js → setup-9sj11ax6.js} +1 -1
- package/dist/{virtual-modules-52km00d6.js → virtual-modules-c6fcq6zr.js} +2 -2
- package/dist/{work-objects-p28fgd70.js → work-objects-0y07495y.js} +20 -20
- package/dist/worker-d4q9sqbc.js +79 -0
- package/openapi.json +1536 -407
- package/package.json +7 -5
- package/src/be/automation-preflight.ts +2 -0
- package/src/be/connector-codes.ts +65 -22
- package/src/be/db/api-keys.ts +9 -0
- package/src/be/db/workflow-runs.ts +36 -5
- package/src/be/db.ts +80 -22
- package/src/be/memory/boot-reembed.ts +4 -1
- package/src/be/memory/constants.ts +6 -0
- package/src/be/memory/embedding-recovery.ts +48 -0
- package/src/be/memory/index-content.ts +5 -2
- package/src/be/memory/providers/openai-embedding.ts +65 -14
- package/src/be/memory/task-learning.ts +257 -0
- package/src/be/memory/types.ts +13 -2
- package/src/be/migrations/245_script_executor.sql +3 -0
- package/src/be/migrations/246_connector_code_kind.sql +11 -0
- package/src/be/oauth-refresh-sweep.ts +2 -1
- package/src/be/onboarding.ts +125 -15
- package/src/be/rbac-roles.ts +4 -1
- package/src/be/scripts/boot-reembed.ts +2 -0
- package/src/be/scripts/db.ts +14 -4
- package/src/be/scripts/embeddings.ts +4 -2
- package/src/be/scripts/run-saved.ts +1 -0
- package/src/be/scripts/typecheck.ts +9 -3
- package/src/be/seed/agent-fs-provision.ts +75 -14
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/swarm-config-guard.ts +3 -0
- package/src/cli.tsx +9 -0
- package/src/comb/config.ts +6 -1
- package/src/commands/onboard/agent-fs-version.ts +5 -0
- package/src/commands/onboard/compose-generator.ts +117 -4
- package/src/commands/onboard/env-generator.ts +9 -0
- package/src/commands/onboard/tei-image.ts +12 -0
- package/src/commands/onboard/types.ts +7 -0
- package/src/commands/onboard.tsx +11 -1
- package/src/commands/provider-credentials.ts +2 -1
- package/src/commands/runner.ts +14 -1
- package/src/heartbeat/heartbeat.ts +14 -1
- package/src/heartbeat/script-runner-probe.ts +47 -0
- package/src/http/agentfs-proxy.ts +369 -0
- package/src/http/all-routes.ts +1 -0
- package/src/http/api-keys.ts +24 -9
- package/src/http/codex-oauth-device.ts +8 -1
- package/src/http/fs.ts +64 -10
- package/src/http/idempotency-key.ts +1 -1
- package/src/http/inbox-state.ts +27 -1
- package/src/http/index.ts +7 -4
- package/src/http/memory.ts +7 -4
- package/src/http/onboarding.ts +139 -11
- package/src/http/pages-public.ts +38 -5
- package/src/http/scripts.ts +27 -0
- package/src/http/session-access.ts +24 -0
- package/src/http/sessions.ts +10 -6
- package/src/http/tasks.ts +85 -11
- package/src/http/telemetry-ui.ts +1 -1
- package/src/http/user-roles.ts +4 -1
- package/src/http/users.ts +272 -3
- package/src/http/utils.ts +22 -3
- package/src/http/workflows.ts +10 -0
- package/src/http/x.ts +5 -0
- package/src/prompts/base-prompt.ts +45 -10
- package/src/prompts/session-templates.ts +43 -5
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/codex-adapter.ts +6 -1
- package/src/providers/cursor-adapter.ts +1 -1
- package/src/providers/dsh-adapter.ts +1 -1
- package/src/providers/pi-mono-adapter.ts +99 -14
- package/src/rbac/legacy-policy.ts +1 -0
- package/src/rbac/permissions.ts +4 -0
- package/src/scheduler/scheduler.ts +2 -1
- package/src/scripts-runtime/eval-harness.ts +8 -1
- package/src/scripts-runtime/executors/native.ts +22 -16
- package/src/scripts-runtime/executors/quickjs-prelude.ts +103 -1
- package/src/scripts-runtime/executors/quickjs-runner.ts +2 -1
- package/src/scripts-runtime/executors/quickjs.ts +7 -0
- package/src/scripts-runtime/executors/registry.ts +32 -0
- package/src/scripts-runtime/executors/types.ts +7 -0
- package/src/scripts-runtime/host-validated-args.ts +133 -0
- package/src/scripts-runtime/loader.ts +30 -3
- package/src/scripts-runtime/swarm-sdk.ts +9 -2
- package/src/scripts-runtime/types/stdlib.d.ts +9 -1
- package/src/scripts-runtime/types/swarm-sdk.d.ts +9 -1
- package/src/tests/agent-fs-provision-seeder.test.ts +261 -92
- package/src/tests/agentfs-proxy.test.ts +1106 -0
- package/src/tests/api-key-status-by-suffix.test.ts +242 -0
- package/src/tests/base-prompt.test.ts +139 -4
- package/src/tests/codex-adapter.test.ts +46 -8
- package/src/tests/codex-oauth-device.test.ts +12 -1
- package/src/tests/comb-config-guard.test.ts +20 -0
- package/src/tests/comb-links.test.ts +79 -1
- package/src/tests/comb-status.test.ts +44 -0
- package/src/tests/community-linear-delivery-loop.test.ts +2099 -0
- package/src/tests/credential-check.test.ts +4 -2
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/docs-index.test.ts +135 -0
- package/src/tests/dsh-adapter.test.ts +1 -1
- package/src/tests/fetch-resolved-env.test.ts +16 -2
- package/src/tests/fixtures/onboard/baseline-states.ts +68 -0
- package/src/tests/fixtures/onboard/content.compose.yml.txt +190 -0
- package/src/tests/fixtures/onboard/content.env.txt +29 -0
- package/src/tests/fixtures/onboard/dev.compose.yml.txt +155 -0
- package/src/tests/fixtures/onboard/dev.env.txt +28 -0
- package/src/tests/fixtures/onboard/full-all.compose.yml.txt +582 -0
- package/src/tests/fixtures/onboard/full-all.env.txt +59 -0
- package/src/tests/fixtures/onboard/full.compose.yml.txt +435 -0
- package/src/tests/fixtures/onboard/full.env.txt +36 -0
- package/src/tests/fixtures/onboard/research.compose.yml.txt +155 -0
- package/src/tests/fixtures/onboard/research.env.txt +28 -0
- package/src/tests/fixtures/onboard/solo.compose.yml.txt +85 -0
- package/src/tests/fixtures/onboard/solo.env.txt +26 -0
- package/src/tests/heartbeat-checklist.test.ts +89 -0
- package/src/tests/heartbeat-script-runner-probe.test.ts +83 -0
- package/src/tests/http-log-scrubbing.test.ts +34 -1
- package/src/tests/http-task-write-ownership.test.ts +5 -1
- package/src/tests/invites-http.test.ts +464 -0
- package/src/tests/memory-embedding-input-cap.test.ts +122 -1
- package/src/tests/memory-embedding-recovery.test.ts +137 -0
- package/src/tests/oauth-refresh-sweep.test.ts +34 -1
- package/src/tests/onboard-compose.test.ts +162 -0
- package/src/tests/onboard-env.test.ts +24 -0
- package/src/tests/onboard-non-interactive.test.ts +29 -0
- package/src/tests/onboard-tei-image.test.ts +36 -0
- package/src/tests/onboarding.test.ts +451 -4
- package/src/tests/openai-embedding-provider.test.ts +105 -2
- package/src/tests/opencode-adapter.test.ts +2 -1
- package/src/tests/pages-frame-ancestors.test.ts +162 -0
- package/src/tests/pi-codemode.test.ts +2 -1
- package/src/tests/pi-mono-adapter.test.ts +54 -0
- package/src/tests/pi-mono-session-cost-on-abort.test.ts +270 -0
- package/src/tests/pi-native-mcp.test.ts +13 -1
- package/src/tests/pi-tool-exposure.test.ts +8 -8
- package/src/tests/preload-env.test.ts +4 -0
- package/src/tests/preload.ts +4 -0
- package/src/tests/probe-tool-schema-tokens.test.ts +144 -0
- package/src/tests/prompt-template-session.test.ts +20 -3
- package/src/tests/rbac-admission-e2e.test.ts +22 -6
- package/src/tests/rbac-admission.test.ts +342 -4
- package/src/tests/rbac-engine.test.ts +1 -0
- package/src/tests/rbac-roles.test.ts +9 -1
- package/src/tests/request-composition-derive.test.ts +329 -0
- package/src/tests/script-connections.test.ts +2 -0
- package/src/tests/script-executor-conformance.test.ts +36 -1
- package/src/tests/script-executor-quickjs-pool.test.ts +50 -0
- package/src/tests/script-executor-quickjs.test.ts +140 -0
- package/src/tests/script-host-validated-args-native.test.ts +196 -0
- package/src/tests/script-per-script-executor.test.ts +415 -0
- package/src/tests/scripts-external-api.test.ts +45 -0
- package/src/tests/sdk-allowlist.test.ts +3 -2
- package/src/tests/self-improvement.test.ts +4 -4
- package/src/tests/send-task-requester-gate.test.ts +64 -3
- package/src/tests/sessions-move.test.ts +39 -1
- package/src/tests/store-progress-learning.test.ts +381 -0
- package/src/tests/ui-logs-parser.test.ts +180 -0
- package/src/tests/whoami-route.test.ts +41 -0
- package/src/tests/workflow-engine-v2.test.ts +116 -1
- package/src/tests/workflow-mcp-trigger-schema.test.ts +209 -0
- package/src/tests/workflow-run-finished-event.test.ts +263 -0
- package/src/tests/workflow-swarm-script.test.ts +34 -0
- package/src/tools/inject-learning.ts +1 -1
- package/src/tools/memory-edit.ts +1 -1
- package/src/tools/memory-search.ts +1 -1
- package/src/tools/script-common.ts +1 -0
- package/src/tools/script-run.ts +7 -0
- package/src/tools/script-upsert.ts +7 -0
- package/src/tools/store-progress.ts +71 -1
- package/src/tools/utils.ts +12 -1
- package/src/tools/workflows/trigger-workflow.ts +104 -10
- package/src/types.ts +12 -1
- package/src/utils/constants.ts +39 -0
- package/src/utils/credentials.ts +5 -2
- package/src/utils/task-attachment-links.ts +15 -3
- package/src/workflows/engine.ts +18 -16
- package/src/workflows/executors/swarm-script.ts +5 -0
- package/src/workflows/foreach-driver.ts +5 -11
- package/src/workflows/node-timeout.ts +30 -0
- package/templates/community/linear-delivery-loop/PLAYBOOK.md +323 -0
- package/templates/community/linear-delivery-loop/README.md +38 -0
- package/templates/community/linear-delivery-loop/config.example.json +31 -0
- package/templates/community/linear-delivery-loop/lead-prompt.md +34 -0
- package/templates/community/linear-delivery-loop/schedule.json +10 -0
- package/templates/community/linear-delivery-loop/scripts/linear-delivery-setup.ts +148 -0
- package/templates/community/linear-delivery-loop/scripts/linear-delivery-tick.ts +1781 -0
- package/templates/skills/swarm-docs/config.json +14 -0
- package/templates/skills/swarm-docs/content.md +144 -0
- package/dist/handlers-eqsnmv95.js +0 -41
- package/dist/lead-23e7z59t.js +0 -79
- package/dist/worker-e3w7vye1.js +0 -79
- package/dist/{azure-openai-responses-9kfwhmn7.js → azure-openai-responses-43asa23s.js} +0 -0
- package/dist/{node-vxx896fa.js → node-t28cc56b.js} +0 -0
- package/dist/{openai-codex-responses-79s8xnbh.js → openai-codex-responses-jhr3sjtm.js} +3 -3
- package/dist/{openai-completions-tdbyts0x.js → openai-completions-gs6yn37k.js} +3 -3
- /package/dist/{openai-responses-dm3t5vqp.js → openai-responses-jqm9vwwk.js} +0 -0
package/src/http/scripts.ts
CHANGED
|
@@ -40,12 +40,14 @@ import {
|
|
|
40
40
|
typecheckScript,
|
|
41
41
|
} from "../be/scripts/typecheck";
|
|
42
42
|
import { can } from "../rbac";
|
|
43
|
+
import { isExecutorAllowedByDeployment } from "../scripts-runtime/executors/registry";
|
|
43
44
|
import { extractScriptSignature, type ScriptSignature } from "../scripts-runtime/extract-signature";
|
|
44
45
|
import { checkQuickJSCompat, quickJSCompatWarnings } from "../scripts-runtime/quickjs-compat";
|
|
45
46
|
import {
|
|
46
47
|
ScriptApiAuthModeSchema,
|
|
47
48
|
ScriptApiRecordSchema,
|
|
48
49
|
type ScriptDetail,
|
|
50
|
+
ScriptExecutorNameSchema,
|
|
49
51
|
ScriptFsModeSchema,
|
|
50
52
|
type ScriptListItem,
|
|
51
53
|
type ScriptRecord,
|
|
@@ -67,6 +69,7 @@ const upsertBodySchema = z.object({
|
|
|
67
69
|
intent: z.string().default(""),
|
|
68
70
|
scope: ScriptScopeSchema.default("agent"),
|
|
69
71
|
fsMode: ScriptFsModeSchema.default("none"),
|
|
72
|
+
executor: ScriptExecutorNameSchema.nullable().optional(),
|
|
70
73
|
});
|
|
71
74
|
|
|
72
75
|
const runBodySchema = z
|
|
@@ -77,6 +80,7 @@ const runBodySchema = z
|
|
|
77
80
|
intent: z.string().default(""),
|
|
78
81
|
scope: ScriptScopeSchema.optional(),
|
|
79
82
|
fsMode: ScriptFsModeSchema.default("none"),
|
|
83
|
+
executor: ScriptExecutorNameSchema.nullable().optional(),
|
|
80
84
|
idempotencyKey: z.string().max(200).optional(),
|
|
81
85
|
})
|
|
82
86
|
.refine((body) => Boolean(body.name) !== Boolean(body.source), {
|
|
@@ -671,6 +675,15 @@ export async function handleScripts(
|
|
|
671
675
|
}
|
|
672
676
|
}
|
|
673
677
|
|
|
678
|
+
if (parsed.body.executor && !isExecutorAllowedByDeployment(parsed.body.executor)) {
|
|
679
|
+
jsonError(
|
|
680
|
+
res,
|
|
681
|
+
'Executor "native" is not permitted when deployment SCRIPT_EXECUTOR="quickjs"',
|
|
682
|
+
400,
|
|
683
|
+
);
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
|
|
674
687
|
const secretRefusal = refuseSourceWithSecrets(parsed.body.source);
|
|
675
688
|
if (secretRefusal) {
|
|
676
689
|
json(res, secretRefusal, 400);
|
|
@@ -708,6 +721,7 @@ export async function handleScripts(
|
|
|
708
721
|
signatureJson: signatureJsonFor(parsed.body.source),
|
|
709
722
|
argsJsonSchema,
|
|
710
723
|
fsMode: parsed.body.fsMode,
|
|
724
|
+
executor: parsed.body.executor,
|
|
711
725
|
agentId: agent.id,
|
|
712
726
|
isScratch: false,
|
|
713
727
|
typeChecked: true,
|
|
@@ -758,6 +772,7 @@ export async function handleScripts(
|
|
|
758
772
|
|
|
759
773
|
let source = parsed.body.source;
|
|
760
774
|
let fsMode = parsed.body.fsMode;
|
|
775
|
+
let executor = parsed.body.executor ?? null;
|
|
761
776
|
let namedScript: ScriptRecord | null = null;
|
|
762
777
|
if (parsed.body.name) {
|
|
763
778
|
const script = await resolveScript(parsed.body.name, agent.id, parsed.body.scope);
|
|
@@ -768,6 +783,7 @@ export async function handleScripts(
|
|
|
768
783
|
namedScript = script;
|
|
769
784
|
source = script.source;
|
|
770
785
|
fsMode = script.fsMode;
|
|
786
|
+
executor = parsed.body.executor !== undefined ? parsed.body.executor : script.executor;
|
|
771
787
|
}
|
|
772
788
|
|
|
773
789
|
if (fsMode === "workspace-rw") {
|
|
@@ -775,6 +791,15 @@ export async function handleScripts(
|
|
|
775
791
|
return true;
|
|
776
792
|
}
|
|
777
793
|
|
|
794
|
+
if (executor && !isExecutorAllowedByDeployment(executor)) {
|
|
795
|
+
jsonError(
|
|
796
|
+
res,
|
|
797
|
+
'Executor "native" is not permitted when deployment SCRIPT_EXECUTOR="quickjs"',
|
|
798
|
+
400,
|
|
799
|
+
);
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
|
|
778
803
|
const startedAt = new Date().toISOString();
|
|
779
804
|
// Touch before executing so an already-stale scratch script isn't reaped
|
|
780
805
|
// by the retention sweep while this run is still in flight.
|
|
@@ -786,6 +811,7 @@ export async function handleScripts(
|
|
|
786
811
|
source: source as string,
|
|
787
812
|
args: parsed.body.args,
|
|
788
813
|
fsMode,
|
|
814
|
+
executor,
|
|
789
815
|
agentId: agent.id,
|
|
790
816
|
runtimeInstanceId,
|
|
791
817
|
egressSecrets: credentials.egressSecrets,
|
|
@@ -954,6 +980,7 @@ export async function handleScripts(
|
|
|
954
980
|
isScratch: script.isScratch,
|
|
955
981
|
typeChecked: script.typeChecked,
|
|
956
982
|
fsMode: script.fsMode,
|
|
983
|
+
executor: script.executor,
|
|
957
984
|
createdByAgentId: script.createdByAgentId,
|
|
958
985
|
createdAt: script.createdAt,
|
|
959
986
|
updatedAt: script.updatedAt,
|
|
@@ -88,6 +88,30 @@ export async function hasSessionWrite(
|
|
|
88
88
|
return hasSessionAccess(access, "write");
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
export const NOT_YOUR_TASK_DENIED =
|
|
92
|
+
"You can only change tasks you requested, or sessions shared with you to edit.";
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* True when a user token without a grant-all role (RBAC on) changes a task it
|
|
96
|
+
* does not own: neither the task nor its session root names the user as
|
|
97
|
+
* requester, and the session is not shared with the user for writing. The
|
|
98
|
+
* session wall reads an ownerless root (Slack, schedules, operator key) as
|
|
99
|
+
* everyone's; for such a user it is not theirs to change. Operator, agent and
|
|
100
|
+
* admin callers are never denied here.
|
|
101
|
+
*/
|
|
102
|
+
export async function deniesNonOwnerTaskWrite(
|
|
103
|
+
req: IncomingMessage,
|
|
104
|
+
task: { id: string; requestedByUserId?: string | null },
|
|
105
|
+
): Promise<boolean> {
|
|
106
|
+
const auth = getRequestAuth(req);
|
|
107
|
+
if (auth?.kind !== "user" || !isRbacEnabled()) return false;
|
|
108
|
+
if (task.requestedByUserId === auth.userId) return false;
|
|
109
|
+
if ((await getUserGrant(auth.userId)).grantsAll) return false;
|
|
110
|
+
const root = await getSessionRoot(task.id);
|
|
111
|
+
if (!root?.requestedByUserId) return true;
|
|
112
|
+
return !hasSessionAccess(await sessionAccessForRoot(auth.userId, root), "write");
|
|
113
|
+
}
|
|
114
|
+
|
|
91
115
|
/**
|
|
92
116
|
* The parent gate shared by `POST /api/tasks` and `POST /api/apps/{id}/actions/{name}`.
|
|
93
117
|
* The child inherits the parent's thread context, so an agent caller must own or
|
package/src/http/sessions.ts
CHANGED
|
@@ -77,7 +77,13 @@ import { isRuntimePoolsEnabled } from "../utils/runtime-pools-flag";
|
|
|
77
77
|
import { canMutateTaskNamespace } from "./assets";
|
|
78
78
|
import { agentFirstPrincipal } from "./request-principal";
|
|
79
79
|
import { route } from "./route-def";
|
|
80
|
-
import {
|
|
80
|
+
import {
|
|
81
|
+
deniesNonOwnerTaskWrite,
|
|
82
|
+
NOT_YOUR_TASK_DENIED,
|
|
83
|
+
resolveSessionActor,
|
|
84
|
+
type SessionActor,
|
|
85
|
+
sessionAccessFor,
|
|
86
|
+
} from "./session-access";
|
|
81
87
|
import { jsonError } from "./utils";
|
|
82
88
|
|
|
83
89
|
// ─── Response Schemas ────────────────────────────────────────────────────────
|
|
@@ -660,7 +666,7 @@ const triageSessionListRoute = route({
|
|
|
660
666
|
401: { description: "Unauthorized" },
|
|
661
667
|
},
|
|
662
668
|
auth: { apiKey: true },
|
|
663
|
-
rbac: {
|
|
669
|
+
rbac: { permission: "favorite.write.own" },
|
|
664
670
|
});
|
|
665
671
|
|
|
666
672
|
const SESSION_MOVE_LIMIT = 200;
|
|
@@ -671,10 +677,7 @@ const SessionMoveResultSchema = z.object({
|
|
|
671
677
|
moved: z.array(z.string()),
|
|
672
678
|
skipped: z.array(z.object({ rootTaskId: z.string(), reason: z.string() })),
|
|
673
679
|
});
|
|
674
|
-
const sessionMoveRbac = {
|
|
675
|
-
ungated:
|
|
676
|
-
"per-session access, per-task task.fs.mutate, and asset-key write checks in the handler, as PATCH /api/assets/task/{id}/key",
|
|
677
|
-
};
|
|
680
|
+
const sessionMoveRbac = { permission: "task.fs.mutate" } as const;
|
|
678
681
|
const sessionMoveResponses = {
|
|
679
682
|
400: { description: "Invalid namespace or request" },
|
|
680
683
|
403: { description: "Personal destination not authorized" },
|
|
@@ -759,6 +762,7 @@ async function checkSessionMove(
|
|
|
759
762
|
const access = await sessionAccessFor(actor, root.id);
|
|
760
763
|
if (access === "none") return { reason: SESSION_MOVE_UNAVAILABLE };
|
|
761
764
|
if (!hasSessionAccess(access, "write")) return { reason: "Session write access required" };
|
|
765
|
+
if (await deniesNonOwnerTaskWrite(req, root)) return { reason: NOT_YOUR_TASK_DENIED };
|
|
762
766
|
}
|
|
763
767
|
if (root.parentTaskId) return { reason: "Task is not a session root" };
|
|
764
768
|
const sourceError = sourceMoveError(options.destination ?? null, root);
|
package/src/http/tasks.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getAgentById,
|
|
12
12
|
getAllTasks,
|
|
13
13
|
getDbClient,
|
|
14
|
+
getInProgressTasksByContextKey,
|
|
14
15
|
getLeadAgent,
|
|
15
16
|
getLogsByTaskId,
|
|
16
17
|
getPausedTasksForAgent,
|
|
@@ -39,6 +40,7 @@ import {
|
|
|
39
40
|
} from "../be/db";
|
|
40
41
|
import { modelProfileRefError, taskProfileError } from "../be/db/model-profiles";
|
|
41
42
|
import { explicitModelErrorForAgent } from "../be/model-validation";
|
|
43
|
+
import { getUserGrant } from "../be/rbac-roles";
|
|
42
44
|
import { hasSessionAccess, type SessionAccess } from "../be/session-shares";
|
|
43
45
|
import {
|
|
44
46
|
getTaskSteeringFields,
|
|
@@ -49,7 +51,7 @@ import {
|
|
|
49
51
|
} from "../be/steering";
|
|
50
52
|
import { getTaskCitations, TaskCitationSchema } from "../be/task-citations";
|
|
51
53
|
import { findUserById } from "../be/users";
|
|
52
|
-
import { can, type RbacPrincipal, type RbacResource } from "../rbac";
|
|
54
|
+
import { can, isRbacEnabled, type RbacPrincipal, type RbacResource } from "../rbac";
|
|
53
55
|
import { chatThreadOfContextKey } from "../tasks/context-key";
|
|
54
56
|
import { TaskCreationBlockedError } from "../tasks/errors";
|
|
55
57
|
import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
|
|
@@ -87,7 +89,9 @@ import { buildTaskRequestedBy, TaskRequestedBySchema } from "./requested-by";
|
|
|
87
89
|
import { bodyTask, route } from "./route-def";
|
|
88
90
|
import {
|
|
89
91
|
canReadSession,
|
|
92
|
+
deniesNonOwnerTaskWrite,
|
|
90
93
|
denyParentAttach,
|
|
94
|
+
NOT_YOUR_TASK_DENIED,
|
|
91
95
|
readableByFor,
|
|
92
96
|
resolveSessionActor,
|
|
93
97
|
SESSION_READ_DENIED,
|
|
@@ -279,6 +283,7 @@ const createTask = route({
|
|
|
279
283
|
path: "/api/tasks",
|
|
280
284
|
pattern: ["api", "tasks"],
|
|
281
285
|
session: bodyTask("parentTaskId"),
|
|
286
|
+
rbac: { permission: "task.create.own" },
|
|
282
287
|
summary: "Create a new task",
|
|
283
288
|
tags: ["Tasks"],
|
|
284
289
|
body: z
|
|
@@ -411,6 +416,7 @@ const cancelTaskRoute = route({
|
|
|
411
416
|
path: "/api/tasks/{id}/cancel",
|
|
412
417
|
pattern: ["api", "tasks", null, "cancel"],
|
|
413
418
|
session: { taskParam: "id" },
|
|
419
|
+
rbac: { permission: "task.cancel.own" },
|
|
414
420
|
summary: "Cancel a pending or in-progress task",
|
|
415
421
|
tags: ["Tasks"],
|
|
416
422
|
params: z.object({ id: z.string() }),
|
|
@@ -687,6 +693,7 @@ const pauseTaskRoute = route({
|
|
|
687
693
|
path: "/api/tasks/{id}/pause",
|
|
688
694
|
pattern: ["api", "tasks", null, "pause"],
|
|
689
695
|
session: { taskParam: "id" },
|
|
696
|
+
rbac: { permission: "task.action.own" },
|
|
690
697
|
summary: "Pause an in-progress task",
|
|
691
698
|
tags: ["Tasks"],
|
|
692
699
|
params: z.object({ id: z.string() }),
|
|
@@ -703,6 +710,7 @@ const resumeTaskRoute = route({
|
|
|
703
710
|
path: "/api/tasks/{id}/resume",
|
|
704
711
|
pattern: ["api", "tasks", null, "resume"],
|
|
705
712
|
session: { taskParam: "id" },
|
|
713
|
+
rbac: { permission: "task.action.own" },
|
|
706
714
|
summary: "Resume a paused task",
|
|
707
715
|
tags: ["Tasks"],
|
|
708
716
|
params: z.object({ id: z.string() }),
|
|
@@ -777,9 +785,7 @@ const updateTaskTitleRoute = route({
|
|
|
777
785
|
404: { description: "Task not found" },
|
|
778
786
|
},
|
|
779
787
|
auth: { apiKey: true },
|
|
780
|
-
rbac: {
|
|
781
|
-
ungated: "mirrors the pre-RBAC PATCH /api/tasks/{id}/vcs sibling route: bearer auth only",
|
|
782
|
-
},
|
|
788
|
+
rbac: { permission: "task.action.own" },
|
|
783
789
|
});
|
|
784
790
|
|
|
785
791
|
async function canSteerTask(
|
|
@@ -879,6 +885,40 @@ async function resolveTaskWritePrincipal(
|
|
|
879
885
|
return { kind: "agent", agentId, isLead: agent?.isLead === true };
|
|
880
886
|
}
|
|
881
887
|
|
|
888
|
+
/**
|
|
889
|
+
* May this caller bind a new task to a chat thread? The operator may. An agent needs the
|
|
890
|
+
* lead's chat post permission. A user needs admin, or a role with `integration.chat.post`.
|
|
891
|
+
*/
|
|
892
|
+
async function mayBindChatThread(principal: RbacPrincipal): Promise<boolean> {
|
|
893
|
+
if (principal.kind === "operator") return true;
|
|
894
|
+
if (principal.kind === "user") {
|
|
895
|
+
if (!isRbacEnabled()) return true;
|
|
896
|
+
const grant = await getUserGrant(principal.userId);
|
|
897
|
+
return grant.grantsAll || grant.verbs.has("integration.chat.post");
|
|
898
|
+
}
|
|
899
|
+
return can({
|
|
900
|
+
principal,
|
|
901
|
+
verb: "integration.chat.post",
|
|
902
|
+
resource: { kind: "none" },
|
|
903
|
+
source: "http",
|
|
904
|
+
}).allow;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* Sibling awareness copies the open tasks under a contextKey into the new task, and may pick
|
|
909
|
+
* one as its parent. A non-admin user may name a context only when they may write each of
|
|
910
|
+
* its open tasks.
|
|
911
|
+
*/
|
|
912
|
+
async function deniesForeignContext(req: IncomingMessage, contextKey: string): Promise<boolean> {
|
|
913
|
+
const auth = getRequestAuth(req);
|
|
914
|
+
if (auth?.kind !== "user" || !isRbacEnabled()) return false;
|
|
915
|
+
if ((await getUserGrant(auth.userId)).grantsAll) return false;
|
|
916
|
+
for (const task of await getInProgressTasksByContextKey(contextKey)) {
|
|
917
|
+
if (await deniesNonOwnerTaskWrite(req, task)) return true;
|
|
918
|
+
}
|
|
919
|
+
return false;
|
|
920
|
+
}
|
|
921
|
+
|
|
882
922
|
/**
|
|
883
923
|
* Requester for a new task. Prefer trusted server-side identity: an
|
|
884
924
|
* authenticated request user, or the caller's own ownership-gated task context
|
|
@@ -1070,17 +1110,27 @@ export async function handleTasks(
|
|
|
1070
1110
|
return true;
|
|
1071
1111
|
}
|
|
1072
1112
|
// A chat-sdk contextKey binds the task to a chat thread that its assignee and creator
|
|
1073
|
-
// may then read and post to.
|
|
1074
|
-
//
|
|
1113
|
+
// may then read and post to. Only a caller with chat post permission may name a thread
|
|
1114
|
+
// other than the parent's.
|
|
1075
1115
|
if (
|
|
1076
|
-
principal.kind === "agent" &&
|
|
1077
1116
|
parsed.body.contextKey &&
|
|
1078
1117
|
parsed.body.contextKey !== parentTask?.contextKey &&
|
|
1079
1118
|
chatThreadOfContextKey(parsed.body.contextKey) &&
|
|
1080
|
-
!
|
|
1081
|
-
.allow
|
|
1119
|
+
!(await mayBindChatThread(principal))
|
|
1082
1120
|
) {
|
|
1083
|
-
jsonError(
|
|
1121
|
+
jsonError(
|
|
1122
|
+
res,
|
|
1123
|
+
"Permission denied: only a lead or an admin can bind a task to a chat thread.",
|
|
1124
|
+
403,
|
|
1125
|
+
);
|
|
1126
|
+
return true;
|
|
1127
|
+
}
|
|
1128
|
+
if (
|
|
1129
|
+
parsed.body.contextKey &&
|
|
1130
|
+
parsed.body.contextKey !== parentTask?.contextKey &&
|
|
1131
|
+
(await deniesForeignContext(req, parsed.body.contextKey))
|
|
1132
|
+
) {
|
|
1133
|
+
jsonError(res, "You don't have access to the tasks in this context.", 403);
|
|
1084
1134
|
return true;
|
|
1085
1135
|
}
|
|
1086
1136
|
let assetKey: string | undefined;
|
|
@@ -1240,7 +1290,12 @@ export async function handleTasks(
|
|
|
1240
1290
|
return true;
|
|
1241
1291
|
}
|
|
1242
1292
|
|
|
1243
|
-
|
|
1293
|
+
if (await deniesNonOwnerTaskWrite(req, task)) {
|
|
1294
|
+
jsonError(res, NOT_YOUR_TASK_DENIED, 403);
|
|
1295
|
+
return true;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
// Admins may cancel any task. Agents get the MCP cancel-task policy:
|
|
1244
1299
|
// lead or task creator.
|
|
1245
1300
|
const principal = await resolveTaskWritePrincipal(req, myAgentId);
|
|
1246
1301
|
if (
|
|
@@ -1882,6 +1937,11 @@ export async function handleTasks(
|
|
|
1882
1937
|
return true;
|
|
1883
1938
|
}
|
|
1884
1939
|
|
|
1940
|
+
if (await deniesNonOwnerTaskWrite(req, task)) {
|
|
1941
|
+
jsonError(res, NOT_YOUR_TASK_DENIED, 403);
|
|
1942
|
+
return true;
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1885
1945
|
if (myAgentId && task.agentId !== myAgentId) {
|
|
1886
1946
|
jsonError(res, "Task belongs to another agent", 403);
|
|
1887
1947
|
return true;
|
|
@@ -1945,6 +2005,15 @@ export async function handleTasks(
|
|
|
1945
2005
|
if (updateTaskTitleRoute.match(req.method, pathSegments)) {
|
|
1946
2006
|
const parsed = await updateTaskTitleRoute.parse(req, res, pathSegments, queryParams);
|
|
1947
2007
|
if (!parsed) return true;
|
|
2008
|
+
const existing = await getTaskById(parsed.params.id);
|
|
2009
|
+
if (!existing) {
|
|
2010
|
+
jsonError(res, "Task not found", 404);
|
|
2011
|
+
return true;
|
|
2012
|
+
}
|
|
2013
|
+
if (await deniesNonOwnerTaskWrite(req, existing)) {
|
|
2014
|
+
jsonError(res, NOT_YOUR_TASK_DENIED, 403);
|
|
2015
|
+
return true;
|
|
2016
|
+
}
|
|
1948
2017
|
const task = await updateTaskTitle(parsed.params.id, parsed.body.title);
|
|
1949
2018
|
if (!task) {
|
|
1950
2019
|
jsonError(res, "Task not found", 404);
|
|
@@ -1964,6 +2033,11 @@ export async function handleTasks(
|
|
|
1964
2033
|
return true;
|
|
1965
2034
|
}
|
|
1966
2035
|
|
|
2036
|
+
if (await deniesNonOwnerTaskWrite(req, task)) {
|
|
2037
|
+
jsonError(res, NOT_YOUR_TASK_DENIED, 403);
|
|
2038
|
+
return true;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
1967
2041
|
if (myAgentId && task.agentId !== myAgentId) {
|
|
1968
2042
|
jsonError(res, "Task belongs to another agent", 403);
|
|
1969
2043
|
return true;
|
package/src/http/telemetry-ui.ts
CHANGED
|
@@ -32,7 +32,7 @@ const uiEvent = route({
|
|
|
32
32
|
401: { description: "Unauthorized" },
|
|
33
33
|
403: { description: "Guest page sessions cannot send events" },
|
|
34
34
|
},
|
|
35
|
-
rbac: {
|
|
35
|
+
rbac: { permission: "favorite.write.own" },
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
const enableTelemetry = route({
|
package/src/http/user-roles.ts
CHANGED
|
@@ -80,7 +80,10 @@ async function composeRoles(userId: string) {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/** Operator or user only; agents never change human roles, even with the shared key. */
|
|
83
|
-
async function ensureRoleManager(
|
|
83
|
+
export async function ensureRoleManager(
|
|
84
|
+
req: IncomingMessage,
|
|
85
|
+
res: ServerResponse,
|
|
86
|
+
): Promise<boolean> {
|
|
84
87
|
if (rejectGuest(req, res)) return false;
|
|
85
88
|
const auth = getRequestAuth(req);
|
|
86
89
|
if (auth?.kind !== "operator" && auth?.kind !== "user") {
|