@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
|
@@ -28,7 +28,7 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
28
28
|
|
|
29
29
|
it("prompts for api url and api key in interactive mode", async () => {
|
|
30
30
|
const promptText = mock(async () => "https://swarm.example.com");
|
|
31
|
-
const promptSecret = mock(async () => "super-secret");
|
|
31
|
+
const promptSecret = mock(async () => "example-super-secret");
|
|
32
32
|
|
|
33
33
|
const result = await resolveCodexLoginConfig([], {
|
|
34
34
|
env: {},
|
|
@@ -39,7 +39,7 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
39
39
|
|
|
40
40
|
expect(result).toEqual({
|
|
41
41
|
apiUrl: "https://swarm.example.com",
|
|
42
|
-
apiKey: "super-secret",
|
|
42
|
+
apiKey: "example-super-secret",
|
|
43
43
|
});
|
|
44
44
|
expect(promptText).toHaveBeenCalledWith("Swarm API URL", "http://localhost:3013");
|
|
45
45
|
expect(promptSecret).toHaveBeenCalledWith(
|
|
@@ -56,7 +56,7 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
56
56
|
const result = await resolveCodexLoginConfig([], {
|
|
57
57
|
env: {
|
|
58
58
|
MCP_BASE_URL: "https://env.example.com",
|
|
59
|
-
API_KEY: "env-secret",
|
|
59
|
+
API_KEY: "example-env-secret",
|
|
60
60
|
},
|
|
61
61
|
isInteractive: true,
|
|
62
62
|
promptText,
|
|
@@ -65,11 +65,11 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
65
65
|
|
|
66
66
|
expect(result).toEqual({
|
|
67
67
|
apiUrl: "https://env.example.com",
|
|
68
|
-
apiKey: "env-secret",
|
|
68
|
+
apiKey: "example-env-secret",
|
|
69
69
|
});
|
|
70
70
|
expect(promptSecret).toHaveBeenCalledWith(
|
|
71
71
|
"Swarm API key",
|
|
72
|
-
"env-secret",
|
|
72
|
+
"example-env-secret",
|
|
73
73
|
"Press Enter to use AGENT_SWARM_API_KEY/API_KEY from the environment",
|
|
74
74
|
);
|
|
75
75
|
});
|
|
@@ -83,11 +83,11 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
const result = await resolveCodexLoginConfig(
|
|
86
|
-
["--api-url", "https://flag.example.com", "--api-key", "flag-secret"],
|
|
86
|
+
["--api-url", "https://flag.example.com", "--api-key", "example-flag-secret"],
|
|
87
87
|
{
|
|
88
88
|
env: {
|
|
89
89
|
MCP_BASE_URL: "https://env.example.com",
|
|
90
|
-
API_KEY: "env-secret",
|
|
90
|
+
API_KEY: "example-env-secret",
|
|
91
91
|
},
|
|
92
92
|
isInteractive: true,
|
|
93
93
|
promptText,
|
|
@@ -97,7 +97,7 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
97
97
|
|
|
98
98
|
expect(result).toEqual({
|
|
99
99
|
apiUrl: "https://flag.example.com",
|
|
100
|
-
apiKey: "flag-secret",
|
|
100
|
+
apiKey: "example-flag-secret",
|
|
101
101
|
});
|
|
102
102
|
expect(promptText).not.toHaveBeenCalled();
|
|
103
103
|
expect(promptSecret).not.toHaveBeenCalled();
|
|
@@ -107,7 +107,7 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
107
107
|
const promptText = mock(async () => {
|
|
108
108
|
throw new Error("should not prompt for api url");
|
|
109
109
|
});
|
|
110
|
-
const promptSecret = mock(async () => "prompted-secret");
|
|
110
|
+
const promptSecret = mock(async () => "example-prompted-secret");
|
|
111
111
|
|
|
112
112
|
const result = await resolveCodexLoginConfig(["--api-url", "https://flag.example.com"], {
|
|
113
113
|
env: {},
|
|
@@ -118,7 +118,7 @@ describe("resolveCodexLoginConfig", () => {
|
|
|
118
118
|
|
|
119
119
|
expect(result).toEqual({
|
|
120
120
|
apiUrl: "https://flag.example.com",
|
|
121
|
-
apiKey: "prompted-secret",
|
|
121
|
+
apiKey: "example-prompted-secret",
|
|
122
122
|
});
|
|
123
123
|
expect(promptText).not.toHaveBeenCalled();
|
|
124
124
|
expect(promptSecret).toHaveBeenCalledTimes(1);
|
|
@@ -186,7 +186,7 @@ describe("runCodexLogin", () => {
|
|
|
186
186
|
await runCodexLogin([], {
|
|
187
187
|
resolveConfig: async () => ({
|
|
188
188
|
apiUrl: "http://localhost:3013",
|
|
189
|
-
apiKey: "test-key",
|
|
189
|
+
apiKey: "example-test-key",
|
|
190
190
|
slot: 3,
|
|
191
191
|
}),
|
|
192
192
|
login: mock(async () => ({
|
|
@@ -214,7 +214,7 @@ describe("runCodexLogin", () => {
|
|
|
214
214
|
await runCodexLogin([], {
|
|
215
215
|
resolveConfig: async () => ({
|
|
216
216
|
apiUrl: "http://localhost:3013",
|
|
217
|
-
apiKey: "test-key",
|
|
217
|
+
apiKey: "example-test-key",
|
|
218
218
|
slot: undefined,
|
|
219
219
|
}),
|
|
220
220
|
login: mock(async () => ({
|
|
@@ -245,7 +245,7 @@ describe("runCodexLogin", () => {
|
|
|
245
245
|
await runCodexLogin([], {
|
|
246
246
|
resolveConfig: async () => ({
|
|
247
247
|
apiUrl: "http://localhost:3013",
|
|
248
|
-
apiKey: "test-key",
|
|
248
|
+
apiKey: "example-test-key",
|
|
249
249
|
slot: 101,
|
|
250
250
|
}),
|
|
251
251
|
login: mock(async () => {
|
|
@@ -274,7 +274,7 @@ describe("runCodexLogin", () => {
|
|
|
274
274
|
await runCodexLogin([], {
|
|
275
275
|
resolveConfig: async () => ({
|
|
276
276
|
apiUrl: "http://localhost:3013",
|
|
277
|
-
apiKey: "test-key",
|
|
277
|
+
apiKey: "example-test-key",
|
|
278
278
|
slot: 10,
|
|
279
279
|
}),
|
|
280
280
|
login: mock(async () => ({
|
|
@@ -306,7 +306,7 @@ describe("runCodexLogin", () => {
|
|
|
306
306
|
await runCodexLogin([], {
|
|
307
307
|
resolveConfig: async () => ({
|
|
308
308
|
apiUrl: "http://localhost:3013",
|
|
309
|
-
apiKey: "test-key",
|
|
309
|
+
apiKey: "example-test-key",
|
|
310
310
|
slot: undefined,
|
|
311
311
|
}),
|
|
312
312
|
login: mock(async () => {
|
|
@@ -31,7 +31,7 @@ import { join } from "node:path";
|
|
|
31
31
|
import { resolveCodexOAuthCredentialInfo } from "../commands/runner";
|
|
32
32
|
|
|
33
33
|
const MOCK_API_URL = "http://localhost:3013";
|
|
34
|
-
const MOCK_API_KEY = "test-api-key";
|
|
34
|
+
const MOCK_API_KEY = "example-test-api-key";
|
|
35
35
|
|
|
36
36
|
const originalFetch = globalThis.fetch;
|
|
37
37
|
const originalHome = process.env.HOME;
|
|
@@ -65,9 +65,9 @@ async function writeStandaloneAuthJson(): Promise<void> {
|
|
|
65
65
|
auth_mode: "chatgpt",
|
|
66
66
|
OPENAI_API_KEY: null,
|
|
67
67
|
tokens: {
|
|
68
|
-
id_token: "id-standalone",
|
|
69
|
-
access_token: "access-standalone",
|
|
70
|
-
refresh_token: "refresh-standalone",
|
|
68
|
+
id_token: "example-id-standalone",
|
|
69
|
+
access_token: "example-access-standalone",
|
|
70
|
+
refresh_token: "example-refresh-standalone",
|
|
71
71
|
account_id: "acct-standalone",
|
|
72
72
|
},
|
|
73
73
|
last_refresh: new Date().toISOString(),
|
|
@@ -24,7 +24,7 @@ const originalApiKey = process.env.AGENT_SWARM_API_KEY;
|
|
|
24
24
|
|
|
25
25
|
beforeAll(async () => {
|
|
26
26
|
initDb(TEST_DB_PATH);
|
|
27
|
-
process.env.AGENT_SWARM_API_KEY = "test-api-key";
|
|
27
|
+
process.env.AGENT_SWARM_API_KEY = "example-test-api-key";
|
|
28
28
|
|
|
29
29
|
lockServer = createServer((req, res) => {
|
|
30
30
|
const url = new URL(req.url ?? "/", "http://internal");
|
|
@@ -159,8 +159,8 @@ describe("POST /api/oauth/keep-warm/codex", () => {
|
|
|
159
159
|
setFetchForTesting(async () => {
|
|
160
160
|
return new Response(
|
|
161
161
|
JSON.stringify({
|
|
162
|
-
access_token: "at_keepwarm",
|
|
163
|
-
refresh_token: "rt_keepwarm",
|
|
162
|
+
access_token: "example-at_keepwarm",
|
|
163
|
+
refresh_token: "example-rt_keepwarm",
|
|
164
164
|
expires_in: 864000,
|
|
165
165
|
}),
|
|
166
166
|
{ status: 200, headers: { "Content-Type": "application/json" } },
|
|
@@ -173,7 +173,7 @@ describe("POST /api/oauth/keep-warm/codex", () => {
|
|
|
173
173
|
const body = JSON.parse(captured.body) as { results: Array<Record<string, unknown>> };
|
|
174
174
|
expect(body.results).toHaveLength(1);
|
|
175
175
|
expect(body.results[0]).toMatchObject({ slot: 1, outcome: "refreshed" });
|
|
176
|
-
expect(slots.get(1)?.access).toBe("at_keepwarm");
|
|
176
|
+
expect(slots.get(1)?.access).toBe("example-at_keepwarm");
|
|
177
177
|
});
|
|
178
178
|
|
|
179
179
|
it("skips a slot with an active codex-auth-watch bench marker", async () => {
|
|
@@ -31,7 +31,7 @@ import type { CodexOAuthCredentials } from "../providers/codex-oauth/types.js";
|
|
|
31
31
|
|
|
32
32
|
const TEST_DB_PATH = "./test-codex-oauth-refresh-lock.sqlite";
|
|
33
33
|
const MOCK_API_URL = "http://localhost:3013";
|
|
34
|
-
const MOCK_API_KEY = "test-api-key";
|
|
34
|
+
const MOCK_API_KEY = "example-test-api-key";
|
|
35
35
|
|
|
36
36
|
process.env.SECRETS_ENCRYPTION_KEY = Buffer.alloc(32, 3).toString("base64");
|
|
37
37
|
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import type { CodexOAuthCredentials } from "../providers/codex-oauth/types.js";
|
|
13
13
|
|
|
14
14
|
const MOCK_API_URL = "http://localhost:3013";
|
|
15
|
-
const MOCK_API_KEY = "test-api-key";
|
|
15
|
+
const MOCK_API_KEY = "example-test-api-key";
|
|
16
16
|
|
|
17
17
|
const mockCreds: CodexOAuthCredentials = {
|
|
18
18
|
access: "at_test123",
|
|
@@ -500,8 +500,8 @@ describe("getValidCodexOAuth", () => {
|
|
|
500
500
|
async () =>
|
|
501
501
|
new Response(
|
|
502
502
|
JSON.stringify({
|
|
503
|
-
access_token: "at_refreshed",
|
|
504
|
-
refresh_token: "rt_refreshed",
|
|
503
|
+
access_token: "example-at_refreshed",
|
|
504
|
+
refresh_token: "example-rt_refreshed",
|
|
505
505
|
expires_in: 3600,
|
|
506
506
|
}),
|
|
507
507
|
{ status: 200 },
|
|
@@ -509,7 +509,7 @@ describe("getValidCodexOAuth", () => {
|
|
|
509
509
|
);
|
|
510
510
|
|
|
511
511
|
const result = await getValidCodexOAuth(MOCK_API_URL, MOCK_API_KEY, 0);
|
|
512
|
-
expect(result?.access).toBe("at_refreshed");
|
|
512
|
+
expect(result?.access).toBe("example-at_refreshed");
|
|
513
513
|
expect(putCapturedKey).toBe("codex_oauth_0");
|
|
514
514
|
});
|
|
515
515
|
|
|
@@ -601,8 +601,8 @@ describe("getValidCodexOAuth", () => {
|
|
|
601
601
|
async () =>
|
|
602
602
|
new Response(
|
|
603
603
|
JSON.stringify({
|
|
604
|
-
access_token: "at_keepwarm_refreshed",
|
|
605
|
-
refresh_token: "rt_keepwarm_refreshed",
|
|
604
|
+
access_token: "example-at_keepwarm_refreshed",
|
|
605
|
+
refresh_token: "example-rt_keepwarm_refreshed",
|
|
606
606
|
expires_in: 3600,
|
|
607
607
|
}),
|
|
608
608
|
{ status: 200 },
|
|
@@ -612,7 +612,7 @@ describe("getValidCodexOAuth", () => {
|
|
|
612
612
|
const result = await getValidCodexOAuth(MOCK_API_URL, MOCK_API_KEY, 0, {
|
|
613
613
|
maxAgeMs: 7 * 24 * 60 * 60 * 1000,
|
|
614
614
|
});
|
|
615
|
-
expect(result?.access).toBe("at_keepwarm_refreshed");
|
|
615
|
+
expect(result?.access).toBe("example-at_keepwarm_refreshed");
|
|
616
616
|
expect(putCapturedKey).toBe("codex_oauth_0");
|
|
617
617
|
});
|
|
618
618
|
|
|
@@ -30,7 +30,7 @@ import type { CodexOAuthCredentials } from "../providers/codex-oauth/types.js";
|
|
|
30
30
|
// ─── Fixtures ────────────────────────────────────────────────────────────────
|
|
31
31
|
|
|
32
32
|
const MOCK_API_URL = "http://localhost:3013";
|
|
33
|
-
const MOCK_API_KEY = "test-api-key";
|
|
33
|
+
const MOCK_API_KEY = "example-test-api-key";
|
|
34
34
|
const FUTURE = Date.now() + 3_600_000;
|
|
35
35
|
|
|
36
36
|
function makeJwt(userId: string, accountId: string): string {
|
|
@@ -9,7 +9,7 @@ import { CHILD_PROCESS_TEST_BUDGET_MS, expectChildOk, runChild } from "./test-pr
|
|
|
9
9
|
|
|
10
10
|
const config: CodexHookConfig = {
|
|
11
11
|
apiUrl: "http://steering.test",
|
|
12
|
-
apiKey: "test-key",
|
|
12
|
+
apiKey: "example-test-key",
|
|
13
13
|
agentId: "11111111-1111-4111-8111-111111111111",
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -19,7 +19,7 @@ const originalFetch = globalThis.fetch;
|
|
|
19
19
|
function buildOpts(override: Partial<CodexSwarmEventHandlerOpts> = {}): CodexSwarmEventHandlerOpts {
|
|
20
20
|
return {
|
|
21
21
|
apiUrl: "http://test-api",
|
|
22
|
-
apiKey: "test-key",
|
|
22
|
+
apiKey: "example-test-key",
|
|
23
23
|
agentId: "agent-1",
|
|
24
24
|
taskId: "task-1",
|
|
25
25
|
abortRef: { current: null },
|
|
@@ -18,7 +18,7 @@ import { listenOnFreePort } from "./test-net";
|
|
|
18
18
|
// WITHOUT agentId — so the bootstrap admin key reached every worker.
|
|
19
19
|
|
|
20
20
|
const TEST_DB_PATH = "./test-config-api-only-keys.sqlite";
|
|
21
|
-
const API_KEY = "test-config-key";
|
|
21
|
+
const API_KEY = "example-test-config-key";
|
|
22
22
|
const BOOTSTRAP_KEY = "API_AGENT_FS_API_KEY";
|
|
23
23
|
const BOOTSTRAP_VALUE = "af_bootstrap_secret_should_never_leak";
|
|
24
24
|
|
|
@@ -7,8 +7,8 @@ import { handleSessions } from "../http/sessions";
|
|
|
7
7
|
import { getPathSegments, parseQueryParams } from "../http/utils";
|
|
8
8
|
import { listenOnFreePort } from "./test-net";
|
|
9
9
|
|
|
10
|
-
const API_KEY = "config-session-test-operator";
|
|
11
|
-
const SECRET = "config-session-test-secret-value";
|
|
10
|
+
const API_KEY = "example-config-session-test-operator";
|
|
11
|
+
const SECRET = "example-config-session-test-secret-value";
|
|
12
12
|
let server: Server;
|
|
13
13
|
let baseUrl: string;
|
|
14
14
|
let workerId: string;
|
|
@@ -55,7 +55,7 @@ const savedEnv = { ...process.env };
|
|
|
55
55
|
|
|
56
56
|
beforeEach(() => {
|
|
57
57
|
clearVolatileSecretsForTesting();
|
|
58
|
-
process.env.AGENT_SWARM_API_KEY = "embedded-auth-test-key";
|
|
58
|
+
process.env.AGENT_SWARM_API_KEY = "example-embedded-auth-test-key";
|
|
59
59
|
delete process.env.API_KEY;
|
|
60
60
|
process.env.MCP_BASE_URL = "http://localhost:3013";
|
|
61
61
|
});
|
|
@@ -101,7 +101,7 @@ describe("embedded connection auth", () => {
|
|
|
101
101
|
kind: "graphql",
|
|
102
102
|
baseUrl: "https://api.vendor.test/graphql",
|
|
103
103
|
allowedHosts: ["api.vendor.test"],
|
|
104
|
-
auth: { type: "bearer", secret: "test-tok-123" },
|
|
104
|
+
auth: { type: "bearer", secret: "example-test-tok-123" },
|
|
105
105
|
});
|
|
106
106
|
createdConnectionIds.push(connection.id);
|
|
107
107
|
|
|
@@ -124,16 +124,16 @@ describe("embedded connection auth", () => {
|
|
|
124
124
|
);
|
|
125
125
|
expect(raw?.isSecret).toBe(1);
|
|
126
126
|
expect(raw?.encrypted).toBe(1);
|
|
127
|
-
expect(raw?.value).not.toBe("test-tok-123");
|
|
127
|
+
expect(raw?.value).not.toBe("example-test-tok-123");
|
|
128
128
|
// Decrypts back to plaintext on read.
|
|
129
129
|
expect((await getSwarmConfigs({ key: "connection.bearerVendor.secret" }))[0]?.value).toBe(
|
|
130
|
-
"test-tok-123",
|
|
130
|
+
"example-test-tok-123",
|
|
131
131
|
);
|
|
132
132
|
|
|
133
133
|
// The broker registers the resolved secret with the scrubber so logs/output
|
|
134
134
|
// only ever show the placeholder — never the raw value.
|
|
135
135
|
await buildScriptCredentialBindings({});
|
|
136
|
-
expect(scrubSecrets("token=test-tok-123")).toContain(
|
|
136
|
+
expect(scrubSecrets("token=example-test-tok-123")).toContain(
|
|
137
137
|
"[REDACTED:connection.bearerVendor.secret]",
|
|
138
138
|
);
|
|
139
139
|
});
|
|
@@ -202,7 +202,7 @@ describe("embedded connection auth", () => {
|
|
|
202
202
|
if (!app) throw new Error("app not created");
|
|
203
203
|
const authorization = await upsertAuthorization({
|
|
204
204
|
appId: app.id,
|
|
205
|
-
accessToken: "oauth-access-token",
|
|
205
|
+
accessToken: "example-oauth-access-token",
|
|
206
206
|
status: "active",
|
|
207
207
|
});
|
|
208
208
|
|
|
@@ -313,7 +313,7 @@ describe("embedded connection auth", () => {
|
|
|
313
313
|
kind: "graphql",
|
|
314
314
|
baseUrl: "https://api.vendor.test/graphql",
|
|
315
315
|
allowedHosts: ["api.vendor.test"],
|
|
316
|
-
auth: { type: "bearer", secret: "slug-secret-1" },
|
|
316
|
+
auth: { type: "bearer", secret: "example-slug-secret-1" },
|
|
317
317
|
});
|
|
318
318
|
createdConnectionIds.push(connection.id);
|
|
319
319
|
expect(await getSwarmConfigs({ key: "connection.slugOne.secret" })).toHaveLength(1);
|
|
@@ -324,17 +324,19 @@ describe("embedded connection auth", () => {
|
|
|
324
324
|
kind: "graphql",
|
|
325
325
|
baseUrl: "https://api.vendor.test/graphql",
|
|
326
326
|
allowedHosts: ["api.vendor.test"],
|
|
327
|
-
auth: { type: "bearer", secret: "slug-secret-2" },
|
|
327
|
+
auth: { type: "bearer", secret: "example-slug-secret-2" },
|
|
328
328
|
});
|
|
329
329
|
expect(renamed.authConfigKey).toBe("connection.slugTwo.secret");
|
|
330
330
|
// Old derived secret is gone; the new one holds the new value.
|
|
331
331
|
expect(await getSwarmConfigs({ key: "connection.slugOne.secret" })).toHaveLength(0);
|
|
332
332
|
expect((await getSwarmConfigs({ key: "connection.slugTwo.secret" }))[0]?.value).toBe(
|
|
333
|
-
"slug-secret-2",
|
|
333
|
+
"example-slug-secret-2",
|
|
334
334
|
);
|
|
335
335
|
// Stale key no longer scrubbed; new key is.
|
|
336
336
|
await buildScriptCredentialBindings({});
|
|
337
|
-
expect(scrubSecrets("v=slug-secret-2")).toContain(
|
|
337
|
+
expect(scrubSecrets("v=example-slug-secret-2")).toContain(
|
|
338
|
+
"[REDACTED:connection.slugTwo.secret]",
|
|
339
|
+
);
|
|
338
340
|
});
|
|
339
341
|
|
|
340
342
|
test("switching an inline-secret connection to oauth deletes the derived inline secret", async () => {
|
|
@@ -351,7 +353,7 @@ describe("embedded connection auth", () => {
|
|
|
351
353
|
if (!app) throw new Error("app not created");
|
|
352
354
|
const authorization = await upsertAuthorization({
|
|
353
355
|
appId: app.id,
|
|
354
|
-
accessToken: "oauth-access-token",
|
|
356
|
+
accessToken: "example-oauth-access-token",
|
|
355
357
|
status: "active",
|
|
356
358
|
});
|
|
357
359
|
|
|
@@ -360,7 +362,7 @@ describe("embedded connection auth", () => {
|
|
|
360
362
|
kind: "graphql",
|
|
361
363
|
baseUrl: "https://api.vendor.test/graphql",
|
|
362
364
|
allowedHosts: ["api.vendor.test"],
|
|
363
|
-
auth: { type: "bearer", secret: "switch-secret" },
|
|
365
|
+
auth: { type: "bearer", secret: "example-switch-secret" },
|
|
364
366
|
});
|
|
365
367
|
createdConnectionIds.push(connection.id);
|
|
366
368
|
expect(await getSwarmConfigs({ key: "connection.switchVendor.secret" })).toHaveLength(1);
|
|
@@ -387,7 +389,7 @@ describe("embedded connection auth", () => {
|
|
|
387
389
|
kind: "graphql",
|
|
388
390
|
baseUrl: "https://api.vendor.test/graphql",
|
|
389
391
|
allowedHosts: ["api.vendor.test"],
|
|
390
|
-
auth: { type: "bearer", secret: "keep-secret" },
|
|
392
|
+
auth: { type: "bearer", secret: "example-keep-secret" },
|
|
391
393
|
});
|
|
392
394
|
createdConnectionIds.push(connection.id);
|
|
393
395
|
|
|
@@ -402,7 +404,7 @@ describe("embedded connection auth", () => {
|
|
|
402
404
|
});
|
|
403
405
|
expect(updated.authConfigKey).toBe("connection.keepVendor.secret");
|
|
404
406
|
expect((await getSwarmConfigs({ key: "connection.keepVendor.secret" }))[0]?.value).toBe(
|
|
405
|
-
"keep-secret",
|
|
407
|
+
"example-keep-secret",
|
|
406
408
|
);
|
|
407
409
|
});
|
|
408
410
|
|
|
@@ -413,7 +415,7 @@ describe("embedded connection auth", () => {
|
|
|
413
415
|
kind: "graphql",
|
|
414
416
|
baseUrl: "https://api.vendor.test/graphql",
|
|
415
417
|
allowedHosts: ["api.vendor.test"],
|
|
416
|
-
auth: { type: "bearer", secret: "rename-secret" },
|
|
418
|
+
auth: { type: "bearer", secret: "example-rename-secret" },
|
|
417
419
|
});
|
|
418
420
|
createdConnectionIds.push(connection.id);
|
|
419
421
|
expect(await getSwarmConfigs({ key: "connection.renameOne.secret" })).toHaveLength(1);
|
|
@@ -689,7 +691,7 @@ describe("embedded connection auth", () => {
|
|
|
689
691
|
kind: "openapi",
|
|
690
692
|
baseUrl: `http://127.0.0.1:${server.port}`,
|
|
691
693
|
openapiSpecJson: openapiSpec(server.port),
|
|
692
|
-
auth: { type: "bearer", secret: "e2e-secret-xyz" },
|
|
694
|
+
auth: { type: "bearer", secret: "example-e2e-secret-xyz" },
|
|
693
695
|
});
|
|
694
696
|
createdConnectionIds.push(connection.id);
|
|
695
697
|
expect(connection.generationError).toBeNull();
|
|
@@ -708,9 +710,9 @@ describe("embedded connection auth", () => {
|
|
|
708
710
|
|
|
709
711
|
expect(output.error).toBeUndefined();
|
|
710
712
|
expect(output.result).toEqual({ ok: true });
|
|
711
|
-
expect(observedAuth).toBe("Bearer e2e-secret-xyz");
|
|
713
|
+
expect(observedAuth).toBe("Bearer example-e2e-secret-xyz");
|
|
712
714
|
// The raw secret never appears in script output/logs — only the placeholder.
|
|
713
|
-
expect(JSON.stringify(output)).not.toContain("e2e-secret-xyz");
|
|
715
|
+
expect(JSON.stringify(output)).not.toContain("example-e2e-secret-xyz");
|
|
714
716
|
} finally {
|
|
715
717
|
server.stop(true);
|
|
716
718
|
}
|
|
@@ -15,7 +15,7 @@ import "../http/trackers/linear";
|
|
|
15
15
|
import "../http/workflows";
|
|
16
16
|
import { listenOnFreePort } from "./test-net";
|
|
17
17
|
|
|
18
|
-
const API_KEY = "test-secret-key";
|
|
18
|
+
const API_KEY = "example-test-secret-key";
|
|
19
19
|
|
|
20
20
|
function createTestServer(apiKey: string): Server {
|
|
21
21
|
return createHttpServer(async (req: IncomingMessage, res: ServerResponse) => {
|
|
@@ -184,14 +184,14 @@ describe("create_page MCP tool", () => {
|
|
|
184
184
|
body: "secret",
|
|
185
185
|
contentType: "text/html",
|
|
186
186
|
authMode: "password",
|
|
187
|
-
password: "open-sesame",
|
|
187
|
+
password: "example-open-sesame",
|
|
188
188
|
},
|
|
189
189
|
fakeMeta,
|
|
190
190
|
);
|
|
191
191
|
const row = await getPageBySlug(agentId, "pw-tool");
|
|
192
192
|
expect(row?.passwordHash).toBeDefined();
|
|
193
|
-
expect(row?.passwordHash).not.toBe("open-sesame");
|
|
194
|
-
expect(await Bun.password.verify("open-sesame", row!.passwordHash!)).toBe(true);
|
|
193
|
+
expect(row?.passwordHash).not.toBe("example-open-sesame");
|
|
194
|
+
expect(await Bun.password.verify("example-open-sesame", row!.passwordHash!)).toBe(true);
|
|
195
195
|
});
|
|
196
196
|
});
|
|
197
197
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
|
|
2
|
+
import {
|
|
3
|
+
CREDENTIAL_RETRY_INTERVAL_MS,
|
|
4
|
+
type CredentialRefreshState,
|
|
5
|
+
refreshCredentialStatus,
|
|
6
|
+
} from "../commands/credential-refresh";
|
|
7
|
+
import * as credentials from "../commands/provider-credentials";
|
|
8
|
+
import type { AgentCredStatus } from "../types";
|
|
9
|
+
|
|
10
|
+
const api = { apiUrl: "http://unused.test", apiKey: "test", agentId: crypto.randomUUID() };
|
|
11
|
+
const ready: AgentCredStatus = {
|
|
12
|
+
ready: true,
|
|
13
|
+
missing: [],
|
|
14
|
+
satisfiedBy: "test",
|
|
15
|
+
hint: null,
|
|
16
|
+
liveTest: null,
|
|
17
|
+
latestModel: null,
|
|
18
|
+
reportedAt: 1,
|
|
19
|
+
reportKind: "post_task",
|
|
20
|
+
bedrock: null,
|
|
21
|
+
acp: null,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe("runner credential refresh", () => {
|
|
25
|
+
let state: CredentialRefreshState;
|
|
26
|
+
let build: ReturnType<typeof spyOn<typeof credentials, "buildCredStatusReport">>;
|
|
27
|
+
let send: ReturnType<typeof spyOn<typeof credentials, "sendCredStatusReport">>;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
state = { harnessProvider: "claude", ready: true, lastRefreshAt: 0, inFlight: false };
|
|
31
|
+
build = spyOn(credentials, "buildCredStatusReport").mockResolvedValue(ready);
|
|
32
|
+
send = spyOn(credentials, "sendCredStatusReport").mockResolvedValue(undefined);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => mock.restore());
|
|
36
|
+
|
|
37
|
+
test("a negative boot snapshot recovers on the retry interval", async () => {
|
|
38
|
+
state.ready = false;
|
|
39
|
+
await refreshCredentialStatus(api, state, "claude", {}, CREDENTIAL_RETRY_INTERVAL_MS - 1);
|
|
40
|
+
expect(build).not.toHaveBeenCalled();
|
|
41
|
+
await refreshCredentialStatus(api, state, "claude", {}, CREDENTIAL_RETRY_INTERVAL_MS);
|
|
42
|
+
expect(send).toHaveBeenCalledTimes(1);
|
|
43
|
+
expect(state.ready).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("a failed readiness write is throttled and retried even when the snapshot is ready", async () => {
|
|
47
|
+
send.mockRejectedValueOnce(new Error("HTTP 503"));
|
|
48
|
+
await expect(refreshCredentialStatus(api, state, "pi", {}, 1)).rejects.toThrow("HTTP 503");
|
|
49
|
+
await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS);
|
|
50
|
+
expect(send).toHaveBeenCalledTimes(1);
|
|
51
|
+
await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS + 1);
|
|
52
|
+
expect(send).toHaveBeenCalledTimes(2);
|
|
53
|
+
expect(state.ready).toBe(true);
|
|
54
|
+
await refreshCredentialStatus(api, state, "pi", {}, 10 * CREDENTIAL_RETRY_INTERVAL_MS);
|
|
55
|
+
expect(build).toHaveBeenCalledTimes(2);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("a failed snapshot build is retried without another provider change", async () => {
|
|
59
|
+
build.mockRejectedValueOnce(new Error("probe failed"));
|
|
60
|
+
await expect(refreshCredentialStatus(api, state, "pi", {}, 1)).rejects.toThrow("probe failed");
|
|
61
|
+
expect(send).not.toHaveBeenCalled();
|
|
62
|
+
await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS);
|
|
63
|
+
expect(build).toHaveBeenCalledTimes(1);
|
|
64
|
+
await refreshCredentialStatus(api, state, "pi", {}, CREDENTIAL_RETRY_INTERVAL_MS + 1);
|
|
65
|
+
expect(send).toHaveBeenCalledTimes(1);
|
|
66
|
+
expect(state.ready).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("CRED_CHECK_DISABLE suppresses provider changes, recovery, and Bedrock refresh", async () => {
|
|
70
|
+
state.ready = false;
|
|
71
|
+
await refreshCredentialStatus(
|
|
72
|
+
api,
|
|
73
|
+
state,
|
|
74
|
+
"pi",
|
|
75
|
+
{ CRED_CHECK_DISABLE: "1", BEDROCK_AUTH_MODE: "sdk" },
|
|
76
|
+
600_000,
|
|
77
|
+
);
|
|
78
|
+
expect(build).not.toHaveBeenCalled();
|
|
79
|
+
expect(send).not.toHaveBeenCalled();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("slow reports cannot overlap or apply an invalidated provider snapshot", async () => {
|
|
83
|
+
let finishBuild!: (snapshot: AgentCredStatus) => void;
|
|
84
|
+
build.mockImplementationOnce(
|
|
85
|
+
() =>
|
|
86
|
+
new Promise((resolve) => {
|
|
87
|
+
finishBuild = resolve;
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
const pending = refreshCredentialStatus(api, state, "pi", {}, 1);
|
|
91
|
+
await refreshCredentialStatus(api, state, "pi", {}, 600_000);
|
|
92
|
+
expect(build).toHaveBeenCalledTimes(1);
|
|
93
|
+
// Same invalidation the runner performs when it swaps adapters mid-check.
|
|
94
|
+
state.harnessProvider = null;
|
|
95
|
+
await refreshCredentialStatus(api, state, "acp", {}, 600_001);
|
|
96
|
+
expect(build).toHaveBeenCalledTimes(1);
|
|
97
|
+
finishBuild(ready);
|
|
98
|
+
await pending;
|
|
99
|
+
expect(send).not.toHaveBeenCalled();
|
|
100
|
+
await refreshCredentialStatus(api, state, "acp", {}, 600_002);
|
|
101
|
+
expect(build).toHaveBeenCalledTimes(2);
|
|
102
|
+
expect(send).toHaveBeenCalledTimes(1);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("Bedrock enumeration retains its five-minute refresh when ready", async () => {
|
|
106
|
+
state.harnessProvider = "pi";
|
|
107
|
+
const env = { BEDROCK_AUTH_MODE: "sdk" };
|
|
108
|
+
await refreshCredentialStatus(api, state, "pi", env, 300_000);
|
|
109
|
+
expect(build).not.toHaveBeenCalled();
|
|
110
|
+
await refreshCredentialStatus(api, state, "pi", env, 300_001);
|
|
111
|
+
expect(build).toHaveBeenCalledTimes(1);
|
|
112
|
+
await refreshCredentialStatus(api, state, "pi", env, 300_002);
|
|
113
|
+
expect(build).toHaveBeenCalledTimes(1);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -221,7 +221,7 @@ describe("awaitCredentials", () => {
|
|
|
221
221
|
const status = await awaitCredentials({
|
|
222
222
|
provider: "claude",
|
|
223
223
|
initialEnv: {},
|
|
224
|
-
refreshEnv: async () => ({ CLAUDE_CODE_OAUTH_TOKEN: "fresh-tok" }),
|
|
224
|
+
refreshEnv: async () => ({ CLAUDE_CODE_OAUTH_TOKEN: "example-fresh-tok" }),
|
|
225
225
|
sleep: async () => {},
|
|
226
226
|
log: log.fn,
|
|
227
227
|
backoff: { initialMs: 1, maxMs: 1, maxWaitSeconds: 0 },
|
|
@@ -229,7 +229,7 @@ describe("awaitCredentials", () => {
|
|
|
229
229
|
|
|
230
230
|
expect(status.ready).toBe(true);
|
|
231
231
|
// After the loop returns ready, process.env reflects the fresh value.
|
|
232
|
-
expect(process.env.CLAUDE_CODE_OAUTH_TOKEN).toBe("fresh-tok");
|
|
232
|
+
expect(process.env.CLAUDE_CODE_OAUTH_TOKEN).toBe("example-fresh-tok");
|
|
233
233
|
});
|
|
234
234
|
|
|
235
235
|
test("backoff config falls back to env-var defaults when override absent", async () => {
|
|
@@ -12,7 +12,7 @@ describe("validateClaudeCredentials", () => {
|
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
test("returns 'api_key' when only ANTHROPIC_API_KEY is set", () => {
|
|
15
|
-
expect(validateClaudeCredentials({ ANTHROPIC_API_KEY: "sk-ant-123" })).toBe("api_key");
|
|
15
|
+
expect(validateClaudeCredentials({ ANTHROPIC_API_KEY: "example-sk-ant-123" })).toBe("api_key");
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
test("prefers oauth over api_key when both are set", () => {
|
|
@@ -52,19 +52,21 @@ describe("validateOpencodeCredentials", () => {
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
test("returns 'openrouter_api_key' when OPENROUTER_API_KEY is set", () => {
|
|
55
|
-
expect(validateOpencodeCredentials({ OPENROUTER_API_KEY: "sk-or-123" })).toBe(
|
|
55
|
+
expect(validateOpencodeCredentials({ OPENROUTER_API_KEY: "example-sk-or-123" })).toBe(
|
|
56
56
|
"openrouter_api_key",
|
|
57
57
|
);
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
test("returns 'anthropic_api_key' when only ANTHROPIC_API_KEY is set", () => {
|
|
61
|
-
expect(validateOpencodeCredentials({ ANTHROPIC_API_KEY: "sk-ant-123" })).toBe(
|
|
61
|
+
expect(validateOpencodeCredentials({ ANTHROPIC_API_KEY: "example-sk-ant-123" })).toBe(
|
|
62
62
|
"anthropic_api_key",
|
|
63
63
|
);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
66
|
test("returns 'openai_api_key' when only OPENAI_API_KEY is set", () => {
|
|
67
|
-
expect(validateOpencodeCredentials({ OPENAI_API_KEY: "sk-openai-123" })).toBe(
|
|
67
|
+
expect(validateOpencodeCredentials({ OPENAI_API_KEY: "example-sk-openai-123" })).toBe(
|
|
68
|
+
"openai_api_key",
|
|
69
|
+
);
|
|
68
70
|
});
|
|
69
71
|
|
|
70
72
|
test("returns 'auth_file' when auth.json exists and no env vars are set", () => {
|