@desplega.ai/agent-swarm 1.149.1 → 1.151.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 +18 -3
- package/dist/{acp-adapter-vhkzfpjg.js → acp-adapter-ex8hzjfc.js} +5 -5
- package/dist/{actions-9d2694yk.js → actions-2bgpyhww.js} +39 -11
- package/dist/{app-fq2ggynt.js → app-1706zhr1.js} +7 -7
- package/dist/{artifact-gj9arwrr.js → artifact-td4q4dch.js} +1 -1
- package/dist/{assistant-edb6n9nn.js → assistant-bavke5p7.js} +44 -20
- package/dist/{azure-openai-responses-cqar64rc.js → azure-openai-responses-f38x2avq.js} +13 -13
- package/dist/{boot-reembed-msweabbp.js → boot-reembed-3cmrrmpa.js} +9 -9
- package/dist/{boot-reembed-q5wd3tha.js → boot-reembed-nafcmmmc.js} +14 -16
- package/dist/{boot-scrub-logs-3g1az933.js → boot-scrub-logs-cd6a2sq0.js} +5 -5
- package/dist/{claude-adapter-v3rnzsdc.js → claude-adapter-wfp2gzvz.js} +15 -16
- package/dist/{claude-managed-adapter-qvsmh6mv.js → claude-managed-adapter-dsmkcrjy.js} +3 -3
- package/dist/{claude-sdk-session-qxrpsna1.js → claude-sdk-session-bht9jjak.js} +15 -16
- package/dist/{cli-5m0qmvdp.js → cli-0qb1z6s2.js} +1 -1
- package/dist/{cli-9d8ntetj.js → cli-2658f6at.js} +1 -1
- package/dist/{cli-7evafqvy.js → cli-2tbvf1z1.js} +85 -69
- package/dist/{cli-k351hv5k.js → cli-3v9xhjcn.js} +24 -12
- package/dist/{cli-1ebpar1q.js → cli-4wppfkcm.js} +350 -20
- package/dist/{cli-4260r1tg.js → cli-5jd2z7av.js} +97 -84
- package/dist/{cli-cv7s5zdq.js → cli-5tpgq60f.js} +9865 -715
- package/dist/{cli-6skz3rk8.js → cli-7tgcstn2.js} +9 -4
- package/dist/{cli-01g3x1ca.js → cli-9004vfdf.js} +108 -56
- package/dist/{cli-1c94wvcw.js → cli-a1z3h107.js} +124 -99
- package/dist/{cli-9br8ypfv.js → cli-czjtgfys.js} +2 -2
- package/dist/{cli-5my3bjsd.js → cli-d3p82erb.js} +7 -7
- package/dist/{cli-e29gmdmw.js → cli-dv6cdjs2.js} +2 -1
- package/dist/{cli-wby1xnnb.js → cli-f1wky6zp.js} +1 -1
- package/dist/{cli-zvz62chv.js → cli-fm4ytsdk.js} +4 -4
- package/dist/{cli-tg8qj8ee.js → cli-frcta2w4.js} +6 -6
- package/dist/{cli-7xx10h0a.js → cli-g69fdc9g.js} +2 -2
- package/dist/{cli-cmp8g3sw.js → cli-gbfwcd3k.js} +44 -9
- package/dist/{handlers-nsg0bcye.js → cli-gjyvhmmh.js} +97 -45
- package/dist/{cli-08b07b4r.js → cli-ht5rs63n.js} +1 -1
- package/dist/{cli-jecc01cb.js → cli-j4nv2wqy.js} +2 -4
- package/dist/{cli-cd60fv6j.js → cli-j9xczhaq.js} +1 -1
- package/dist/cli-pf9q3696.js +172 -0
- package/dist/{cli-xm87hzbw.js → cli-pgj4a5fb.js} +1 -1
- package/dist/{cli-jezx9b9c.js → cli-ppm4975n.js} +9 -3
- package/dist/{cli-3z634pqe.js → cli-q88st9aj.js} +2 -2
- package/dist/{cli-3sysyjve.js → cli-r2q6pevn.js} +142 -49
- package/dist/{cli-07jd68a1.js → cli-re8z5p8p.js} +1 -1
- package/dist/{cli-qgd4sqz5.js → cli-s14agm5s.js} +121 -14
- package/dist/{cli-svbrpf5q.js → cli-sjaae6ff.js} +9872 -424
- package/dist/{cli-73gq0zxn.js → cli-vwm416m6.js} +13 -13
- package/dist/{cli-4wtq5jjv.js → cli-wbyk465z.js} +1 -1
- package/dist/{cli-3apbzgyk.js → cli-z61ykvam.js} +19 -14
- package/dist/{cli-e06a8a7y.js → cli-zkxymas5.js} +4 -3
- package/dist/cli.js +26 -25
- package/dist/{codex-adapter-jyw7a91z.js → codex-adapter-jjjk8w4m.js} +8 -9
- package/dist/{codex-hook-hfrt9shr.js → codex-hook-8jexc34x.js} +3 -3
- package/dist/{codex-session-runner-bmngj0s5.js → codex-session-runner-nd6ayxkx.js} +8 -9
- package/dist/{commands-n755g391.js → commands-9v4psyq1.js} +5 -5
- package/dist/{db-s1cgh5gv.js → db-wnt58tpe.js} +5 -5
- package/dist/dispatcher-05jh1aqk.js +74 -0
- package/dist/{e2b-p04vmtx0.js → e2b-413b8t4v.js} +1 -1
- package/dist/{google-generative-ai-tsskx7te.js → google-generative-ai-ndjmj5fa.js} +7 -7
- package/dist/{google-vertex-ppw8ydpa.js → google-vertex-fr665tqs.js} +10 -10
- package/dist/handlers-tw90pkh5.js +65 -0
- package/dist/{hook-jf0xe8zh.js → hook-123e2scb.js} +11 -12
- package/dist/{hook-h9cqrm8q.js → hook-sxe3r349.js} +11 -12
- package/dist/{http-nc6pydw5.js → http-ecsar8ez.js} +1442 -581
- package/dist/{index-ezxkds2n.js → index-16js521z.js} +335 -107
- package/dist/{index-769nc012.js → index-hw26vj40.js} +25 -19
- package/dist/{index-0wdy6gwc.js → index-nnrbpcjp.js} +25 -17
- package/dist/index-ymn7em0p.js +25 -0
- package/dist/{index-x1zcj09z.js → index-zj518gf9.js} +26 -20
- package/dist/{keepalive-nesm3xb6.js → keepalive-asqtcm4y.js} +7 -7
- package/dist/{lead-bwy6t2za.js → lead-xbfr7fvt.js} +40 -48
- package/dist/{maintenance-8w393zf0.js → maintenance-qma55qvw.js} +9 -9
- package/dist/{oauth-refresh-sweep-sh8xjy08.js → oauth-refresh-sweep-3s04c6qw.js} +6 -6
- package/dist/{onboard-25ps29h1.js → onboard-drskd386.js} +13 -4
- package/dist/{openai-codex-responses-g7w48y30.js → openai-codex-responses-wy6a43wd.js} +13 -13
- package/dist/{openai-responses-nmeyptke.js → openai-responses-6xwf7bzg.js} +19 -19
- package/dist/{opencode-adapter-dce4wskd.js → opencode-adapter-28axqa09.js} +4 -4
- package/dist/{otel-impl-b93gxnz5.js → otel-impl-943c96er.js} +1 -1
- package/dist/{pi-mono-adapter-zvshk5cj.js → pi-mono-adapter-jcqt71cg.js} +17 -19
- package/dist/{pricing-refresh-5v56x7gb.js → pricing-refresh-mx51az05.js} +7 -7
- package/dist/{rbac-roles-x55cnezn.js → rbac-roles-78baecqd.js} +13 -9
- package/dist/{rbac-roles-0p0s6pbj.js → rbac-roles-wcmrg6sv.js} +7 -7
- package/dist/{render-v2-hyd45w8b.js → render-v2-8zjntgf5.js} +7 -7
- package/dist/{seed-pricing-49gbgn96.js → seed-pricing-jqjs6cws.js} +6 -6
- package/dist/{setup-qvq64vzq.js → setup-4pks0vfk.js} +2 -2
- package/dist/work-objects-wangt792.js +165 -0
- package/dist/{worker-scj60cxg.js → worker-p2mr422x.js} +40 -48
- package/openapi.json +1365 -268
- package/package.json +4 -3
- package/src/agentmail/handlers.ts +95 -66
- package/src/be/budget-refusal-notify.ts +1 -0
- package/src/be/db/tasks/read.ts +3 -0
- package/src/be/db/tasks/write.ts +13 -1
- package/src/be/db-client.ts +5 -0
- package/src/be/db.ts +15 -5
- package/src/be/extensions/db.ts +461 -0
- package/src/be/extensions/validate.ts +107 -0
- package/src/be/memory/boot-reembed.ts +17 -12
- package/src/be/memory/index.ts +12 -0
- package/src/be/memory/providers/openai-embedding.ts +4 -0
- package/src/be/memory/types.ts +2 -0
- package/src/be/migrations/153_deferred_task_wait_members.sql +25 -0
- package/src/be/migrations/154_routing_source.sql +3 -0
- package/src/be/migrations/155_extensions.sql +66 -0
- package/src/be/migrations/156_inbox_item_state_read_at.sql +7 -0
- package/src/be/rbac-roles.ts +3 -2
- package/src/be/scripts/typecheck.ts +59 -41
- package/src/be/seed/schedules-seeder.ts +25 -2
- package/src/be/seed/workflows-seeder.ts +17 -0
- package/src/be/seed-scripts/catalog/delegate.ts +3 -1
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/seed-skills/index.ts +7 -0
- package/src/be/steering.ts +1 -0
- package/src/be/swarm-config-guard.ts +3 -1
- package/src/commands/credential-refresh.ts +70 -0
- package/src/commands/onboard/compose-generator.ts +14 -2
- package/src/commands/onboard/env-generator.ts +7 -0
- package/src/commands/provider-credentials.ts +2 -25
- package/src/commands/runner.ts +24 -57
- package/src/extensions/apply-task-create.ts +135 -0
- package/src/extensions/bundle-path.ts +10 -0
- package/src/extensions/contract-runtime.ts +7 -0
- package/src/extensions/contract-types.generated.ts +4 -0
- package/src/extensions/contract.ts +270 -0
- package/src/extensions/ctx.ts +186 -0
- package/src/extensions/dispatcher.ts +479 -0
- package/src/extensions/identity.ts +44 -0
- package/src/extensions/lifecycle.ts +281 -0
- package/src/extensions/loader.ts +207 -0
- package/src/extensions/post-bridge.ts +161 -0
- package/src/github/handlers.ts +185 -140
- package/src/gitlab/handlers.ts +97 -77
- package/src/heartbeat/heartbeat.ts +155 -83
- package/src/http/agents.ts +1 -1
- package/src/http/all-routes.ts +1 -0
- package/src/http/approval-requests.ts +1 -0
- package/src/http/apps.ts +14 -9
- package/src/http/config.ts +4 -1
- package/src/http/core.ts +38 -2
- package/src/http/extensions.ts +547 -0
- package/src/http/inbox-state.ts +2 -0
- package/src/http/index.ts +41 -3
- package/src/http/mcp-bridge.ts +96 -62
- package/src/http/mcp.ts +1 -1
- package/src/http/script-runs.ts +5 -0
- package/src/http/status.ts +6 -4
- package/src/http/tasks.ts +51 -30
- package/src/integrations/kapso/inbound.ts +15 -10
- package/src/jira/sync.ts +26 -16
- package/src/linear/sync.ts +26 -16
- package/src/prompts/session-templates.ts +18 -13
- package/src/providers/claude-adapter.ts +21 -8
- package/src/rbac/admission.ts +1 -1
- package/src/rbac/elevated-agents.ts +24 -0
- package/src/rbac/legacy-policy.ts +35 -6
- package/src/rbac/permissions.ts +8 -0
- package/src/scheduler/deferred-task-waits.ts +138 -27
- package/src/scheduler/schedule-task.ts +54 -24
- package/src/scheduler/scheduler.ts +108 -125
- package/src/scripts-runtime/executors/native.ts +5 -1
- package/src/scripts-runtime/executors/types.ts +5 -0
- package/src/scripts-runtime/import-allowlist.ts +79 -19
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/swarm-config.ts +8 -0
- package/src/scripts-runtime/swarm-sdk.ts +3 -0
- package/src/scripts-runtime/types/stdlib.d.ts +16 -3
- package/src/scripts-runtime/types/swarm-extension.d.ts +562 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +16 -3
- package/src/server.ts +6 -0
- package/src/slack/HEURISTICS.md +3 -1
- package/src/slack/actions.ts +21 -16
- package/src/slack/app.ts +2 -0
- package/src/slack/assistant.ts +4 -12
- package/src/slack/blocks.ts +1 -1
- package/src/slack/handlers.ts +107 -19
- package/src/slack/inbound-files.ts +9 -5
- package/src/slack/render-v2.ts +188 -38
- package/src/slack/router.ts +13 -3
- package/src/slack/steering.ts +3 -3
- package/src/slack/thread-buffer.ts +66 -23
- package/src/slack/work-objects.test.ts +252 -0
- package/src/slack/work-objects.ts +118 -0
- package/src/tasks/errors.ts +9 -0
- package/src/tasks/sibling-awareness.ts +35 -1
- package/src/tasks/worker-follow-up.ts +67 -11
- package/src/tests/acp-adapter.test.ts +10 -10
- package/src/tests/agent-fs-live-url.test.ts +40 -0
- package/src/tests/agent-fs-provision-seeder.test.ts +12 -12
- package/src/tests/api-key-tracking.test.ts +18 -18
- package/src/tests/api-key.test.ts +4 -2
- package/src/tests/apps-rbac.test.ts +1 -1
- package/src/tests/apps-spike5.test.ts +1 -1
- package/src/tests/apps-sync-engine.test.ts +8 -8
- package/src/tests/apps-user-config.test.ts +1 -1
- package/src/tests/artifact-sdk.test.ts +8 -8
- package/src/tests/asset-key-mcp.test.ts +2 -0
- package/src/tests/automation-preflight-alert.test.ts +1 -1
- package/src/tests/base-prompt.test.ts +7 -6
- package/src/tests/budget-user-scope.test.ts +1 -1
- package/src/tests/budgets-routes.test.ts +1 -1
- package/src/tests/claude-adapter-binary.test.ts +22 -40
- package/src/tests/claude-adapter-otel.test.ts +13 -7
- package/src/tests/claude-adapter.test.ts +8 -6
- package/src/tests/claude-hook-credentials.test.ts +3 -3
- package/src/tests/claude-managed-adapter.test.ts +4 -4
- package/src/tests/claude-managed-setup.test.ts +3 -3
- package/src/tests/claude-sdk-lifecycle.test.ts +1 -1
- package/src/tests/claude-sdk-transport.test.ts +6 -6
- package/src/tests/claude-stop-hook.test.ts +8 -8
- package/src/tests/claude-worker-parity.test.ts +3 -3
- package/src/tests/codex-adapter-pool-auth-revalidate.test.ts +5 -5
- package/src/tests/codex-adapter.test.ts +7 -5
- package/src/tests/codex-app-server.test.ts +2 -2
- package/src/tests/codex-login.test.ts +15 -15
- package/src/tests/codex-oauth-credential-info.test.ts +4 -4
- package/src/tests/codex-oauth-keep-warm.test.ts +4 -4
- package/src/tests/codex-oauth-refresh-lock.test.ts +1 -1
- package/src/tests/codex-oauth-storage.test.ts +7 -7
- package/src/tests/codex-pool.test.ts +1 -1
- package/src/tests/codex-steering-hook.test.ts +1 -1
- package/src/tests/codex-swarm-events.test.ts +1 -1
- package/src/tests/config-api-only-keys.test.ts +1 -1
- package/src/tests/config-session-auth.test.ts +2 -2
- package/src/tests/connection-embedded-auth.test.ts +20 -18
- package/src/tests/core-auth.test.ts +1 -1
- package/src/tests/create-page-tool.test.ts +3 -3
- package/src/tests/credential-refresh.test.ts +115 -0
- package/src/tests/credential-wait.test.ts +2 -2
- package/src/tests/credentials.test.ts +6 -4
- package/src/tests/db-queries-oauth.test.ts +40 -40
- package/src/tests/defer-task.test.ts +73 -8
- package/src/tests/deferred-task-wait-migration.test.ts +64 -0
- package/src/tests/deferred-task-wake.test.ts +349 -8
- package/src/tests/devin-adapter.test.ts +1 -1
- package/src/tests/devin-api.test.ts +1 -1
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/e2b-dispatch.test.ts +21 -19
- package/src/tests/e2e-claude-transport.test.ts +3 -3
- package/src/tests/e2e-redact.test.ts +6 -6
- package/src/tests/ensure-token.test.ts +68 -68
- package/src/tests/entrypoint-api-readiness.test.ts +1 -1
- package/src/tests/entrypoint-codex-oauth-seed.test.ts +13 -13
- package/src/tests/env-flag.test.ts +1 -0
- package/src/tests/events-http.test.ts +1 -1
- package/src/tests/extensions-db.test.ts +216 -0
- package/src/tests/extensions-dispatcher.test.ts +275 -0
- package/src/tests/extensions-example-heartbeat-remediate.test.ts +69 -0
- package/src/tests/extensions-example-mcp-install.test.ts +63 -0
- package/src/tests/extensions-example-no-exclamation-marks.test.ts +72 -0
- package/src/tests/extensions-example-rewrite-and-suppress.test.ts +70 -0
- package/src/tests/extensions-example-route-slack-channel.test.ts +217 -0
- package/src/tests/extensions-heartbeat.test.ts +291 -0
- package/src/tests/extensions-http.test.ts +431 -0
- package/src/tests/extensions-lead-equivalence.test.ts +49 -0
- package/src/tests/extensions-lifecycle.test.ts +209 -0
- package/src/tests/extensions-loader.test.ts +95 -0
- package/src/tests/extensions-mcp-tools.test.ts +245 -0
- package/src/tests/extensions-pre-task.test.ts +487 -0
- package/src/tests/extensions-run-context.test.ts +41 -0
- package/src/tests/extensions-tool-call.test.ts +288 -0
- package/src/tests/extensions-validate.test.ts +196 -0
- package/src/tests/fixtures/extensions/bad-import/hooks.ts +8 -0
- package/src/tests/fixtures/extensions/bad-import/manifest.json +9 -0
- package/src/tests/fixtures/extensions/bad-return-shape/hooks.ts +10 -0
- package/src/tests/fixtures/extensions/bad-return-shape/manifest.json +9 -0
- package/src/tests/fixtures/extensions/block-tasks-from-source/hooks.ts +22 -0
- package/src/tests/fixtures/extensions/block-tasks-from-source/manifest.json +9 -0
- package/src/tests/fixtures/extensions/ignore-channel/hooks.ts +22 -0
- package/src/tests/fixtures/extensions/ignore-channel/manifest.json +9 -0
- package/src/tests/fixtures/extensions/load.ts +10 -0
- package/src/tests/fixtures/extensions/minimal/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/minimal/manifest.json +9 -0
- package/src/tests/fixtures/extensions/never-fail-long-tasks/hooks.ts +11 -0
- package/src/tests/fixtures/extensions/never-fail-long-tasks/manifest.json +9 -0
- package/src/tests/fixtures/extensions/no-exclamation-marks/hooks.ts +23 -0
- package/src/tests/fixtures/extensions/no-exclamation-marks/manifest.json +9 -0
- package/src/tests/fixtures/extensions/post-logger/hooks.ts +9 -0
- package/src/tests/fixtures/extensions/post-logger/manifest.json +9 -0
- package/src/tests/fixtures/extensions/priority-a/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/priority-a/manifest.json +9 -0
- package/src/tests/fixtures/extensions/priority-b/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/priority-b/manifest.json +9 -0
- package/src/tests/fixtures/extensions/record-only-on-tag/hooks.ts +16 -0
- package/src/tests/fixtures/extensions/record-only-on-tag/manifest.json +9 -0
- package/src/tests/fixtures/extensions/reserved-assets/hooks.ts +5 -0
- package/src/tests/fixtures/extensions/reserved-assets/manifest.json +10 -0
- package/src/tests/fixtures/extensions/rewrite-progress-prefix/hooks.ts +22 -0
- package/src/tests/fixtures/extensions/rewrite-progress-prefix/manifest.json +9 -0
- package/src/tests/fixtures/extensions/rewrite-task-priority/hooks.ts +7 -0
- package/src/tests/fixtures/extensions/rewrite-task-priority/manifest.json +9 -0
- package/src/tests/fixtures/extensions/route-channel-to-agent/hooks.ts +26 -0
- package/src/tests/fixtures/extensions/route-channel-to-agent/manifest.json +9 -0
- package/src/tests/fixtures/extensions/slow/hooks.ts +10 -0
- package/src/tests/fixtures/extensions/slow/manifest.json +9 -0
- package/src/tests/fixtures/extensions/suppress-lead-follow-up/hooks.ts +12 -0
- package/src/tests/fixtures/extensions/suppress-lead-follow-up/manifest.json +9 -0
- package/src/tests/fixtures/extensions/throws/hooks.ts +12 -0
- package/src/tests/fixtures/extensions/throws/manifest.json +9 -0
- package/src/tests/fixtures/extensions/worker-runtime/hooks.ts +5 -0
- package/src/tests/fixtures/extensions/worker-runtime/manifest.json +9 -0
- package/src/tests/fs-routes.test.ts +1 -1
- package/src/tests/gitlab-auth.test.ts +10 -10
- package/src/tests/harness-provider-resolution.test.ts +8 -5
- package/src/tests/heartbeat-reroute-decision.test.ts +1 -0
- package/src/tests/helper-credentials.test.ts +137 -0
- package/src/tests/http/context-routes.test.ts +2 -2
- package/src/tests/http-api-integration.test.ts +5 -2
- package/src/tests/http-users.test.ts +1 -1
- package/src/tests/identity-refresh.test.ts +2 -2
- package/src/tests/internal-ai/complete-structured.test.ts +2 -2
- package/src/tests/internal-ai/credentials.test.ts +19 -17
- package/src/tests/jira-metadata.test.ts +1 -1
- package/src/tests/jira-oauth.test.ts +5 -5
- package/src/tests/jira-sync.test.ts +1 -1
- package/src/tests/jira-webhook-lifecycle.test.ts +3 -3
- package/src/tests/jira-webhook.test.ts +2 -2
- package/src/tests/kapso-inbound.test.ts +2 -2
- package/src/tests/kv-http.test.ts +1 -1
- package/src/tests/kv-namespace-resolution.test.ts +1 -1
- package/src/tests/kv-page-proxy.test.ts +2 -2
- package/src/tests/launch-password-rejection.test.ts +2 -2
- package/src/tests/linear-webhook.test.ts +1 -1
- package/src/tests/mcp-oauth-dcr-reuse.test.ts +6 -6
- package/src/tests/mcp-oauth-ensure-token.test.ts +28 -22
- package/src/tests/mcp-oauth-manual-client.test.ts +16 -12
- package/src/tests/mcp-oauth-queries.test.ts +35 -32
- package/src/tests/mcp-oauth-resolve-secrets.test.ts +8 -8
- package/src/tests/mcp-oauth-wrapper.test.ts +20 -20
- package/src/tests/mcp-user-route.test.ts +1 -1
- package/src/tests/memory-edges.test.ts +1 -1
- package/src/tests/memory-edit-authorization.test.ts +32 -0
- package/src/tests/memory-rate-endpoint.test.ts +1 -1
- package/src/tests/memory-rate-tool.test.ts +2 -2
- package/src/tests/memory-rater-e2e.test.ts +1 -1
- package/src/tests/memory-rater-llm-summarizer.test.ts +3 -3
- package/src/tests/memory-rater-llm.test.ts +1 -1
- package/src/tests/model-control.test.ts +3 -0
- package/src/tests/multi-runtime-enabled-stats.test.ts +2 -2
- package/src/tests/multi-runtime-registration.test.ts +111 -17
- package/src/tests/oauth-access-token-tool.test.ts +18 -18
- package/src/tests/oauth-callback-flow.test.ts +8 -8
- package/src/tests/oauth-credential-bindings.test.ts +29 -27
- package/src/tests/oauth-keepalive.test.ts +10 -10
- package/src/tests/oauth-presets.test.ts +13 -5
- package/src/tests/oauth-refresh-failure.test.ts +9 -9
- package/src/tests/oauth-refresh-sweep.test.ts +20 -13
- package/src/tests/oauth-wrapper.test.ts +1 -1
- package/src/tests/onboard-compose.test.ts +47 -3
- package/src/tests/onboard-env.test.ts +26 -26
- package/src/tests/onboard-non-interactive.test.ts +4 -4
- package/src/tests/opencode-adapter.test.ts +1 -1
- package/src/tests/opencode-plugin.test.ts +2 -2
- package/src/tests/otel-session-cost-metrics.test.ts +1 -1
- package/src/tests/page-proxy-authed.test.ts +2 -2
- package/src/tests/page-proxy.test.ts +2 -2
- package/src/tests/page-session.test.ts +7 -7
- package/src/tests/page-viewer-auth.test.ts +2 -2
- package/src/tests/pages-authed-mode.test.ts +1 -1
- package/src/tests/pages-http.test.ts +1 -1
- package/src/tests/pages-password-mode.test.ts +1 -1
- package/src/tests/pages-public-authed-401.test.ts +1 -1
- package/src/tests/pages-public-html.test.ts +2 -2
- package/src/tests/pages-view-count.test.ts +1 -1
- package/src/tests/pi-mono-adapter.test.ts +10 -10
- package/src/tests/pi-mono-extension.test.ts +2 -2
- package/src/tests/preload.ts +5 -0
- package/src/tests/pricing-routes.test.ts +1 -1
- package/src/tests/profile-sync-warning.test.ts +8 -8
- package/src/tests/profile-sync.test.ts +8 -8
- package/src/tests/prompt-template-session.test.ts +36 -5
- package/src/tests/provider-process-group.test.ts +95 -4
- package/src/tests/providers/pi-cost.test.ts +1 -1
- package/src/tests/queue-stall-alarm.test.ts +1 -1
- package/src/tests/rbac-admission.test.ts +19 -4
- package/src/tests/rbac-charact-http.test.ts +1 -1
- package/src/tests/rbac-e2e-helpers.ts +1 -1
- package/src/tests/rbac-engine.test.ts +39 -0
- package/src/tests/realtime-room-auth.test.ts +1 -1
- package/src/tests/realtime-room-surfaces.test.ts +1 -1
- package/src/tests/reload-config.test.ts +45 -1
- package/src/tests/routing-affinity-inventory.test.ts +1 -1
- package/src/tests/routing-reason-contract.test.ts +76 -3
- package/src/tests/routing-reason-inventory.test.ts +11 -6
- package/src/tests/routing-source.test.ts +53 -0
- package/src/tests/runner-agent-fs-provision-retry.test.ts +1 -1
- package/src/tests/runner-context-preamble.test.ts +1 -1
- package/src/tests/runner-deployment-resume.test.ts +1 -1
- package/src/tests/runner-fallback-output.test.ts +1 -1
- package/src/tests/runner-identity-refresh.test.ts +1 -1
- package/src/tests/runner-skills-refresh.test.ts +1 -1
- package/src/tests/schedule-target-type.test.ts +3 -3
- package/src/tests/scheduled-tasks.test.ts +14 -5
- package/src/tests/scheduler-occurrence.test.ts +347 -0
- package/src/tests/script-apis-mcp.test.ts +1 -1
- package/src/tests/script-connections-http.test.ts +61 -58
- package/src/tests/script-connections-mcp.test.ts +1 -1
- package/src/tests/script-connections.test.ts +3 -1
- package/src/tests/script-runs-http.test.ts +15 -7
- package/src/tests/script-workflows-runtime-e2e.test.ts +1 -1
- package/src/tests/scripts-boot-reembed.test.ts +4 -0
- package/src/tests/scripts-embeddings.test.ts +4 -0
- package/src/tests/scripts-external-api.test.ts +1 -1
- package/src/tests/scripts-http.test.ts +1 -1
- package/src/tests/scripts-import-allowlist.test.ts +44 -1
- package/src/tests/scripts-mcp-e2e.test.ts +81 -1
- package/src/tests/scripts-only-gating.test.ts +4 -2
- package/src/tests/scripts-retention.test.ts +1 -1
- package/src/tests/scripts-runtime-identity.test.ts +2 -2
- package/src/tests/scripts-runtime-secret-egress.test.ts +1 -1
- package/src/tests/scripts-runtime.test.ts +6 -4
- package/src/tests/scripts-typecheck.test.ts +21 -0
- package/src/tests/sdk-allowlist.test.ts +1 -1
- package/src/tests/secret-scrubber.test.ts +38 -31
- package/src/tests/seed-registry.test.ts +46 -8
- package/src/tests/seed-schedules.test.ts +44 -9
- package/src/tests/seed-workflows.test.ts +21 -9
- package/src/tests/send-task-output-schema.test.ts +9 -1
- package/src/tests/send-task-requested-by.test.ts +1 -0
- package/src/tests/send-task-slack-routing-guard.test.ts +2 -0
- package/src/tests/session-costs-codex-recompute.test.ts +1 -1
- package/src/tests/session-costs-golden.test.ts +2 -2
- package/src/tests/session-costs-model-key-normalize.test.ts +2 -2
- package/src/tests/session-costs-recompute-all-providers.test.ts +1 -1
- package/src/tests/session-tokens.test.ts +1 -1
- package/src/tests/shutdown-error-scrubbing.test.ts +1 -1
- package/src/tests/slack-blocks.test.ts +12 -1
- package/src/tests/slack-file-tools-attachments.test.ts +1 -1
- package/src/tests/slack-inbound-files.test.ts +222 -86
- package/src/tests/slack-reaction-config.test.ts +5 -4
- package/src/tests/slack-read-boundaries.test.ts +1 -1
- package/src/tests/slack-render-v2.test.ts +196 -4
- package/src/tests/slack-router.test.ts +17 -2
- package/src/tests/slack-steering.test.ts +19 -0
- package/src/tests/status.test.ts +19 -7
- package/src/tests/steering-core.test.ts +1 -1
- package/src/tests/steering-enabled.test.ts +6 -8
- package/src/tests/steering-transport.test.ts +4 -4
- package/src/tests/store-progress-output-guidance.test.ts +34 -0
- package/src/tests/swarm-tool-result-gate.test.ts +11 -11
- package/src/tests/swarm-x-tool.test.ts +7 -5
- package/src/tests/sync-ai-toolbox-skills.test.ts +19 -0
- package/src/tests/task-supersede-resume.test.ts +1 -1
- package/src/tests/task-tool-preload-mcp.test.ts +4 -1
- package/src/tests/task-tools-ctx.test.ts +2 -0
- package/src/tests/tasks-requested-by-filter.test.ts +2 -2
- package/src/tests/telemetry-init.test.ts +11 -3
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/tool-output-agent-id.test.ts +1 -0
- package/src/tests/tool-registrar-no-input.test.ts +42 -1
- package/src/tests/tracker-fold.test.ts +7 -7
- package/src/tests/tracker-tools.test.ts +3 -3
- package/src/tests/ui-followup-lead-delegation.test.ts +1 -0
- package/src/tests/unified-oauth-migration.test.ts +5 -5
- package/src/tests/user-token-rest-auth.test.ts +1 -1
- package/src/tests/user-token-routes.test.ts +1 -1
- package/src/tests/whoami-route.test.ts +1 -1
- package/src/tests/workflow-agent-task.test.ts +15 -13
- package/src/tests/workflow-ctx.test.ts +1 -1
- package/src/tests/workflow-e2e.test.ts +1 -1
- package/src/tests/workflow-engine-v2.test.ts +3 -1
- package/src/tests/workflow-executors.test.ts +2 -2
- package/src/tests/workflow-http-v2.test.ts +8 -6
- package/src/tests/workflow-input-redaction.test.ts +7 -5
- package/src/tests/workflow-integration-io.test.ts +2 -2
- package/src/tests/workflow-llm.test.ts +5 -5
- package/src/tests/workflow-registry.test.ts +1 -1
- package/src/tests/workflow-swarm-script.test.ts +1 -1
- package/src/tests/workflow-triggers-v2.test.ts +23 -21
- package/src/tests/x-composio.test.ts +9 -7
- package/src/tests/x402-client.test.ts +1 -1
- package/src/tests/x402-config.test.ts +28 -41
- package/src/tools/defer-task.ts +156 -24
- package/src/tools/extension-common.ts +84 -0
- package/src/tools/extension-install.ts +65 -0
- package/src/tools/extension-list.ts +66 -0
- package/src/tools/script-common.ts +43 -18
- package/src/tools/send-task.ts +87 -105
- package/src/tools/skills/skill-publish.ts +1 -0
- package/src/tools/store-progress.ts +1 -1
- package/src/tools/task-action.ts +43 -22
- package/src/tools/task-tool-ctx.ts +2 -0
- package/src/tools/templates.ts +2 -1
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/utils.ts +140 -16
- package/src/types.ts +144 -0
- package/src/utils/constants.ts +7 -1
- package/src/utils/credentials.test.ts +16 -16
- package/src/utils/multi-runtime.ts +2 -2
- package/src/utils/steering-enabled.ts +4 -4
- package/src/workflows/executors/agent-task.ts +18 -3
- package/templates/ai-toolbox.manifest.json +7 -1
- package/templates/extensions/README.md +17 -0
- package/templates/extensions/notify-on-complete/README.md +11 -0
- package/templates/extensions/notify-on-complete/hooks.ts +61 -0
- package/templates/extensions/notify-on-complete/manifest.json +7 -0
- package/templates/extensions/require-ticket-ref/README.md +11 -0
- package/templates/extensions/require-ticket-ref/hooks.ts +30 -0
- package/templates/extensions/require-ticket-ref/manifest.json +7 -0
- package/templates/extensions/require-verification-note/README.md +11 -0
- package/templates/extensions/require-verification-note/hooks.ts +32 -0
- package/templates/extensions/require-verification-note/manifest.json +7 -0
- package/templates/schedules/daily-hn-briefing/config.json +1 -1
- package/templates/schedules/gtm-weekly-review/config.json +1 -1
- package/templates/schedules/weekly-code-health-reports/config.json +1 -1
- package/templates/schedules/weekly-dependabot-triage/config.json +1 -1
- package/templates/schedules/weekly-dora-metrics/config.json +1 -1
- package/templates/schedules/weekly-harness-upgrade-check/config.json +1 -1
- package/templates/skills/delegate-work/files/scripts/codex-exec.sh +1 -1
- package/templates/skills/scheduling/content.md +2 -0
- package/templates/skills/serply-search/SKILL.md +95 -0
- package/templates/skills/serply-search/config.json +13 -0
- package/templates/skills/serply-search/content.md +90 -0
- package/templates/skills/swarm-extensions/config.json +14 -0
- package/templates/skills/swarm-extensions/content.md +120 -0
- package/templates/skills/swarm-scripts/SKILL.md +2 -2
- package/templates/skills/swarm-scripts/content.md +2 -2
- package/templates/workflows/claude-code-changelog-watch/config.json +1 -1
- package/templates/workflows/gsc-topic-miner/config.json +1 -1
- package/templates/workflows/linear-drain-loop/config.json +1 -1
- package/templates/workflows/llm-safe-release-context/config.json +1 -1
- package/templates/workflows/ralph-loop/config.json +1 -1
- package/dist/cli-7fehefdf.js +0 -562
- package/dist/cli-ayvy5kde.js +0 -164
- package/dist/cli-ddfw1mc4.js +0 -4322
- package/dist/cli-hzqmgcm2.js +0 -3066
- package/dist/cli-j4d4f6hv.js +0 -338
- package/dist/cli-qgm2pfpq.js +0 -6377
- package/dist/cli-sdzq01t9.js +0 -823
- package/dist/cli-xvkmedgn.js +0 -332
- package/dist/cli-y3pq4v9g.js +0 -664
- package/dist/{anthropic-messages-vs2rabzp.js → anthropic-messages-2y8nktar.js} +19 -19
- package/dist/{claude-managed-setup-f5pmsyrp.js → claude-managed-setup-48dwg9bv.js} +3 -3
- package/dist/{cli-81r683bv.js → cli-ch38q5z4.js} +0 -0
- package/dist/{cli-6664w7y4.js → cli-kj76p1ez.js} +8 -8
- package/dist/{cli-c71mg51n.js → cli-r2fpe7cx.js} +5 -5
- package/dist/{cli-4xz3pmrq.js → cli-y6x0gqtg.js} +16 -16
- package/dist/{index-aa3sa6s8.js → index-2wsdsnmm.js} +1 -1
- package/dist/{mistral-conversations-4ryk7h83.js → mistral-conversations-qhr84ph3.js} +9 -9
- package/dist/{openai-completions-0bqmsajw.js → openai-completions-32rdwmze.js} +19 -19
- package/dist/{openrouter-images-qx18fyp8.js → openrouter-images-9f9ek4rw.js} +3 -3
- package/dist/{pi-messages-79jvzz1d.js → pi-messages-b1mbr6gp.js} +4 -4
package/src/http/mcp-bridge.ts
CHANGED
|
@@ -8,8 +8,13 @@ import {
|
|
|
8
8
|
} from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
9
9
|
import { z } from "zod";
|
|
10
10
|
import { createServer } from "@/server";
|
|
11
|
+
import { resolveBridgeCallOrigin } from "../extensions/dispatcher";
|
|
11
12
|
import { isMcpToolAllowedForScripts } from "../scripts-runtime/sdk-allowlist";
|
|
12
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
markExtensionRequestOrigin,
|
|
15
|
+
markScriptSdkRequestOrigin,
|
|
16
|
+
type RequestInfo,
|
|
17
|
+
} from "../tools/utils";
|
|
13
18
|
import { route, runtimeInstanceHeader } from "./route-def";
|
|
14
19
|
import { json, jsonError } from "./utils";
|
|
15
20
|
|
|
@@ -35,6 +40,78 @@ type RegisteredTool = {
|
|
|
35
40
|
|
|
36
41
|
type ToolRegistry = Record<string, RegisteredTool>;
|
|
37
42
|
|
|
43
|
+
export class InProcessToolInvocationError extends Error {
|
|
44
|
+
constructor(
|
|
45
|
+
message: string,
|
|
46
|
+
readonly status: number,
|
|
47
|
+
) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = "InProcessToolInvocationError";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function invokeToolInProcess(args: {
|
|
54
|
+
toolName: string;
|
|
55
|
+
args?: unknown;
|
|
56
|
+
agentId?: string;
|
|
57
|
+
sourceTaskId?: string;
|
|
58
|
+
runtimeInstanceId?: string;
|
|
59
|
+
callOrigin: Extract<RequestInfo["callOrigin"], "script-sdk" | "extension">;
|
|
60
|
+
}): Promise<unknown> {
|
|
61
|
+
if (!isMcpToolAllowedForScripts(args.toolName)) {
|
|
62
|
+
throw new InProcessToolInvocationError(
|
|
63
|
+
`Tool '${args.toolName}' is not in the SDK allowlist`,
|
|
64
|
+
403,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const server = await getBridgeServer();
|
|
69
|
+
const tools = (server as unknown as { _registeredTools: ToolRegistry })._registeredTools;
|
|
70
|
+
const tool = tools[args.toolName];
|
|
71
|
+
if (!tool) {
|
|
72
|
+
throw new InProcessToolInvocationError(
|
|
73
|
+
`Tool '${args.toolName}' not found in the MCP registry`,
|
|
74
|
+
404,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
if (tool.enabled === false) {
|
|
78
|
+
throw new InProcessToolInvocationError(`Tool '${args.toolName}' is disabled`, 400);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const baseExtra = {
|
|
82
|
+
sessionId: args.callOrigin === "extension" ? "extension" : "mcp-bridge",
|
|
83
|
+
requestInfo: {
|
|
84
|
+
headers: {
|
|
85
|
+
"x-agent-id": args.agentId ?? "",
|
|
86
|
+
...(args.sourceTaskId ? { "x-source-task-id": args.sourceTaskId } : {}),
|
|
87
|
+
...(args.runtimeInstanceId ? { "x-runtime-instance-id": args.runtimeInstanceId } : {}),
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
const extra =
|
|
92
|
+
args.callOrigin === "extension"
|
|
93
|
+
? markExtensionRequestOrigin(baseExtra)
|
|
94
|
+
: markScriptSdkRequestOrigin(baseExtra);
|
|
95
|
+
|
|
96
|
+
let handlerArgs: unknown = args.args ?? {};
|
|
97
|
+
if (tool.inputSchema) {
|
|
98
|
+
const inputObj = normalizeObjectSchema(tool.inputSchema);
|
|
99
|
+
const parseResult = await safeParseAsync(inputObj ?? tool.inputSchema, handlerArgs);
|
|
100
|
+
if (!parseResult.success) {
|
|
101
|
+
const parseError = "error" in parseResult ? parseResult.error : "Unknown error";
|
|
102
|
+
throw new InProcessToolInvocationError(
|
|
103
|
+
`Invalid arguments for tool '${args.toolName}': ${getParseErrorMessage(parseError)}`,
|
|
104
|
+
400,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
handlerArgs = parseResult.data;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return tool.inputSchema
|
|
111
|
+
? await Promise.resolve(tool.handler(handlerArgs, extra))
|
|
112
|
+
: await Promise.resolve(tool.handler(extra));
|
|
113
|
+
}
|
|
114
|
+
|
|
38
115
|
const mcpBridgeRoute = route({
|
|
39
116
|
method: "post",
|
|
40
117
|
path: "/api/mcp-bridge",
|
|
@@ -58,6 +135,11 @@ const mcpBridgeRoute = route({
|
|
|
58
135
|
},
|
|
59
136
|
});
|
|
60
137
|
|
|
138
|
+
function headerValue(req: IncomingMessage, name: string): string | undefined {
|
|
139
|
+
const value = req.headers[name];
|
|
140
|
+
return Array.isArray(value) ? value[0] : value;
|
|
141
|
+
}
|
|
142
|
+
|
|
61
143
|
export async function handleMcpBridge(
|
|
62
144
|
req: IncomingMessage,
|
|
63
145
|
res: ServerResponse,
|
|
@@ -72,70 +154,22 @@ export async function handleMcpBridge(
|
|
|
72
154
|
|
|
73
155
|
const { tool: toolName, args } = parsed.body;
|
|
74
156
|
|
|
75
|
-
|
|
76
|
-
jsonError(res, `Tool '${toolName}' is not in the SDK allowlist`, 403);
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const server = await getBridgeServer();
|
|
81
|
-
const tools = (server as unknown as { _registeredTools: ToolRegistry })._registeredTools;
|
|
82
|
-
|
|
83
|
-
const tool = tools[toolName];
|
|
84
|
-
if (!tool) {
|
|
85
|
-
jsonError(res, `Tool '${toolName}' not found in the MCP registry`, 404);
|
|
86
|
-
return true;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (tool.enabled === false) {
|
|
90
|
-
jsonError(res, `Tool '${toolName}' is disabled`, 400);
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const sourceTaskId = Array.isArray(req.headers["x-source-task-id"])
|
|
95
|
-
? req.headers["x-source-task-id"][0]
|
|
96
|
-
: (req.headers["x-source-task-id"] as string | undefined);
|
|
157
|
+
const sourceTaskId = headerValue(req, "x-source-task-id");
|
|
97
158
|
// Runtime identity rides the bridge like the agent identity so the
|
|
98
159
|
// work-acquisition gates in bridged tools see the invoking worker process.
|
|
99
|
-
const runtimeInstanceId =
|
|
100
|
-
? req.headers["x-runtime-instance-id"][0]
|
|
101
|
-
: (req.headers["x-runtime-instance-id"] as string | undefined);
|
|
102
|
-
|
|
103
|
-
const extra = markScriptSdkRequestOrigin({
|
|
104
|
-
sessionId: "mcp-bridge",
|
|
105
|
-
requestInfo: {
|
|
106
|
-
headers: {
|
|
107
|
-
"x-agent-id": myAgentId ?? "",
|
|
108
|
-
...(sourceTaskId ? { "x-source-task-id": sourceTaskId } : {}),
|
|
109
|
-
...(runtimeInstanceId ? { "x-runtime-instance-id": runtimeInstanceId } : {}),
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
// Mirror the SDK's own tools/call validation (`validateToolInput` in
|
|
115
|
-
// @modelcontextprotocol/sdk server/mcp.js). The bridge bypasses the MCP
|
|
116
|
-
// transport, so without this parse raw script args reach handlers
|
|
117
|
-
// unchecked (2026-08-18 priority='high' incident) and the schema's
|
|
118
|
-
// `.default()`/`.transform()` never apply.
|
|
119
|
-
let handlerArgs: unknown = args;
|
|
120
|
-
if (tool.inputSchema) {
|
|
121
|
-
const inputObj = normalizeObjectSchema(tool.inputSchema);
|
|
122
|
-
const parseResult = await safeParseAsync(inputObj ?? tool.inputSchema, args);
|
|
123
|
-
if (!parseResult.success) {
|
|
124
|
-
const parseError = "error" in parseResult ? parseResult.error : "Unknown error";
|
|
125
|
-
jsonError(
|
|
126
|
-
res,
|
|
127
|
-
`Invalid arguments for tool '${toolName}': ${getParseErrorMessage(parseError)}`,
|
|
128
|
-
400,
|
|
129
|
-
);
|
|
130
|
-
return true;
|
|
131
|
-
}
|
|
132
|
-
handlerArgs = parseResult.data;
|
|
133
|
-
}
|
|
160
|
+
const runtimeInstanceId = headerValue(req, "x-runtime-instance-id");
|
|
134
161
|
|
|
135
162
|
try {
|
|
136
|
-
const result =
|
|
137
|
-
|
|
138
|
-
|
|
163
|
+
const result = await invokeToolInProcess({
|
|
164
|
+
toolName,
|
|
165
|
+
args,
|
|
166
|
+
agentId: myAgentId,
|
|
167
|
+
sourceTaskId,
|
|
168
|
+
runtimeInstanceId,
|
|
169
|
+
// The agent header is caller-controlled; the extension origin also needs the
|
|
170
|
+
// per-process token that only the in-process extension SDK holds.
|
|
171
|
+
callOrigin: resolveBridgeCallOrigin(myAgentId, headerValue(req, "x-extension-token")),
|
|
172
|
+
});
|
|
139
173
|
|
|
140
174
|
if (result && typeof result === "object" && "structuredContent" in result) {
|
|
141
175
|
json(res, result.structuredContent);
|
|
@@ -155,7 +189,7 @@ export async function handleMcpBridge(
|
|
|
155
189
|
}
|
|
156
190
|
} catch (err) {
|
|
157
191
|
const message = err instanceof Error ? err.message : String(err);
|
|
158
|
-
jsonError(res, message, 500);
|
|
192
|
+
jsonError(res, message, err instanceof InProcessToolInvocationError ? err.status : 500);
|
|
159
193
|
}
|
|
160
194
|
return true;
|
|
161
195
|
}
|
package/src/http/mcp.ts
CHANGED
|
@@ -203,7 +203,7 @@ export async function handleMcp(
|
|
|
203
203
|
const preloadEnabled = parseEnvFlag(
|
|
204
204
|
configs.find((config) => config.key === "TASK_TOOL_PRELOAD_ENABLED")?.value ??
|
|
205
205
|
process.env.TASK_TOOL_PRELOAD_ENABLED,
|
|
206
|
-
|
|
206
|
+
true,
|
|
207
207
|
);
|
|
208
208
|
let preloadedTools: string[] = [];
|
|
209
209
|
if (preloadEnabled) {
|
package/src/http/script-runs.ts
CHANGED
|
@@ -625,6 +625,11 @@ export async function handleScriptRuns(
|
|
|
625
625
|
routingReason:
|
|
626
626
|
parsed.body.routingReason ?? (parsed.body.agentId ? "human_pinned" : undefined),
|
|
627
627
|
routingNote: parsed.body.routingNote,
|
|
628
|
+
routingSource: parsed.body.routingReason
|
|
629
|
+
? "declared"
|
|
630
|
+
: parsed.body.agentId
|
|
631
|
+
? "engine_default"
|
|
632
|
+
: undefined,
|
|
628
633
|
tags: parsed.body.tags,
|
|
629
634
|
priority: parsed.body.priority,
|
|
630
635
|
offeredTo: parsed.body.offerMode ? parsed.body.agentId : undefined,
|
package/src/http/status.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
hasFirstCompletedTask,
|
|
33
33
|
listAgentsWithCredStatusByProvider,
|
|
34
34
|
} from "../be/db";
|
|
35
|
+
import { getEmbeddingProvider } from "../be/memory";
|
|
35
36
|
import { getFileStorageProvider } from "../fs/registry";
|
|
36
37
|
import { type AgentCredStatus, AutomationIntegrationIdSchema, ProviderNameSchema } from "../types";
|
|
37
38
|
import { route } from "./route-def";
|
|
@@ -385,10 +386,11 @@ async function harnessMilestone(): Promise<SetupMilestone> {
|
|
|
385
386
|
}
|
|
386
387
|
|
|
387
388
|
function embeddingsMilestone(): SetupMilestone {
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
|
|
389
|
+
// Ask the live provider rather than re-deriving key precedence here — it
|
|
390
|
+
// reflects whatever the last config reload (or boot) resolved, including
|
|
391
|
+
// an explicitly empty EMBEDDING_API_KEY disabling the OPENAI_API_KEY
|
|
392
|
+
// fallback. See OpenAIEmbeddingProvider.isConfigured().
|
|
393
|
+
if (getEmbeddingProvider().isConfigured()) {
|
|
392
394
|
return {
|
|
393
395
|
id: "embeddings",
|
|
394
396
|
label: "Memory search",
|
package/src/http/tasks.ts
CHANGED
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
} from "../be/steering";
|
|
42
42
|
import { findUserById } from "../be/users";
|
|
43
43
|
import { can, type RbacPrincipal, type RbacResource } from "../rbac";
|
|
44
|
+
import { TaskCreationBlockedError } from "../tasks/errors";
|
|
44
45
|
import { createTaskWithSiblingAwareness } from "../tasks/sibling-awareness";
|
|
45
46
|
import { guardTerminalTaskResultWrite } from "../tasks/terminal-result-guard";
|
|
46
47
|
import { createResumeFollowUp, createWorkerTaskFollowUp } from "../tasks/worker-follow-up";
|
|
@@ -259,6 +260,13 @@ const createTask = route({
|
|
|
259
260
|
responses: {
|
|
260
261
|
201: { description: "Task created", schema: AgentTaskSchema },
|
|
261
262
|
400: { description: "Validation error" },
|
|
263
|
+
422: {
|
|
264
|
+
description: "Task creation blocked by an extension",
|
|
265
|
+
schema: z.object({
|
|
266
|
+
error: z.string(),
|
|
267
|
+
extension: z.object({ id: z.string(), name: z.string() }),
|
|
268
|
+
}),
|
|
269
|
+
},
|
|
262
270
|
},
|
|
263
271
|
});
|
|
264
272
|
|
|
@@ -836,36 +844,45 @@ export async function handleTasks(
|
|
|
836
844
|
}
|
|
837
845
|
|
|
838
846
|
try {
|
|
839
|
-
const task = await createTaskWithSiblingAwareness(
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
847
|
+
const task = await createTaskWithSiblingAwareness(
|
|
848
|
+
parsed.body.task,
|
|
849
|
+
{
|
|
850
|
+
key: assetKey,
|
|
851
|
+
agentId: defaultAgentId,
|
|
852
|
+
routingReason:
|
|
853
|
+
parsed.body.routingReason ??
|
|
854
|
+
(defaultAgentId
|
|
855
|
+
? parentTask?.agentId === defaultAgentId
|
|
856
|
+
? "continuity"
|
|
857
|
+
: "skill"
|
|
858
|
+
: undefined),
|
|
859
|
+
routingSource: parsed.body.routingReason
|
|
860
|
+
? "declared"
|
|
861
|
+
: defaultAgentId
|
|
862
|
+
? "engine_default"
|
|
863
|
+
: undefined,
|
|
864
|
+
routingNote: parsed.body.routingNote,
|
|
865
|
+
creatorAgentId: myAgentId || undefined,
|
|
866
|
+
taskType: parsed.body.taskType || undefined,
|
|
867
|
+
tags: parsed.body.tags || undefined,
|
|
868
|
+
priority: parsed.body.priority,
|
|
869
|
+
dependsOn: parsed.body.dependsOn || undefined,
|
|
870
|
+
offeredTo: parsed.body.offeredTo || undefined,
|
|
871
|
+
dir: parsed.body.dir || undefined,
|
|
872
|
+
parentTaskId: parsed.body.parentTaskId || undefined,
|
|
873
|
+
source: parsed.body.source || "api",
|
|
874
|
+
outputSchema: parsed.body.outputSchema || undefined,
|
|
875
|
+
contextKey: parsed.body.contextKey || undefined,
|
|
876
|
+
requestedByUserId,
|
|
877
|
+
status: parsed.body.draft ? "draft" : undefined,
|
|
878
|
+
...splitLegacyModelAlias({
|
|
879
|
+
model: parsed.body.model,
|
|
880
|
+
modelTier: parsed.body.modelTier,
|
|
881
|
+
}),
|
|
882
|
+
effort: parsed.body.effort,
|
|
883
|
+
},
|
|
884
|
+
{ origin: "rest" },
|
|
885
|
+
);
|
|
869
886
|
|
|
870
887
|
ensure({
|
|
871
888
|
id: "created",
|
|
@@ -885,6 +902,10 @@ export async function handleTasks(
|
|
|
885
902
|
|
|
886
903
|
createTask.respond(res, 201, task);
|
|
887
904
|
} catch (error) {
|
|
905
|
+
if (error instanceof TaskCreationBlockedError) {
|
|
906
|
+
createTask.respond(res, 422, { error: error.reason, extension: error.extension });
|
|
907
|
+
return true;
|
|
908
|
+
}
|
|
888
909
|
console.error("[HTTP] Failed to create task:", error);
|
|
889
910
|
jsonError(res, "Failed to create task", 500);
|
|
890
911
|
}
|
|
@@ -152,16 +152,21 @@ export async function routeKapsoInbound(payload: KapsoWebhookPayload): Promise<K
|
|
|
152
152
|
return { kind: "workflow", workflowId: mapping.workflowId };
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
const task = await createTaskWithSiblingAwareness(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
const task = await createTaskWithSiblingAwareness(
|
|
156
|
+
await buildTaskDescription(payload),
|
|
157
|
+
{
|
|
158
|
+
agentId: mapping.agentId ?? null,
|
|
159
|
+
routingReason: mapping.agentId ? "human_pinned" : undefined,
|
|
160
|
+
routingSource: mapping.agentId ? "engine_default" : undefined,
|
|
161
|
+
source: "system",
|
|
162
|
+
taskType: "kapso-inbound",
|
|
163
|
+
tags: ["kapso-whatsapp", "inbound"],
|
|
164
|
+
priority: 70,
|
|
165
|
+
requestedByUserId: await resolveKapsoRequestedByUserId(payload),
|
|
166
|
+
contextKey: `kapso:conversation:${payload.conversation?.id ?? messageId}`,
|
|
167
|
+
},
|
|
168
|
+
{ origin: "webhook" },
|
|
169
|
+
);
|
|
165
170
|
|
|
166
171
|
return { kind: "task", taskId: task.id };
|
|
167
172
|
}
|
package/src/jira/sync.ts
CHANGED
|
@@ -580,14 +580,19 @@ async function createInitialJiraTask(input: {
|
|
|
580
580
|
return;
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
-
const task = await createTaskWithSiblingAwareness(
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
583
|
+
const task = await createTaskWithSiblingAwareness(
|
|
584
|
+
result.text,
|
|
585
|
+
{
|
|
586
|
+
agentId: lead?.id ?? "",
|
|
587
|
+
routingReason: lead ? "skill" : undefined,
|
|
588
|
+
routingSource: lead ? "engine_default" : undefined,
|
|
589
|
+
source: "jira",
|
|
590
|
+
taskType: "jira-issue",
|
|
591
|
+
requestedByUserId: input.requestedByUserId,
|
|
592
|
+
contextKey: buildJiraContextKey(input.issueKey),
|
|
593
|
+
},
|
|
594
|
+
{ origin: "webhook" },
|
|
595
|
+
);
|
|
591
596
|
|
|
592
597
|
await updateTrackerSyncSwarmId(input.syncRowId, task.id);
|
|
593
598
|
|
|
@@ -626,14 +631,19 @@ async function createCommentMentionTask(input: {
|
|
|
626
631
|
return;
|
|
627
632
|
}
|
|
628
633
|
|
|
629
|
-
const task = await createTaskWithSiblingAwareness(
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
634
|
+
const task = await createTaskWithSiblingAwareness(
|
|
635
|
+
result.text,
|
|
636
|
+
{
|
|
637
|
+
agentId: lead?.id ?? "",
|
|
638
|
+
routingReason: lead ? "skill" : undefined,
|
|
639
|
+
routingSource: lead ? "engine_default" : undefined,
|
|
640
|
+
source: "jira",
|
|
641
|
+
taskType: "jira-issue",
|
|
642
|
+
requestedByUserId: input.requestedByUserId,
|
|
643
|
+
contextKey: buildJiraContextKey(input.issueKey),
|
|
644
|
+
},
|
|
645
|
+
{ origin: "webhook" },
|
|
646
|
+
);
|
|
637
647
|
|
|
638
648
|
await updateTrackerSyncSwarmId(input.syncRowId, task.id);
|
|
639
649
|
|
package/src/linear/sync.ts
CHANGED
|
@@ -612,14 +612,19 @@ export async function handleAgentSessionEvent(event: Record<string, unknown>): P
|
|
|
612
612
|
return;
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
-
const task = await createTaskWithSiblingAwareness(
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
615
|
+
const task = await createTaskWithSiblingAwareness(
|
|
616
|
+
templateResult.text,
|
|
617
|
+
{
|
|
618
|
+
agentId: lead?.id ?? "",
|
|
619
|
+
routingReason: lead ? "skill" : undefined,
|
|
620
|
+
routingSource: lead ? "engine_default" : undefined,
|
|
621
|
+
source: "linear",
|
|
622
|
+
taskType: "linear-issue",
|
|
623
|
+
requestedByUserId,
|
|
624
|
+
contextKey,
|
|
625
|
+
},
|
|
626
|
+
{ origin: "webhook" },
|
|
627
|
+
);
|
|
623
628
|
|
|
624
629
|
// Delete old tracker_sync before creating new one (UNIQUE constraint)
|
|
625
630
|
if (existing) {
|
|
@@ -896,14 +901,19 @@ export async function handleAgentSessionPrompted(event: Record<string, unknown>)
|
|
|
896
901
|
return;
|
|
897
902
|
}
|
|
898
903
|
|
|
899
|
-
const task = await createTaskWithSiblingAwareness(
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
904
|
+
const task = await createTaskWithSiblingAwareness(
|
|
905
|
+
followupResult.text,
|
|
906
|
+
{
|
|
907
|
+
agentId: lead?.id ?? "",
|
|
908
|
+
routingReason: lead ? "skill" : undefined,
|
|
909
|
+
routingSource: lead ? "engine_default" : undefined,
|
|
910
|
+
source: "linear",
|
|
911
|
+
taskType: "linear-issue",
|
|
912
|
+
requestedByUserId: promptedRequestedByUserId,
|
|
913
|
+
contextKey,
|
|
914
|
+
},
|
|
915
|
+
{ origin: "webhook" },
|
|
916
|
+
);
|
|
907
917
|
|
|
908
918
|
// Repoint the existing tracker_sync to the new follow-up task (can't create a
|
|
909
919
|
// duplicate due to UNIQUE(provider, entityType, externalId) constraint)
|
|
@@ -72,10 +72,12 @@ Choose the path by the shape of the work:
|
|
|
72
72
|
- Everything else: tools, directly.
|
|
73
73
|
|
|
74
74
|
Store progress with \`store-progress\` at each milestone. A milestone is a result the lead could act on.
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
Complete with \`store-progress\`: status \`completed\`, and \`output\` naming the result and every artifact link. On failure: status \`failed\`, with \`failureReason\` naming what you tried.
|
|
76
|
+
Free-text \`output\`: under 120 words by default, with the exceptions in How you write. Link documents instead of inlining them; omit process narration.
|
|
77
|
+
For a task with \`outputSchema\`, return matching JSON in \`output\`.
|
|
77
78
|
When you are blocked after real effort, store the blocker with \`store-progress\` and keep working on what you can.
|
|
78
|
-
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
|
|
79
|
+
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.
|
|
80
|
+
For task waits, add \`wakeOn:{event:"settled",taskIds:["<id>"],mode:"all"}\`; the displayed time is a ceiling, not a fixed wake-up.
|
|
79
81
|
`,
|
|
80
82
|
variables: [],
|
|
81
83
|
category: "system",
|
|
@@ -90,15 +92,15 @@ registerTemplate({
|
|
|
90
92
|
Your output is delegation and review. Workers implement, research, analyze, and write. Data gathering, even a quick query, goes to a worker. You answer simple factual questions yourself.
|
|
91
93
|
|
|
92
94
|
\`get-swarm\` is the roster. Route by capability and load.
|
|
93
|
-
\`send-task\`: include \`routingReason\` with \`agentId\`. Read results via \`get-task-details\`.
|
|
95
|
+
\`send-task\`: include \`routingReason\` and \`routingNote\` (at least 10 characters after trim, maximum 200) with \`agentId\`. Read results via \`get-task-details\`.
|
|
94
96
|
A task states the goal, the repo URL when there is one, and the constraints. Workers know git, the skills, and \`store-progress\`.
|
|
95
97
|
Delegate by the shape of the work: a workflow for multi-step or fan-out work, a schedule for recurring work, a script for bulk data, an inline \`script-run\` for a one-off bulk job you can run yourself. The \`workflow-iterate\`, \`scheduling\`, and \`swarm-scripts\` skills build them.
|
|
96
98
|
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.
|
|
97
99
|
A follow-up that continues earlier work carries \`parentTaskId\`. The worker receives the prior context.
|
|
98
100
|
|
|
99
|
-
Worker completion/failure triggers a follow-up by default. For longer
|
|
101
|
+
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.
|
|
100
102
|
|
|
101
|
-
|
|
103
|
+
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.
|
|
102
104
|
|
|
103
105
|
A task from an unknown user: register them with \`manage-user\`, then continue.
|
|
104
106
|
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.
|
|
@@ -118,6 +120,7 @@ registerTemplate({
|
|
|
118
120
|
The lead assigns your tasks and reviews your output. Your task is in your first message, with memories from past sessions.
|
|
119
121
|
|
|
120
122
|
Your final message is the task output. It names the result, every link (a PR, a file, a page), and, on failure, what you tried and what blocked you.
|
|
123
|
+
Free-text task output: under 120 words by default, with the exceptions in How you write. Link documents instead of inlining them; omit process narration.
|
|
121
124
|
`,
|
|
122
125
|
variables: [],
|
|
123
126
|
category: "system",
|
|
@@ -230,14 +233,14 @@ registerTemplate({
|
|
|
230
233
|
defaultBody: `
|
|
231
234
|
## How you write
|
|
232
235
|
|
|
233
|
-
For
|
|
236
|
+
For replies, task output (\`output\` or a remote final message), and artifacts: lead with the result. Use plain words, active voice, one idea per sentence, and sentence case headings.
|
|
234
237
|
State blockers and reasons. Preserve meaningful uncertainty.
|
|
235
238
|
Omit em dashes, filler, sign-offs, praise, repetition, step narration, and generic offers to elaborate.
|
|
236
239
|
|
|
237
|
-
Simple replies: one to three sentences. Routine replies: under 120 words,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
240
|
+
Simple replies: one to three sentences. Routine replies and free-text task output: under 120 words by default, in short paragraphs or up to three bullets.
|
|
241
|
+
Exceed for requested depth, enumerated results, essential evidence, caveats, instructions, or longer output required by the task's \`outputSchema\`.
|
|
242
|
+
Keep replies and task output self-contained; link documents instead of inlining them.
|
|
243
|
+
Preserve investigation and required artifacts. Schema exemptions apply to \`outputSchema\`-constrained completions; free-text \`output\` follows the target.
|
|
241
244
|
|
|
242
245
|
Follow the current request and Requester Profile for language, tone, depth, and format. Correctness wins over style.
|
|
243
246
|
Use the \`comms\` skill when available for requested simplification or clarity rewrites. Ordinary replies need no skill invocation.
|
|
@@ -278,6 +281,7 @@ registerTemplate({
|
|
|
278
281
|
## Slack
|
|
279
282
|
|
|
280
283
|
The engine posts the thread tree and the outcome card. You post at most one message per task, and only when you have something the card will not carry. Progress, receipts, and relayed worker output stay out of Slack.
|
|
284
|
+
The outcome card publishes your \`output\` verbatim. Keep free-text \`output\` under 120 words by default, with the exceptions in How you write.
|
|
281
285
|
A Slack task from an unknown user: register them with \`manage-user\` first.
|
|
282
286
|
You MUST use the \`slack-interaction\` skill before you post to Slack.
|
|
283
287
|
`,
|
|
@@ -400,8 +404,8 @@ This swarm runs in **scripts-only mode**. The ONLY swarm MCP tools available are
|
|
|
400
404
|
The script authoring contract in the \`swarm-scripts\` skill (entry signature, \`ctx\` shape, secret handling) applies here unchanged. The full SDK is \`ctx.swarm.*\`: task lifecycle (\`task_get\`, \`task_send\`, \`task_storeProgress\`, \`task_action\`, \`task_list\`), Slack (\`slack_reply\`, \`slack_post\`, \`slack_read\`), memory, kv, swarm info (\`swarm_get\`, \`agent_info\`), and more. Responses are usually wrapped; prefer \`res?.data ?? res\`.
|
|
401
405
|
|
|
402
406
|
**Built-in coordination scripts, USE THESE FIRST (\`script-run\` with \`name\` + \`args\`):**
|
|
403
|
-
- \`delegate\` {agentName, task, routingReason, parentTaskId?} → subtask for an agent by name; returns {taskId}
|
|
404
|
-
- \`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
|
|
407
|
+
- \`delegate\` {agentName, task, routingReason, routingNote, parentTaskId?} → subtask for an agent by name; returns {taskId}
|
|
408
|
+
- \`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.
|
|
405
409
|
- \`get-child-outputs\` {parentTaskId} → all children with status+output
|
|
406
410
|
- \`complete-task\` {taskId, output} → THE way to finish your assigned task
|
|
407
411
|
- \`report-progress\` {taskId, note} → progress update
|
|
@@ -426,6 +430,7 @@ registerTemplate({
|
|
|
426
430
|
## Slack (scripts-only)
|
|
427
431
|
|
|
428
432
|
This task originated from Slack (channel: \`{{slackChannelId}}\`). The engine maintains the thread tree and publishes the top-level outcome card. Post at most one distinct agent-authored message per task, concrete, sized to what the user asked for. Progress, start, completion, failure, acknowledgment messages, and relayed raw task output stay out of Slack. Named Slack tools are not exposed in scripts-only mode, so use \`script-run\` with inline source calling \`ctx.swarm.slack_reply({ taskId, message })\` (your taskId carries the thread context).
|
|
433
|
+
The outcome card publishes your \`output\` verbatim. Keep free-text \`output\` under 120 words by default, with the exceptions in How you write.
|
|
429
434
|
`,
|
|
430
435
|
variables: [
|
|
431
436
|
{ name: "slackChannelId", description: "The Slack channel ID for the originating thread" },
|
|
@@ -96,6 +96,8 @@ export function parseClaudeBinary(raw: string | undefined): string[] {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
const MIN_CLAUDE_QUEUE_STEERING_VERSION = [2, 1, 205] as const;
|
|
99
|
+
const CLAUDE_VERSION_PROBE_TIMEOUT_MS = 1_000;
|
|
100
|
+
const CLAUDE_VERSION_PROBE_MAX_BUFFER_BYTES = 64 * 1024;
|
|
99
101
|
|
|
100
102
|
/**
|
|
101
103
|
* Operator kill-switch for the stream-json invocation path.
|
|
@@ -1157,14 +1159,25 @@ export class ClaudeAdapter implements ProviderAdapter {
|
|
|
1157
1159
|
const queueSteeringOverride = resolveClaudeQueueSteeringOverride(sourceEnv);
|
|
1158
1160
|
let harnessVersion: string | undefined;
|
|
1159
1161
|
try {
|
|
1160
|
-
const
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1162
|
+
const probe = registerProcessGroup(
|
|
1163
|
+
Bun.spawn([...effectiveClaudeBinaryArgv, "--version"], {
|
|
1164
|
+
detached: detachedProcessGroup,
|
|
1165
|
+
env: sourceEnv,
|
|
1166
|
+
stdin: "ignore",
|
|
1167
|
+
stdout: "pipe",
|
|
1168
|
+
stderr: "pipe",
|
|
1169
|
+
timeout: CLAUDE_VERSION_PROBE_TIMEOUT_MS,
|
|
1170
|
+
killSignal: "SIGKILL",
|
|
1171
|
+
maxBuffer: CLAUDE_VERSION_PROBE_MAX_BUFFER_BYTES,
|
|
1172
|
+
}),
|
|
1173
|
+
);
|
|
1174
|
+
const exitCode = await probe.exited.finally(() => terminateProcessGroup(probe.pid));
|
|
1175
|
+
const [stdout, stderr] = await Promise.all([
|
|
1176
|
+
new Response(probe.stdout).text(),
|
|
1177
|
+
new Response(probe.stderr).text(),
|
|
1178
|
+
]);
|
|
1179
|
+
if (exitCode === 0) {
|
|
1180
|
+
const trimmed = `${stdout}\n${stderr}`.trim();
|
|
1168
1181
|
if (trimmed) {
|
|
1169
1182
|
harnessVersion = trimmed;
|
|
1170
1183
|
harnessVariantMeta = { version: trimmed };
|
package/src/rbac/admission.ts
CHANGED
|
@@ -15,7 +15,7 @@ export type AdmissionDecision =
|
|
|
15
15
|
| { allow: false; reason: string; verb?: PermissionVerb };
|
|
16
16
|
|
|
17
17
|
export function isRbacEnabled(): boolean {
|
|
18
|
-
return isEnvFlagEnabled("RBAC_ENABLED",
|
|
18
|
+
return isEnvFlagEnabled("RBAC_ENABLED", true);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export function decideAdmission(input: {
|