@desplega.ai/agent-swarm 1.164.1 → 1.166.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.
- package/README.md +1 -1
- package/dist/acp-adapter-yzfxn8vj.js +23 -0
- package/dist/{actions-hp2h32dx.js → actions-qz3m692w.js} +24 -28
- package/dist/{amp-adapter-zfd7djyx.js → amp-adapter-j1xbmsqz.js} +7 -7
- package/dist/{app-w2d26h4f.js → app-43vrdmv8.js} +9 -10
- package/dist/{assistant-45pc4en7.js → assistant-ertffmka.js} +25 -29
- package/dist/{boot-reembed-k1q2s4fc.js → boot-reembed-998jtpdg.js} +12 -15
- package/dist/{boot-reembed-6rhcpsjf.js → boot-reembed-s7k7c6v2.js} +13 -15
- package/dist/boot-scrub-sweep-nepsk4t1.js +211 -0
- package/dist/{boot-seeds-ex93edx7.js → boot-seeds-vvzs1zhk.js} +12 -12
- package/dist/{claude-adapter-hcxd0szm.js → claude-adapter-2zvmekrp.js} +15 -17
- package/dist/{claude-managed-adapter-fz7xps2r.js → claude-managed-adapter-s49wbk8t.js} +5 -5
- package/dist/{claude-managed-setup-xx6f15h9.js → claude-managed-setup-cvhqq8qn.js} +4 -4
- package/dist/{claude-sdk-session-6nb9raem.js → claude-sdk-session-kkbxtw5q.js} +2624 -2606
- package/dist/{cli-etbrt8x1.js → cli-0nhdwxd5.js} +4 -4
- package/dist/{cli-jeefgppq.js → cli-0qjcsxgz.js} +7 -7
- package/dist/{cli-6behs2bt.js → cli-32bca7nr.js} +1 -1
- package/dist/{cli-gt8v96qx.js → cli-3ddybbbx.js} +4 -4
- package/dist/{acp-adapter-rxvek4ym.js → cli-3qn4r334.js} +317 -35
- package/dist/{cli-1d3w4xm3.js → cli-4r1sjfc4.js} +14 -6
- package/dist/{cli-691f2rxm.js → cli-66zh26sp.js} +68 -16
- package/dist/{cli-et8wdyqh.js → cli-68r1j4sg.js} +9 -9
- package/dist/{cli-xb7kyanp.js → cli-8kgvmkak.js} +3 -3
- package/dist/{cli-fdpkw8vk.js → cli-8t229cmr.js} +8 -8
- package/dist/{cli-gc54qc0p.js → cli-aqcey741.js} +1 -1
- package/dist/{cli-4q4cmr4t.js → cli-cpfmqz3n.js} +8 -8
- package/dist/{cli-a9bw0xxt.js → cli-df56tqdw.js} +997 -408
- package/dist/{cli-n7h1kqpf.js → cli-dmtrxqhg.js} +6 -1
- package/dist/{cli-xfb7333f.js → cli-dw2q9f7g.js} +5 -5
- package/dist/{cli-4drstbb9.js → cli-ecknp7p1.js} +81 -23
- package/dist/{cli-v0pvvhfq.js → cli-efnd2kce.js} +36 -1
- package/dist/{cli-1wetf34q.js → cli-f2n17zhp.js} +1 -1
- package/dist/{cli-2c8eky5y.js → cli-feh3dkah.js} +1 -1
- package/dist/cli-fn697bnt.js +126 -0
- package/dist/{cli-v5pr2fgt.js → cli-gt8azyet.js} +3 -3
- package/dist/{cli-dbszf3rw.js → cli-h3x613ze.js} +4 -4
- package/dist/{cli-nwhb8y2e.js → cli-hf5s9pgf.js} +1 -1
- package/dist/cli-j2jbr8af.js +516 -0
- package/dist/{cli-agjzafns.js → cli-jhm6hzjn.js} +593 -10
- package/dist/{cli-j0tmc908.js → cli-jvj6a0cv.js} +484 -477
- package/dist/{cli-xxz89c2n.js → cli-mb75wpxf.js} +1 -1
- package/dist/{cli-07s39g1n.js → cli-mv2520nm.js} +1 -1
- package/dist/{cli-v90vfwyb.js → cli-mwegs4af.js} +5 -5
- package/dist/{cli-bz1gbac9.js → cli-p4ztb80h.js} +2 -2
- package/dist/{cli-1wd1n2ya.js → cli-rfphkzh5.js} +1 -1
- package/dist/{cli-976r1zqx.js → cli-rggdq8wq.js} +5 -5
- package/dist/{cli-3ajw5v5v.js → cli-rsy933yz.js} +6 -6
- package/dist/{cli-yj790e19.js → cli-tadfgd0t.js} +8 -1
- package/dist/{cli-cn53e7vc.js → cli-ttbsse3f.js} +6 -1
- package/dist/{cli-dyqsrqcf.js → cli-v2a8x45d.js} +4 -4
- package/dist/{cli-wbvnn6tk.js → cli-v6vv7dy8.js} +91 -9
- package/dist/{cli-z2ap2c0c.js → cli-vzc73wet.js} +90 -55
- package/dist/cli-wt7ccy4r.js +2654 -0
- package/dist/{cli-4cn19jvn.js → cli-x7kpr72a.js} +3 -3
- package/dist/{cli-003785v9.js → cli-xvc3q9br.js} +1 -1
- package/dist/{cli-v0e7jpr5.js → cli-xvdgasgy.js} +13 -4
- package/dist/{cli-asqeg4ve.js → cli-y59h2pk9.js} +2 -2
- package/dist/{cli-0wn3ypqv.js → cli-yshaazs1.js} +14121 -3478
- package/dist/{cli-wg8yjqtw.js → cli-ysnyhws9.js} +16 -3
- package/dist/cli-zp67qg5x.js +92 -0
- package/dist/{cli-g3qgrzck.js → cli-zsh093hk.js} +71 -3
- package/dist/{cli-ma3zvh39.js → cli-zy7vwsne.js} +6066 -5829
- package/dist/cli.js +79 -26
- package/dist/{codex-adapter-pcxdn10v.js → codex-adapter-dw1wxqt8.js} +10 -10
- package/dist/{codex-hook-b1fb7c2k.js → codex-hook-d2rkvf39.js} +1 -1
- package/dist/{codex-login-059nm145.js → codex-login-terbdsqq.js} +2 -2
- package/dist/{codex-session-runner-xzwwddp8.js → codex-session-runner-3cgb8y1g.js} +10 -10
- package/dist/{commands-98at8mkn.js → commands-mhxam6z2.js} +9 -9
- package/dist/{cursor-adapter-dkg6qnkp.js → cursor-adapter-2qda3st7.js} +6 -6
- package/dist/{db-01g8wtvw.js → db-sjks418k.js} +11 -9
- package/dist/{devin-adapter-qmttt2fz.js → devin-adapter-bffjj5n4.js} +2 -2
- package/dist/{dispatcher-nn2k1wxd.js → dispatcher-1es759rn.js} +22 -26
- package/dist/{dsh-adapter-w4d4vwdq.js → dsh-adapter-bek4cyw9.js} +6 -6
- package/dist/{e2b-9e4g2hvt.js → e2b-nd50eccg.js} +1 -1
- package/dist/{event-bus-z7v2t26e.js → event-bus-vnfthafg.js} +2 -2
- package/dist/grok-adapter-ar9cw9jg.js +29 -0
- package/dist/{handlers-b0kqsbg8.js → handlers-1gkbhktr.js} +25 -29
- package/dist/{hook-sap7v1aj.js → hook-ds2zxq9v.js} +16 -18
- package/dist/{hook-pz50gqep.js → hook-vxa3tcsy.js} +10 -12
- package/dist/{http-ncr8rmd0.js → http-3h21z9md.js} +679 -227
- package/dist/{index-c4aqcyz1.js → index-9b65j1m5.js} +11 -11
- package/dist/{index-r46s01nq.js → index-bn6cy8ps.js} +22 -26
- package/dist/{index-38kqdt3e.js → index-dkfxpkmm.js} +23 -27
- package/dist/{index-630kj5vd.js → index-f8xnqrye.js} +55 -43
- package/dist/{index-fdk1t4d6.js → index-n0rxa4ca.js} +11962 -9900
- package/dist/{index-9nrj7797.js → index-n99fycq7.js} +22 -26
- package/dist/{keepalive-31613r2h.js → keepalive-3xspa9jw.js} +14 -11
- package/dist/{lead-mx59tr5s.js → lead-6qphc124.js} +43 -43
- package/dist/{maintenance-55ff39ca.js → maintenance-0teem1bb.js} +10 -12
- package/dist/{node-f0ykebbv.js → node-9sg7ajby.js} +25 -7
- package/dist/{oauth-refresh-sweep-anma954w.js → oauth-refresh-sweep-sh9q25xp.js} +13 -10
- package/dist/{onboard-b2fy8ftb.js → onboard-54qmnqxe.js} +4 -3
- package/dist/{opencode-adapter-p1s92tmy.js → opencode-adapter-wjfa2wvd.js} +6 -6
- package/dist/{otel-impl-9brvt7xv.js → otel-impl-ycqzp2a1.js} +2 -2
- package/dist/{pi-mono-adapter-kz4rrwvd.js → pi-mono-adapter-e77e9zst.js} +6 -6
- package/dist/{pricing-refresh-7w8mbmva.js → pricing-refresh-atnkngqs.js} +10 -10
- package/dist/{rbac-roles-ejp7qwvb.js → rbac-roles-9pjphh9q.js} +10 -10
- package/dist/{rbac-roles-nhk4r7bc.js → rbac-roles-j78wdksm.js} +10 -10
- package/dist/{render-v2-2gzt8skq.js → render-v2-pxjs49fx.js} +9 -10
- package/dist/{setup-5et8t412.js → setup-ymej0xtx.js} +2 -2
- package/dist/{work-objects-tb0er7qa.js → work-objects-3nh4ymzb.js} +26 -30
- package/dist/{worker-62cv075d.js → worker-qa9fkz5s.js} +43 -43
- package/dist/{x-vbxb31jr.js → x-ma4gnfgy.js} +2 -2
- package/openapi.json +457 -31
- package/package.json +14 -6
- package/plugin/commands/create-pr.md +7 -1
- package/plugin/pi-skills/create-pr/SKILL.md +7 -1
- package/src/agentmail/app.ts +5 -4
- package/src/be/automation-preflight.ts +11 -9
- package/src/be/boot-scrub-sweep.ts +302 -0
- package/src/be/connector-codes.ts +81 -0
- package/src/be/crypto/key-bootstrap.ts +1 -1
- package/src/be/db/approvals.ts +15 -1
- package/src/be/db/codex-oauth-device-flows.ts +40 -0
- package/src/be/db/config-secrets.ts +31 -0
- package/src/be/db/runtime.ts +4 -0
- package/src/be/db/script-runs.ts +15 -0
- package/src/be/db/tasks/write.ts +1 -1
- package/src/be/db-queries/mcp-oauth.ts +5 -0
- package/src/be/db-queries/oauth.ts +77 -0
- package/src/be/db.ts +162 -59
- package/src/be/events.ts +17 -1
- package/src/be/memory/index-content.ts +2 -2
- package/src/be/memory/providers/sqlite-store.ts +63 -11
- package/src/be/memory/types.ts +14 -0
- package/src/be/migrations/197_connector_codes.sql +23 -0
- package/src/be/migrations/198_permission_audit_guest.sql +33 -0
- package/src/be/migrations/200_backfill_auto_memory_expiry.sql +20 -0
- package/src/be/migrations/201_workflow_replay_columns.sql +10 -0
- package/src/be/migrations/202_codex_oauth_device_flows.sql +24 -0
- package/src/be/model-tier-resolution.ts +2 -1
- package/src/be/model-validation.ts +1 -1
- package/src/be/pricing-normalize.ts +3 -0
- package/src/be/rbac-audit.ts +2 -1
- package/src/be/scripts/db.ts +28 -4
- package/src/be/scripts/source-secrets.ts +37 -0
- package/src/be/scripts/typecheck.ts +23 -2
- package/src/be/scrub-json.ts +32 -0
- package/src/be/sealed-json.ts +59 -0
- package/src/be/secret-registry.ts +131 -0
- package/src/be/seed-pricing.ts +14 -0
- package/src/be/users.ts +7 -1
- package/src/be/workflow-replay.ts +77 -0
- package/src/cli.tsx +7 -0
- package/src/commands/provider-credentials.ts +46 -8
- package/src/commands/runner.ts +2 -10
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/github/app.ts +4 -4
- package/src/heartbeat/heartbeat.ts +20 -8
- package/src/hooks/pr-body-guard.ts +1 -1
- package/src/http/agents.ts +1 -0
- package/src/http/approval-requests.ts +1 -0
- package/src/http/apps.ts +3 -0
- package/src/http/auth.ts +4 -1
- package/src/http/codex-oauth-device.ts +8 -10
- package/src/http/codex-oauth-keep-warm.ts +2 -2
- package/src/http/config-values.ts +59 -0
- package/src/http/config.ts +5 -0
- package/src/http/db-query-bounded.ts +3 -0
- package/src/http/db-query-shared.ts +107 -15
- package/src/http/db-query.ts +10 -2
- package/src/http/extensions.ts +1 -0
- package/src/http/index.ts +23 -6
- package/src/http/integrations.ts +1 -38
- package/src/http/ip-rate-limit.ts +82 -0
- package/src/http/kv.ts +38 -4
- package/src/http/mcp-servers.ts +1 -0
- package/src/http/memory.ts +9 -0
- package/src/http/models-catalog.ts +2 -0
- package/src/http/operator-actor.ts +4 -0
- package/src/http/page-proxy.ts +22 -0
- package/src/http/pages.ts +4 -2
- package/src/http/realtime.ts +1 -1
- package/src/http/request-principal.ts +14 -1
- package/src/http/script-connections.ts +8 -0
- package/src/http/script-runs.ts +12 -4
- package/src/http/scripts.ts +15 -0
- package/src/http/session-cost-recompute.ts +3 -2
- package/src/http/tasks.ts +9 -0
- package/src/http/users.ts +226 -0
- package/src/http/workflows.ts +3 -2
- package/src/http.ts +1 -0
- package/src/integrations/kapso/client.ts +3 -1
- package/src/jira/app.ts +2 -2
- package/src/kv-view.ts +324 -0
- package/src/linear/app.ts +2 -2
- package/src/oauth/mcp-wrapper.ts +1 -1
- package/src/prompts/memories.ts +42 -1
- package/src/providers/acp-adapter.ts +85 -24
- package/src/providers/acp-target-catalog.ts +54 -1
- package/src/providers/acp-targets.ts +358 -4
- package/src/providers/amp-adapter.ts +1 -1
- package/src/providers/cursor-adapter.ts +1 -1
- package/src/providers/grok-adapter.ts +186 -0
- package/src/providers/index.ts +5 -1
- package/src/providers/pricing-sources.md +6 -0
- package/src/providers/reasoning-effort.ts +17 -1
- package/src/providers/types.ts +2 -1
- package/src/rbac/can.ts +4 -3
- package/src/rbac/legacy-policy.ts +3 -3
- package/src/rbac/types.ts +6 -0
- package/src/script-workflows/supervisor.ts +11 -2
- package/src/scripts-runtime/eval-harness.ts +2 -12
- package/src/scripts-runtime/executors/quickjs-bundle.ts +152 -0
- package/src/scripts-runtime/executors/quickjs-prelude.ts +285 -0
- package/src/scripts-runtime/executors/quickjs-runner.ts +580 -0
- package/src/scripts-runtime/executors/quickjs-worker.ts +81 -0
- package/src/scripts-runtime/executors/quickjs.ts +196 -0
- package/src/scripts-runtime/executors/registry.ts +2 -0
- package/src/scripts-runtime/executors/sourcemap.ts +79 -0
- package/src/scripts-runtime/script-error-hints.ts +14 -0
- package/src/scripts-runtime/swarm-sdk.ts +9 -2
- package/src/scripts-runtime/types/stdlib.d.ts +27 -8
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +27 -8
- package/src/server-user.ts +2 -20
- package/src/server.ts +3 -1
- package/src/slack/app.ts +4 -0
- package/src/slack/config.ts +3 -1
- package/src/slack/egress-scrub.ts +87 -0
- package/src/tests/acp-adapter.test.ts +191 -2
- package/src/tests/boot-scrub-sweep.test.ts +390 -0
- package/src/tests/budget-user-scope.test.ts +7 -21
- package/src/tests/check-pr-body.test.ts +149 -6
- package/src/tests/check-text-columns.test.ts +145 -0
- package/src/tests/claude-adapter-binary.test.ts +1 -1
- package/src/tests/claude-sdk-process.fixture.ts +13 -2
- package/src/tests/codex-oauth-device.test.ts +23 -37
- package/src/tests/codex-oauth-keep-warm.test.ts +29 -0
- package/src/tests/console-scrub.test.ts +141 -0
- package/src/tests/credential-check.test.ts +90 -0
- package/src/tests/db-query-denylist.test.ts +202 -0
- package/src/tests/db-task-read-contract.test.ts +1 -0
- package/src/tests/db-task-write-contract.test.ts +1 -0
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/entrypoint-acp-target-binary.test.ts +44 -1
- package/src/tests/events-scrub.test.ts +88 -0
- package/src/tests/explicit-model-validation.test.ts +81 -0
- package/src/tests/extensions-pre-task.test.ts +33 -1
- package/src/tests/fixtures/grok/acp-updates-recorded.jsonl +53 -0
- package/src/tests/fixtures/grok/prompt-response-meta.json +36 -0
- package/src/tests/fixtures/secret-corpus.ts +320 -0
- package/src/tests/grok-adapter.test.ts +647 -0
- package/src/tests/heartbeat-checklist.test.ts +44 -0
- package/src/tests/integration-disable-flags.test.ts +156 -0
- package/src/tests/kv-http.test.ts +34 -0
- package/src/tests/kv-tool.test.ts +274 -1
- package/src/tests/kv-view.test.ts +147 -0
- package/src/tests/mcp-user-route.test.ts +257 -15
- package/src/tests/memory-injection-outcome.test.ts +143 -0
- package/src/tests/model-tier-resolution.test.ts +76 -3
- package/src/tests/page-guest-session.test.ts +424 -0
- package/src/tests/page-proxy.test.ts +1 -1
- package/src/tests/page-viewer-auth.test.ts +22 -1
- package/src/tests/pr-body-leaks.test.ts +157 -2
- package/src/tests/preload.ts +10 -0
- package/src/tests/provider-registration.test.ts +3 -1
- package/src/tests/rbac-audit.test.ts +32 -0
- package/src/tests/rbac-mcp-admission-e2e.test.ts +4 -62
- package/src/tests/script-connections.test.ts +9 -0
- package/src/tests/script-executor-conformance.test.ts +3 -0
- package/src/tests/script-executor-quickjs.test.ts +442 -0
- package/src/tests/script-executor-registry.test.ts +6 -1
- package/src/tests/script-runs-http.test.ts +126 -1
- package/src/tests/script-runs-scrub.test.ts +275 -0
- package/src/tests/scripts-http.test.ts +82 -1
- package/src/tests/scripts-mcp-e2e.test.ts +42 -6
- package/src/tests/scripts-runtime.test.ts +37 -0
- package/src/tests/scrubbed-text-12e.test.ts +289 -0
- package/src/tests/sealed-key-guard.test.ts +166 -0
- package/src/tests/secret-canary-sweep.test.ts +958 -0
- package/src/tests/secret-registry.test.ts +355 -0
- package/src/tests/secret-rules.test.ts +230 -0
- package/src/tests/secret-scrubber.test.ts +317 -1
- package/src/tests/session-costs-golden.test.ts +17 -0
- package/src/tests/slack-egress-scrub.test.ts +216 -0
- package/src/tests/swarm-tool-result-gate.test.ts +143 -30
- package/src/tests/task-tools-ctx.test.ts +3 -0
- package/src/tests/user-token-routes.test.ts +342 -3
- package/src/tests/workflow-replay.test.ts +518 -0
- package/src/tests/workflow-scrub.test.ts +242 -0
- package/src/tests/workflow-system-one-decision-providers.test.ts +737 -0
- package/src/tools/db-query.ts +1 -1
- package/src/tools/inject-learning.ts +1 -1
- package/src/tools/kv/kv-get.ts +136 -6
- package/src/tools/send-task.ts +61 -17
- package/src/tools/utils.ts +186 -43
- package/src/tools/workflows/get-workflow-run.ts +3 -2
- package/src/types.ts +16 -1
- package/src/utils/console-scrub-install.ts +5 -0
- package/src/utils/console-scrub.ts +57 -0
- package/src/utils/credentials.ts +8 -0
- package/src/utils/page-session.ts +6 -2
- package/src/utils/pr-body-leaks.ts +149 -10
- package/src/utils/request-auth-context.ts +2 -0
- package/src/utils/secret-rules.generated.ts +2055 -0
- package/src/utils/secret-scrubber.ts +662 -36
- package/src/workflows/engine.ts +39 -4
- package/src/workflows/executors/notify.ts +6 -1
- package/src/workflows/executors/system-one-decision.ts +31 -12
- package/src/workflows/executors/system-one-openai-wire.ts +168 -0
- package/src/workflows/executors/system-one-providers.ts +112 -11
- package/src/workflows/executors/system-one-wire.ts +79 -0
- package/src/workflows/recovery.ts +10 -1
- package/src/workflows/resume.ts +62 -3
- package/src/workflows/retry-poller.ts +3 -0
- package/templates/ai-toolbox.manifest.json +2 -2
- package/templates/skills/agent-browser/SKILL.md +5 -5
- package/templates/skills/agent-browser/config.json +1 -1
- package/templates/skills/agent-browser/content.md +4 -4
- package/templates/skills/artifacts/content.md +17 -7
- package/templates/skills/jira-interaction/config.json +1 -1
- package/templates/skills/jira-interaction/content.md +56 -205
- package/templates/skills/linear-interaction/config.json +1 -1
- package/templates/skills/linear-interaction/content.md +31 -50
- package/templates/skills/pages/content.md +8 -4
- package/templates/skills/qa/content.md +2 -2
- package/templates/skills/workflow-iterate/content.md +4 -4
- package/tsconfig.json +3 -3
- package/dist/boot-scrub-logs-t8xg7wd7.js +0 -99
- package/dist/cli-0a7r5331.js +0 -168
- package/dist/cli-93rxw9yd.js +0 -951
- package/dist/cli-cvk6yzw5.js +0 -40
- package/dist/cli-dgnj0zcc.js +0 -40
- package/dist/cli-qt5wzq6v.js +0 -256
- package/dist/cli-v7fqehqd.js +0 -9281
- package/dist/cli-vbr859rz.js +0 -572
- package/src/be/boot-scrub-logs.ts +0 -132
|
@@ -21,6 +21,13 @@
|
|
|
21
21
|
* label and a commit SHA. Only "swarm run", "workflow run" or "run id"
|
|
22
22
|
* followed by a hex id counts. Cost: "run <id>" alone passes.
|
|
23
23
|
* Every other category is checked everywhere, fences included.
|
|
24
|
+
*
|
|
25
|
+
* Swarm provenance: a `## Swarm provenance` section may carry the auth-gated
|
|
26
|
+
* links a maintainer uses to backtrack (task and session links, durable
|
|
27
|
+
* agent-fs paths, the Slack permalink of the ask). Inside that section only,
|
|
28
|
+
* `PROVENANCE_ALLOWED` categories pass, and a Slack permalink's embedded
|
|
29
|
+
* channel id and ts do not count. Bare Slack ids, ts values and private-chat
|
|
30
|
+
* quotes stay blocked there too.
|
|
24
31
|
*/
|
|
25
32
|
|
|
26
33
|
export type LeakCategory =
|
|
@@ -144,27 +151,159 @@ const PLACEHOLDER_UUIDS = new RegExp(
|
|
|
144
151
|
"gi",
|
|
145
152
|
);
|
|
146
153
|
|
|
147
|
-
/**
|
|
148
|
-
const
|
|
154
|
+
/** The section heading under which auth-gated provenance links are allowed. */
|
|
155
|
+
export const PROVENANCE_HEADING = "Swarm provenance";
|
|
149
156
|
|
|
150
|
-
/**
|
|
151
|
-
export
|
|
152
|
-
|
|
153
|
-
|
|
157
|
+
/** Categories allowed inside the provenance section. Everything else stays blocked there too. */
|
|
158
|
+
export const PROVENANCE_ALLOWED: ReadonlySet<LeakCategory> = new Set<LeakCategory>([
|
|
159
|
+
"slack-link",
|
|
160
|
+
"swarm-dashboard-link",
|
|
161
|
+
"agent-fs-link",
|
|
162
|
+
"swarm-task-ref",
|
|
163
|
+
"agent-fs-path",
|
|
164
|
+
]);
|
|
165
|
+
|
|
166
|
+
/** A whole Slack permalink, query string included (`?thread_ts=...`). */
|
|
167
|
+
const SLACK_URL = /https?:\/\/[^\s)"'<>]*slack\.com\/(?:archives|client)\/[^\s)"'<>]*/gi;
|
|
168
|
+
|
|
169
|
+
// CommonMark 0.31.2 §4.5: a fence line starts at most 3 columns in, and a tab
|
|
170
|
+
// expands to the next multiple of 4, so a line with a leading tab is too deep.
|
|
171
|
+
// Only ASCII space and tab count as whitespace here (§2.1); JS `\s` and
|
|
172
|
+
// `trim()` also match U+00A0 and other Unicode spaces, which GitHub treats as text.
|
|
173
|
+
const HEADING = /^#{1,2}[ \t]+(.+?)(?:[ \t]+#+)?[ \t]*$/;
|
|
174
|
+
const FENCE_LINE = /^( {0,3})(`{3,}|~{3,})(.*)$/;
|
|
175
|
+
const COMMENT_OPEN = /^[ \t]*<!--/;
|
|
176
|
+
const BLANK = /^[ \t]*$/;
|
|
177
|
+
|
|
178
|
+
export type MarkdownLine = {
|
|
179
|
+
line: string;
|
|
180
|
+
/** Text of the level-1/level-2 heading this line starts, else null. */
|
|
181
|
+
heading: string | null;
|
|
182
|
+
/** True for a fence line or a line inside a fenced code block. */
|
|
183
|
+
code: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* True once a fence closed on a line less indented than its opener. The
|
|
186
|
+
* opener may sit in a list item, where that line ends the item and opens a
|
|
187
|
+
* new fence instead, so GitHub can read the rest of the body differently.
|
|
188
|
+
*/
|
|
189
|
+
ambiguous: boolean;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Each line of `markdown`, read the way GitHub renders it at the top level.
|
|
194
|
+
* Headings inside fenced code blocks and HTML comment blocks do not count.
|
|
195
|
+
* A fence opens or closes only on a line indented at most 3 columns; it closes
|
|
196
|
+
* on the same character, at least as long as the opener, with no info string.
|
|
197
|
+
* An unclosed fence runs to the end. Inside an ambiguous span no line counts
|
|
198
|
+
* as code, so prose checks still see it.
|
|
199
|
+
* Shared with `scripts/check-pr-body.ts` so both read sections the same way.
|
|
200
|
+
*/
|
|
201
|
+
export function markdownHeadings(markdown: string): MarkdownLine[] {
|
|
202
|
+
const out: MarkdownLine[] = [];
|
|
203
|
+
let fence: { char: string; length: number; indent: number } | null = null;
|
|
204
|
+
let inComment = false;
|
|
205
|
+
let ambiguous = false;
|
|
206
|
+
for (const line of markdown.replace(/\r\n/g, "\n").split("\n")) {
|
|
207
|
+
const fenceLine = FENCE_LINE.exec(line);
|
|
208
|
+
const indent = fenceLine?.[1]?.length ?? 0;
|
|
209
|
+
const run = fenceLine?.[2] ?? "";
|
|
210
|
+
const info = fenceLine?.[3] ?? "";
|
|
211
|
+
let heading: string | null = null;
|
|
212
|
+
let code = false;
|
|
213
|
+
if (fence) {
|
|
214
|
+
code = true;
|
|
215
|
+
if (run[0] === fence.char && run.length >= fence.length && BLANK.test(info)) {
|
|
216
|
+
if (indent < fence.indent) ambiguous = true;
|
|
217
|
+
fence = null;
|
|
218
|
+
}
|
|
219
|
+
} else if (inComment) {
|
|
220
|
+
if (line.includes("-->")) inComment = false;
|
|
221
|
+
} else if (fenceLine && !(run[0] === "`" && info.includes("`"))) {
|
|
222
|
+
fence = { char: run[0] ?? "`", length: run.length, indent };
|
|
223
|
+
code = true;
|
|
224
|
+
} else if (COMMENT_OPEN.test(line)) {
|
|
225
|
+
inComment = !line.slice(line.indexOf("<!--") + 4).includes("-->");
|
|
226
|
+
} else {
|
|
227
|
+
heading = HEADING.exec(line)?.[1] ?? null;
|
|
228
|
+
}
|
|
229
|
+
out.push({ line, heading, code: code && !ambiguous, ambiguous });
|
|
230
|
+
}
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** `markdown` with every fenced code block collapsed to one placeholder line. */
|
|
235
|
+
export function stripFencedCode(markdown: string, placeholder = "<code-block>"): string {
|
|
236
|
+
const out: string[] = [];
|
|
237
|
+
let wasCode = false;
|
|
238
|
+
for (const { line, code } of markdownHeadings(markdown)) {
|
|
239
|
+
if (!code) out.push(line);
|
|
240
|
+
else if (!wasCode && placeholder) out.push(placeholder);
|
|
241
|
+
wasCode = code;
|
|
242
|
+
}
|
|
243
|
+
return out.join("\n");
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const isProvenanceHeading = (raw: string) =>
|
|
247
|
+
raw
|
|
248
|
+
.replace(/<!--[\s\S]*?-->/g, "")
|
|
249
|
+
.replace(/^[ \t]+|[ \t]+$/g, "")
|
|
250
|
+
.replace(/[ \t]+/g, " ")
|
|
251
|
+
.toLowerCase() === PROVENANCE_HEADING.toLowerCase();
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* A line GitHub might render as a level-1/level-2 heading in some context: an
|
|
255
|
+
* ATX heading at any indent or behind list or quote markers, or a setext
|
|
256
|
+
* underline. Fence and comment state are ignored on purpose.
|
|
257
|
+
*/
|
|
258
|
+
const MAYBE_HEADING =
|
|
259
|
+
/^[ \t]*(?:(?:[-*+>]|\d{1,9}[.)])[ \t]*)*(?:#{1,2}(?:[ \t]|$)|(?:=+|-+)[ \t]*$)/;
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Split a body into the `## Swarm provenance` section(s) and everything else.
|
|
263
|
+
* Fails closed both ways. A section opens only on a heading `markdownHeadings`
|
|
264
|
+
* reads at the top level, outside an ambiguous span. It ends on any line that
|
|
265
|
+
* might render as a level-1/level-2 heading, even one the parser reads as
|
|
266
|
+
* fenced or commented out.
|
|
267
|
+
*/
|
|
268
|
+
export function splitProvenance(body: string): { outside: string; provenance: string } {
|
|
269
|
+
const outside: string[] = [];
|
|
270
|
+
const provenance: string[] = [];
|
|
271
|
+
let inProvenance = false;
|
|
272
|
+
for (const { line, heading, ambiguous } of markdownHeadings(body)) {
|
|
273
|
+
if (heading !== null && !ambiguous && isProvenanceHeading(heading)) inProvenance = true;
|
|
274
|
+
else if (heading !== null || MAYBE_HEADING.test(line)) inProvenance = false;
|
|
275
|
+
(inProvenance ? provenance : outside).push(line);
|
|
276
|
+
}
|
|
277
|
+
return { outside: outside.join("\n"), provenance: provenance.join("\n") };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function scan(text: string, skip: ReadonlySet<LeakCategory>, found: LeakCategory[]) {
|
|
281
|
+
const clean = text
|
|
154
282
|
.replace(PRESIGNED_URL, "<presigned-url>")
|
|
155
283
|
.replace(PLACEHOLDER_UUIDS, "<placeholder-uuid>");
|
|
156
|
-
const prose =
|
|
157
|
-
const found: LeakCategory[] = [];
|
|
284
|
+
const prose = stripFencedCode(clean);
|
|
158
285
|
for (const rule of LEAK_RULES) {
|
|
159
286
|
if (
|
|
160
287
|
rule.enabled &&
|
|
288
|
+
!skip.has(rule.category) &&
|
|
161
289
|
!found.includes(rule.category) &&
|
|
162
|
-
rule.pattern.test(rule.proseOnly ? prose :
|
|
290
|
+
rule.pattern.test(rule.proseOnly ? prose : clean)
|
|
163
291
|
) {
|
|
164
292
|
found.push(rule.category);
|
|
165
293
|
}
|
|
166
294
|
}
|
|
167
|
-
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/** Returns the distinct leak categories found in `body`, in rule order. Empty means clean. */
|
|
298
|
+
export function findPrBodyLeaks(body: string): LeakCategory[] {
|
|
299
|
+
const { outside, provenance } = splitProvenance(body);
|
|
300
|
+
const found: LeakCategory[] = [];
|
|
301
|
+
scan(outside, new Set(), found);
|
|
302
|
+
// A permalink carries a channel id and a message ts; allowed here, so drop it whole.
|
|
303
|
+
scan(provenance.replace(SLACK_URL, "<slack-permalink>"), PROVENANCE_ALLOWED, found);
|
|
304
|
+
return LEAK_RULES.map((r) => r.category).filter(
|
|
305
|
+
(c, i, all) => found.includes(c) && all.indexOf(c) === i,
|
|
306
|
+
);
|
|
168
307
|
}
|
|
169
308
|
|
|
170
309
|
/** GitHub logins whose PR bodies get the leak check in CI. */
|
|
@@ -5,6 +5,8 @@ import type { User } from "../types";
|
|
|
5
5
|
export type HttpRequestAuth = (
|
|
6
6
|
| { kind: "operator"; fingerprint: string }
|
|
7
7
|
| { kind: "user"; userId: string; user: User }
|
|
8
|
+
/** Password-page viewer with no user identity. Least privilege: every gate denies it. */
|
|
9
|
+
| { kind: "guest" }
|
|
8
10
|
/** Ephemeral session token minted by the ACP adapter per session (aseph_ prefix). */
|
|
9
11
|
| { kind: "agent"; agentId: string; taskId: string }
|
|
10
12
|
) & {
|