@desplega.ai/agent-swarm 1.149.0 → 1.150.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 +7 -3
- package/dist/{acp-adapter-4jncb126.js → acp-adapter-d5mzggyk.js} +1 -1
- package/dist/{actions-31vp3ae7.js → actions-wn6ew0p7.js} +11 -10
- package/dist/{anthropic-messages-vs2rabzp.js → anthropic-messages-ec35ktvx.js} +4 -4
- package/dist/{app-1hh67x8w.js → app-dty7p9hg.js} +7 -7
- package/dist/{artifact-gj9arwrr.js → artifact-td4q4dch.js} +1 -1
- package/dist/{assistant-z66dmz6p.js → assistant-q4vhgjtx.js} +16 -17
- package/dist/{boot-reembed-wxa8ya0s.js → boot-reembed-92292pgf.js} +9 -9
- package/dist/{boot-reembed-fqzxxzjh.js → boot-reembed-n15q6s9x.js} +8 -8
- package/dist/{boot-scrub-logs-jnyndh79.js → boot-scrub-logs-44pc955m.js} +5 -5
- package/dist/{claude-adapter-3qpa9w0j.js → claude-adapter-cjegjbje.js} +14 -14
- package/dist/{claude-managed-adapter-qvsmh6mv.js → claude-managed-adapter-p3ts5m9m.js} +2 -2
- package/dist/{claude-sdk-session-2yxgjs5d.js → claude-sdk-session-7ywbn12v.js} +14 -14
- package/dist/{cli-cr12paw2.js → cli-111ey3ra.js} +5 -5
- package/dist/{cli-4wtq5jjv.js → cli-1mx65de9.js} +1 -1
- package/dist/{cli-9d8ntetj.js → cli-2658f6at.js} +1 -1
- package/dist/{cli-n3dz2942.js → cli-3ckzxdt1.js} +10 -6
- package/dist/{cli-yb9qhqam.js → cli-3mh119qv.js} +184 -67
- package/dist/{cli-ykxrnd1q.js → cli-72xdszyx.js} +2 -2
- package/dist/{cli-xm87hzbw.js → cli-7fesa1ky.js} +1 -1
- package/dist/{cli-3q5ejx9p.js → cli-7kwmt3r5.js} +2 -2
- package/dist/{cli-2qts1hys.js → cli-8chp8xab.js} +2 -2
- package/dist/{cli-qaacms9y.js → cli-9gqddmxs.js} +122 -97
- package/dist/{cli-zvz62chv.js → cli-a45d5v9b.js} +4 -4
- package/dist/{cli-9xvdm3bx.js → cli-asvrh7kj.js} +1 -1
- package/dist/{cli-kgz4np97.js → cli-b8x19vbh.js} +4 -4
- package/dist/{cli-9fy6nk6g.js → cli-ceb5y160.js} +1 -1
- package/dist/{cli-k0cr4kat.js → cli-ck1vqzdj.js} +1 -1
- package/dist/{cli-e29gmdmw.js → cli-dv6cdjs2.js} +2 -1
- package/dist/{cli-jecc01cb.js → cli-dyx0237s.js} +1 -1
- package/dist/{cli-kjwt6hdf.js → cli-gm0fhz13.js} +3 -3
- package/dist/{cli-sd5pv3b1.js → cli-h505yhex.js} +2 -2
- package/dist/{handlers-nbzdzn9k.js → cli-hbagregr.js} +15 -38
- package/dist/{cli-08b07b4r.js → cli-hmyynq9b.js} +1 -1
- package/dist/{cli-d8ftsp62.js → cli-kt7wevqh.js} +20 -13
- package/dist/{cli-gjhjfeeg.js → cli-kyysm7m3.js} +1 -1
- package/dist/{cli-1ebpar1q.js → cli-mzb0n642.js} +6 -6
- package/dist/{cli-q50ef8g0.js → cli-n1yj5fd5.js} +1 -1
- package/dist/{cli-3apbzgyk.js → cli-n75jt793.js} +13 -9
- package/dist/{cli-19f354qr.js → cli-q04q68be.js} +2 -2
- package/dist/{cli-yab68w40.js → cli-qp69dd5d.js} +29 -14
- package/dist/{cli-6pqcb4q0.js → cli-rnsr8asm.js} +12 -11
- package/dist/{cli-ygweqcn4.js → cli-rwp3ksm7.js} +91 -108
- package/dist/{cli-phsxnkp6.js → cli-ryz8q8p1.js} +74 -58
- package/dist/{cli-e95cx1eb.js → cli-taym3dmg.js} +10 -10
- package/dist/{cli-nye12xk5.js → cli-ttje5a4z.js} +7 -4
- package/dist/{cli-9hspd3dp.js → cli-vr6qj104.js} +1 -1
- package/dist/{cli-mnmsfd1w.js → cli-xjb9wghj.js} +7 -3
- package/dist/{cli-gv88e1vf.js → cli-ydk0wjj8.js} +1 -1
- package/dist/{cli-aae6hz6a.js → cli-zd21jrrc.js} +3 -3
- package/dist/{cli-7smrsr25.js → cli-zthatyrx.js} +23 -11
- package/dist/cli.js +19 -19
- package/dist/{codex-adapter-8meawydj.js → codex-adapter-rn3aq7jm.js} +7 -7
- package/dist/{codex-hook-hfrt9shr.js → codex-hook-gthcmm0g.js} +3 -3
- package/dist/{codex-session-runner-gjgxyp5j.js → codex-session-runner-bge0cbsw.js} +7 -7
- package/dist/{commands-hz3nb95f.js → commands-26phw0pc.js} +5 -5
- package/dist/{db-ggz97zbm.js → db-jxjx6s1b.js} +6 -6
- package/dist/{e2b-p04vmtx0.js → e2b-413b8t4v.js} +1 -1
- package/dist/handlers-vr1djg4n.js +41 -0
- package/dist/{hook-bks2q1f6.js → hook-jw0ztn96.js} +9 -9
- package/dist/{hook-kq9wp0ep.js → hook-t6fqsggw.js} +10 -10
- package/dist/{http-hrf77v87.js → http-hyc7s57s.js} +80 -71
- package/dist/{index-n28pw1zt.js → index-1d9r6a74.js} +18 -18
- package/dist/{index-cqtebbhb.js → index-bcyx5djw.js} +17 -17
- package/dist/{index-6nsbg88z.js → index-sfhaq59d.js} +408 -74
- package/dist/{index-8hmeg8j1.js → index-wtwpthe1.js} +17 -17
- package/dist/{keepalive-dxc12gvg.js → keepalive-fbsak4ya.js} +7 -7
- package/dist/{lead-yckfn18d.js → lead-rdzdm627.js} +39 -39
- package/dist/{maintenance-6kfb2m5e.js → maintenance-25z1c1vf.js} +9 -9
- package/dist/{node-x1g4v0pq.js → node-209sxmg3.js} +9 -9
- package/dist/{oauth-refresh-sweep-1x1ac722.js → oauth-refresh-sweep-j3d7gtse.js} +6 -6
- package/dist/{onboard-dcyt1609.js → onboard-dkcwrc75.js} +2 -2
- package/dist/{otel-impl-tbk3e5dr.js → otel-impl-8rgyy3j8.js} +1 -1
- package/dist/{pi-mono-adapter-zvshk5cj.js → pi-mono-adapter-4s2bbkgq.js} +8 -8
- package/dist/{pricing-refresh-kaqg567e.js → pricing-refresh-9cek71nq.js} +7 -7
- package/dist/{rbac-roles-cf97v1vd.js → rbac-roles-vk8mqp9v.js} +6 -6
- package/dist/{rbac-roles-ammq6rd2.js → rbac-roles-z98s2ypy.js} +5 -5
- package/dist/{render-v2-80w603vy.js → render-v2-3j26g0qh.js} +7 -7
- package/dist/{seed-pricing-zbrn83xv.js → seed-pricing-7rxhcnzm.js} +6 -6
- package/dist/{setup-fe66kczs.js → setup-e2t7vz0c.js} +2 -2
- package/dist/work-objects-8d3nd3x2.js +141 -0
- package/dist/{worker-qmb2d1e2.js → worker-0x9fn7nq.js} +39 -39
- package/openapi.json +15 -4
- package/package.json +3 -3
- package/src/agentmail/handlers.ts +5 -0
- 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.ts +4 -2
- 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/scripts/typecheck.ts +7 -3
- package/src/be/seed/automation-toggle.ts +69 -0
- package/src/be/seed/schedules-seeder.ts +53 -8
- package/src/be/seed/workflows-seeder.ts +35 -6
- package/src/be/seed-scripts/catalog/delegate.ts +3 -1
- package/src/be/seed-skills/bundled-files.generated.json +1 -1
- package/src/be/steering.ts +1 -0
- package/src/be/swarm-config-guard.ts +1 -0
- package/src/commands/credential-refresh.ts +70 -0
- package/src/commands/provider-credentials.ts +2 -25
- package/src/commands/runner.ts +23 -56
- package/src/github/handlers.ts +9 -0
- package/src/gitlab/handlers.ts +4 -0
- package/src/heartbeat/heartbeat.ts +3 -0
- package/src/http/approval-requests.ts +1 -0
- package/src/http/apps.ts +1 -0
- package/src/http/config.ts +4 -1
- package/src/http/core.ts +4 -2
- package/src/http/index.ts +16 -3
- package/src/http/script-runs.ts +5 -0
- package/src/http/tasks.ts +5 -0
- package/src/integrations/kapso/inbound.ts +1 -0
- package/src/jira/sync.ts +2 -0
- package/src/linear/sync.ts +2 -0
- package/src/prompts/session-templates.ts +13 -9
- package/src/providers/claude-adapter.ts +21 -8
- package/src/scheduler/deferred-task-waits.ts +34 -5
- package/src/scheduler/schedule-task.ts +5 -1
- package/src/scheduler/scheduler.ts +104 -123
- package/src/scripts-runtime/types/stdlib.d.ts +7 -3
- package/src/scripts-runtime/types/swarm-sdk.d.ts +7 -3
- package/src/slack/HEURISTICS.md +2 -0
- package/src/slack/actions.ts +1 -0
- package/src/slack/app.ts +2 -0
- package/src/slack/assistant.ts +4 -12
- package/src/slack/handlers.ts +9 -14
- package/src/slack/inbound-files.ts +3 -3
- package/src/slack/render-v2.ts +17 -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/worker-follow-up.ts +4 -0
- 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 +6 -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 +190 -1
- package/src/tests/devin-adapter.test.ts +1 -1
- package/src/tests/devin-api.test.ts +1 -1
- 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/events-http.test.ts +1 -1
- 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-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-registration.test.ts +97 -3
- 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 +3 -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/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 +1 -1
- package/src/tests/rbac-charact-http.test.ts +1 -1
- package/src/tests/rbac-e2e-helpers.ts +1 -1
- package/src/tests/realtime-room-surfaces.test.ts +1 -1
- package/src/tests/reload-config.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 +1 -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-external-api.test.ts +1 -1
- package/src/tests/scripts-http.test.ts +1 -1
- package/src/tests/scripts-mcp-e2e.test.ts +1 -1
- package/src/tests/scripts-only-gating.test.ts +2 -2
- package/src/tests/scripts-retention.test.ts +1 -1
- package/src/tests/scripts-runtime-identity.test.ts +1 -1
- 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 +139 -8
- package/src/tests/seed-workflows.test.ts +93 -7
- 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-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 +120 -1
- package/src/tests/status.test.ts +7 -7
- package/src/tests/steering-core.test.ts +1 -1
- 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-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-output-agent-id.test.ts +1 -0
- 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/send-task.ts +21 -1
- package/src/tools/skills/skill-publish.ts +1 -0
- package/src/tools/store-progress.ts +1 -1
- package/src/tools/templates.ts +2 -1
- package/src/types.ts +11 -0
- package/src/utils/constants.ts +7 -1
- package/src/utils/credentials.test.ts +16 -16
- package/src/workflows/executors/agent-task.ts +5 -0
- package/templates/ai-toolbox.manifest.json +7 -1
- package/templates/schedules/daily-blocker-digest/config.json +6 -1
- package/templates/schedules/daily-compounding-reflection/config.json +1 -0
- package/templates/schedules/daily-hn-briefing/config.json +1 -1
- package/templates/schedules/daily-status-report/config.json +6 -1
- package/templates/schedules/daily-swarm-update-check/config.json +19 -0
- package/templates/schedules/daily-swarm-update-check/content.md +49 -0
- package/templates/schedules/daily-workflow-health-audit/config.json +6 -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/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-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/{azure-openai-responses-cqar64rc.js → azure-openai-responses-g85jv7m8.js} +8 -8
- package/dist/{cli-4xz3pmrq.js → cli-8qx7jnrk.js} +5 -5
- package/dist/{cli-6664w7y4.js → cli-wk0gjrn3.js} +3 -3
- package/dist/{google-vertex-ppw8ydpa.js → google-vertex-pkhpkbq9.js} +3 -3
- package/dist/{openai-codex-responses-g7w48y30.js → openai-codex-responses-pm5gnyfa.js} +4 -4
- package/dist/{openai-completions-0bqmsajw.js → openai-completions-qdcmkfnr.js} +12 -12
- package/dist/{openai-responses-nmeyptke.js → openai-responses-vwvk1taj.js} +13 -13
package/src/tests/status.test.ts
CHANGED
|
@@ -245,13 +245,13 @@ describe("setup milestones", () => {
|
|
|
245
245
|
hint: "Memory search is off. Set OPENAI_API_KEY (or EMBEDDING_API_KEY) on the API server to enable it; it is cheap.",
|
|
246
246
|
});
|
|
247
247
|
|
|
248
|
-
process.env.OPENAI_API_KEY = "openai-embedding-key";
|
|
248
|
+
process.env.OPENAI_API_KEY = "example-openai-embedding-key";
|
|
249
249
|
expect(getMilestone(await buildStatusPayload(), "embeddings").state).toBe("configured");
|
|
250
250
|
|
|
251
251
|
process.env.EMBEDDING_API_KEY = "";
|
|
252
252
|
expect(getMilestone(await buildStatusPayload(), "embeddings").state).toBe("unverified");
|
|
253
253
|
|
|
254
|
-
process.env.EMBEDDING_API_KEY = "dedicated-embedding-key";
|
|
254
|
+
process.env.EMBEDDING_API_KEY = "example-dedicated-embedding-key";
|
|
255
255
|
delete process.env.OPENAI_API_KEY;
|
|
256
256
|
expect(getMilestone(await buildStatusPayload(), "embeddings").state).toBe("configured");
|
|
257
257
|
});
|
|
@@ -417,7 +417,7 @@ describe("setup milestones", () => {
|
|
|
417
417
|
const a = await buildStatusPayload();
|
|
418
418
|
expect(getMilestone(a, "github").state).toBe("unverified");
|
|
419
419
|
|
|
420
|
-
process.env.GITHUB_APP_PRIVATE_KEY = "
|
|
420
|
+
process.env.GITHUB_APP_PRIVATE_KEY = "[REDACTED:github_app_private_key]";
|
|
421
421
|
const b = await buildStatusPayload();
|
|
422
422
|
expect(getMilestone(b, "github").state).toBe("verified");
|
|
423
423
|
});
|
|
@@ -456,7 +456,7 @@ describe("setup milestones", () => {
|
|
|
456
456
|
scopes: "read",
|
|
457
457
|
});
|
|
458
458
|
await storeOAuthTokens("linear", {
|
|
459
|
-
accessToken: "lin-tok-xyz",
|
|
459
|
+
accessToken: "example-lin-tok-xyz",
|
|
460
460
|
refreshToken: "ref",
|
|
461
461
|
expiresAt: new Date(Date.now() + 3600_000).toISOString(),
|
|
462
462
|
scope: "read",
|
|
@@ -475,7 +475,7 @@ describe("setup milestones", () => {
|
|
|
475
475
|
// metadata intentionally omitted on first upsert
|
|
476
476
|
});
|
|
477
477
|
await storeOAuthTokens("jira", {
|
|
478
|
-
accessToken: "jira-tok",
|
|
478
|
+
accessToken: "example-jira-tok",
|
|
479
479
|
refreshToken: null,
|
|
480
480
|
expiresAt: new Date(Date.now() + 3600_000).toISOString(),
|
|
481
481
|
scope: null,
|
|
@@ -831,7 +831,7 @@ describe("validateProviderCredentials — error scrubbing", () => {
|
|
|
831
831
|
});
|
|
832
832
|
|
|
833
833
|
test("devin hits v3/self (not the deprecated v1 endpoint) and passes on 2xx", async () => {
|
|
834
|
-
process.env.DEVIN_API_KEY = "cog_fake-devin-key-1234";
|
|
834
|
+
process.env.DEVIN_API_KEY = "example-cog_fake-devin-key-1234";
|
|
835
835
|
let capturedUrl = "";
|
|
836
836
|
globalThis.fetch = (async (url) => {
|
|
837
837
|
capturedUrl = String(url);
|
|
@@ -851,7 +851,7 @@ describe("validateProviderCredentials — error scrubbing", () => {
|
|
|
851
851
|
});
|
|
852
852
|
|
|
853
853
|
test("scrubs api key from error message on 401 response", async () => {
|
|
854
|
-
const fakeKey = "
|
|
854
|
+
const fakeKey = "example-anthropic-key-do-not-leak";
|
|
855
855
|
process.env.ANTHROPIC_API_KEY = fakeKey;
|
|
856
856
|
globalThis.fetch = (async () =>
|
|
857
857
|
new Response(`Unauthorized: invalid key ${fakeKey}`, {
|
|
@@ -413,7 +413,7 @@ describe("task steering core", () => {
|
|
|
413
413
|
|
|
414
414
|
test("scrubs secrets before persisting the steering body", async () => {
|
|
415
415
|
const previous = process.env.OPENAI_API_KEY;
|
|
416
|
-
const secret = "
|
|
416
|
+
const secret = "example-steering-secret-value";
|
|
417
417
|
process.env.OPENAI_API_KEY = secret;
|
|
418
418
|
try {
|
|
419
419
|
const task = await runningTask("pi", "secret scrubbing");
|
|
@@ -233,7 +233,7 @@ describe("steering worker transport", () => {
|
|
|
233
233
|
|
|
234
234
|
test("scrubs provider errors before reporting an undeliverable reason", async () => {
|
|
235
235
|
const pending = pendingMessage();
|
|
236
|
-
const secret =
|
|
236
|
+
const secret = `sk-proj-${"steering".repeat(4)}`;
|
|
237
237
|
let reportedBody = "";
|
|
238
238
|
const fetchImpl = (async (input: string | URL | Request, init?: RequestInit) => {
|
|
239
239
|
if (String(input).includes("/api/steering-messages?")) {
|
|
@@ -280,7 +280,7 @@ describe("steering worker transport", () => {
|
|
|
280
280
|
expect(requested.outcome).toBe("queued");
|
|
281
281
|
|
|
282
282
|
await pollAndDispatchSteering(
|
|
283
|
-
{ apiUrl: baseUrl, apiKey: "test-key", agentId: agent.id },
|
|
283
|
+
{ apiUrl: baseUrl, apiKey: "example-test-key", agentId: agent.id },
|
|
284
284
|
task.id,
|
|
285
285
|
session(),
|
|
286
286
|
createSteeringDispatchState(),
|
|
@@ -327,7 +327,7 @@ describe("steering worker transport", () => {
|
|
|
327
327
|
// undeliverable — but the external-delivery flag short-circuits the poll.
|
|
328
328
|
const codexLikeSession = { ...session(), steeringDeliveredExternally: true };
|
|
329
329
|
await pollAndDispatchSteering(
|
|
330
|
-
{ apiUrl: baseUrl, apiKey: "test-key", agentId: agent.id },
|
|
330
|
+
{ apiUrl: baseUrl, apiKey: "example-test-key", agentId: agent.id },
|
|
331
331
|
task.id,
|
|
332
332
|
codexLikeSession,
|
|
333
333
|
createSteeringDispatchState(),
|
|
@@ -343,7 +343,7 @@ describe("steering worker transport", () => {
|
|
|
343
343
|
const previousBaseUrl = process.env.MCP_BASE_URL;
|
|
344
344
|
const previousApiKey = process.env.AGENT_SWARM_API_KEY;
|
|
345
345
|
process.env.MCP_BASE_URL = baseUrl;
|
|
346
|
-
process.env.AGENT_SWARM_API_KEY = "test-key";
|
|
346
|
+
process.env.AGENT_SWARM_API_KEY = "example-test-key";
|
|
347
347
|
try {
|
|
348
348
|
const agent = await createAgent({
|
|
349
349
|
name: "accept steering worker",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import type * as z from "zod";
|
|
4
|
+
import { registerStoreProgressTool } from "../tools/store-progress";
|
|
5
|
+
|
|
6
|
+
describe("store-progress output guidance", () => {
|
|
7
|
+
const server = new McpServer({ name: "output-guidance-test", version: "1.0.0" });
|
|
8
|
+
registerStoreProgressTool(server);
|
|
9
|
+
const tools = (
|
|
10
|
+
server as unknown as {
|
|
11
|
+
_registeredTools: Record<string, { inputSchema: z.ZodObject }>;
|
|
12
|
+
}
|
|
13
|
+
)._registeredTools;
|
|
14
|
+
const outputSchema = tools["store-progress"].inputSchema.shape.output;
|
|
15
|
+
|
|
16
|
+
test("the exposed output field carries the same budget and exceptions as the prompts", () => {
|
|
17
|
+
expect(outputSchema.description).toContain("Keep free-text output under 120 words by default");
|
|
18
|
+
expect(outputSchema.description).toContain("published verbatim in the thread's outcome card");
|
|
19
|
+
expect(outputSchema.description).toContain("every artifact link");
|
|
20
|
+
expect(outputSchema.description).toContain("Link documents instead of inlining them");
|
|
21
|
+
expect(outputSchema.description).toContain(
|
|
22
|
+
"requested depth, enumerated results, essential evidence",
|
|
23
|
+
);
|
|
24
|
+
expect(outputSchema.description).toContain("the task's outputSchema requires longer output");
|
|
25
|
+
expect(outputSchema.description).toContain("output must be JSON matching it");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("the style target does not reject longer requested or schema-constrained output", () => {
|
|
29
|
+
const longResult = "Required result. ".repeat(150);
|
|
30
|
+
for (const output of [longResult, JSON.stringify({ results: [longResult] })]) {
|
|
31
|
+
expect(outputSchema.parse(output)).toBe(output);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -111,38 +111,38 @@ describe("finalizeSwarmToolResult", () => {
|
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
test("secrets are scrubbed from message, details, and data at the egress point", async () => {
|
|
114
|
-
registerVolatileSecret("sk-super-secret-token-123", "TEST_TOKEN");
|
|
114
|
+
registerVolatileSecret("example-sk-super-secret-token-123", "TEST_TOKEN");
|
|
115
115
|
try {
|
|
116
116
|
const result = await finalizeSwarmToolResult("some-tool", {
|
|
117
117
|
ok: false,
|
|
118
|
-
message: "Auth failed with sk-super-secret-token-123",
|
|
119
|
-
details: "header was sk-super-secret-token-123",
|
|
120
|
-
data: { token: "sk-super-secret-token-123" },
|
|
118
|
+
message: "Auth failed with example-sk-super-secret-token-123",
|
|
119
|
+
details: "header was example-sk-super-secret-token-123",
|
|
120
|
+
data: { token: "example-sk-super-secret-token-123" },
|
|
121
121
|
});
|
|
122
122
|
const serialized = JSON.stringify(result);
|
|
123
|
-
expect(serialized).not.toContain("sk-super-secret-token-123");
|
|
123
|
+
expect(serialized).not.toContain("example-sk-super-secret-token-123");
|
|
124
124
|
} finally {
|
|
125
125
|
clearVolatileSecretsForTesting();
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
test("allowSecretEgress skips scrubbing for deliberate credential reveals only", async () => {
|
|
130
|
-
registerVolatileSecret("xsk_reveal_me_once_456", "TEST_REVEAL");
|
|
130
|
+
registerVolatileSecret("example-xsk_reveal_me_once_456", "TEST_REVEAL");
|
|
131
131
|
try {
|
|
132
132
|
const revealed = await finalizeSwarmToolResult("script-apis", {
|
|
133
133
|
ok: true,
|
|
134
134
|
message: "Endpoint created.",
|
|
135
|
-
details: "Bearer token (shown once — save it now): xsk_reveal_me_once_456",
|
|
136
|
-
data: { token: "xsk_reveal_me_once_456" },
|
|
135
|
+
details: "Bearer token (shown once — save it now): example-xsk_reveal_me_once_456",
|
|
136
|
+
data: { token: "example-xsk_reveal_me_once_456" },
|
|
137
137
|
allowSecretEgress: true,
|
|
138
138
|
});
|
|
139
|
-
expect(JSON.stringify(revealed)).toContain("xsk_reveal_me_once_456");
|
|
139
|
+
expect(JSON.stringify(revealed)).toContain("example-xsk_reveal_me_once_456");
|
|
140
140
|
|
|
141
141
|
const scrubbed = await finalizeSwarmToolResult("some-tool", {
|
|
142
142
|
ok: true,
|
|
143
|
-
message: "leaky xsk_reveal_me_once_456",
|
|
143
|
+
message: "leaky example-xsk_reveal_me_once_456",
|
|
144
144
|
});
|
|
145
|
-
expect(JSON.stringify(scrubbed)).not.toContain("xsk_reveal_me_once_456");
|
|
145
|
+
expect(JSON.stringify(scrubbed)).not.toContain("example-xsk_reveal_me_once_456");
|
|
146
146
|
} finally {
|
|
147
147
|
clearVolatileSecretsForTesting();
|
|
148
148
|
}
|
|
@@ -36,12 +36,14 @@ afterEach(() => {
|
|
|
36
36
|
|
|
37
37
|
describe("swarm_x MCP tool", () => {
|
|
38
38
|
test("routes composio requests with server-side auth and scrubbed output", async () => {
|
|
39
|
-
process.env.COMPOSIO_API_KEY = "ck_tool_secret_value";
|
|
39
|
+
process.env.COMPOSIO_API_KEY = "example-ck_tool_secret_value";
|
|
40
40
|
const fetchMock = mock(async (url: string | URL | Request, init?: RequestInit) => {
|
|
41
41
|
expect(String(url)).toBe("https://backend.composio.dev/api/v3.1/tools?limit=1");
|
|
42
42
|
expect(init?.method).toBe("GET");
|
|
43
|
-
expect((init?.headers as Record<string, string>)["x-api-key"]).toBe(
|
|
44
|
-
|
|
43
|
+
expect((init?.headers as Record<string, string>)["x-api-key"]).toBe(
|
|
44
|
+
"example-ck_tool_secret_value",
|
|
45
|
+
);
|
|
46
|
+
return jsonResponse({ ok: true, token: "example-ck_tool_secret_value" });
|
|
45
47
|
});
|
|
46
48
|
globalThis.fetch = fetchMock;
|
|
47
49
|
|
|
@@ -65,11 +67,11 @@ describe("swarm_x MCP tool", () => {
|
|
|
65
67
|
expect(JSON.stringify(result.structuredContent.response)).toContain(
|
|
66
68
|
"[REDACTED:COMPOSIO_API_KEY]",
|
|
67
69
|
);
|
|
68
|
-
expect(result.structuredContent.responseText).not.toContain("ck_tool_secret_value");
|
|
70
|
+
expect(result.structuredContent.responseText).not.toContain("example-ck_tool_secret_value");
|
|
69
71
|
});
|
|
70
72
|
|
|
71
73
|
test("rejects absolute composio paths", async () => {
|
|
72
|
-
process.env.COMPOSIO_API_KEY = "ck_tool_secret_value";
|
|
74
|
+
process.env.COMPOSIO_API_KEY = "example-ck_tool_secret_value";
|
|
73
75
|
const fetchMock = mock(async () => jsonResponse({ ok: true }));
|
|
74
76
|
globalThis.fetch = fetchMock;
|
|
75
77
|
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
type Manifest,
|
|
11
11
|
type PathRewrite,
|
|
12
12
|
parseSkillMd,
|
|
13
|
+
rewriteBundledFileComments,
|
|
13
14
|
rewriteSkillReferences,
|
|
14
15
|
sanitizeSyncedVia,
|
|
15
16
|
stableJson,
|
|
@@ -215,6 +216,24 @@ describe("ai-toolbox skill sync pure transforms", () => {
|
|
|
215
216
|
).toThrow("exceed 10485760 bytes total");
|
|
216
217
|
});
|
|
217
218
|
|
|
219
|
+
test("clarifies only the Codex helper comment and preserves executable sandbox settings", () => {
|
|
220
|
+
const comment =
|
|
221
|
+
"# CODEX_SANDBOX default: workspace-write read-only | workspace-write | danger-full-access";
|
|
222
|
+
const executable = `SANDBOX="\${CODEX_SANDBOX:-workspace-write}"\nargs+=( --dangerously-bypass-approvals-and-sandbox )\n`;
|
|
223
|
+
const source = `${comment}\n${executable}`;
|
|
224
|
+
expect(rewriteBundledFileComments("delegate-work", "scripts/codex-exec.sh", source)).toBe(
|
|
225
|
+
`# CODEX_SANDBOX default: workspace-write (passed to codex's -s option)\n${executable}`,
|
|
226
|
+
);
|
|
227
|
+
expect(rewriteBundledFileComments("other", "scripts/codex-exec.sh", source)).toBe(source);
|
|
228
|
+
expect(rewriteBundledFileComments("delegate-work", "scripts/other.sh", source)).toBe(source);
|
|
229
|
+
expect(() =>
|
|
230
|
+
rewriteBundledFileComments("delegate-work", "scripts/codex-exec.sh", executable),
|
|
231
|
+
).toThrow("expected one upstream sandbox default comment");
|
|
232
|
+
expect(() =>
|
|
233
|
+
rewriteBundledFileComments("delegate-work", "scripts/codex-exec.sh", `${comment}\n${source}`),
|
|
234
|
+
).toThrow("expected one upstream sandbox default comment");
|
|
235
|
+
});
|
|
236
|
+
|
|
218
237
|
test("reports executable text downgrades and rejects binary files", () => {
|
|
219
238
|
const executable = validateBundledFileBytes(
|
|
220
239
|
"fixture",
|
|
@@ -645,7 +645,7 @@ describe("Task Supersede + Resume", () => {
|
|
|
645
645
|
test("scrubs secret-shaped values from session-log summaries", async () => {
|
|
646
646
|
// GitHub PAT-shaped token — matches a structural pattern in
|
|
647
647
|
// scrubSecrets (regardless of env state).
|
|
648
|
-
const fakeToken = "
|
|
648
|
+
const fakeToken = `ghp_${"a".repeat(36)}`;
|
|
649
649
|
mockSessionLogs = [
|
|
650
650
|
{
|
|
651
651
|
createdAt: new Date().toISOString(),
|
|
@@ -86,6 +86,7 @@ describe("task tool ctx", () => {
|
|
|
86
86
|
task: "ordinary direct assignment",
|
|
87
87
|
agentId: lead.id,
|
|
88
88
|
routingReason: "skill",
|
|
89
|
+
routingNote: "This test explicitly selects the target worker",
|
|
89
90
|
offerMode: false,
|
|
90
91
|
allowDuplicate: false,
|
|
91
92
|
});
|
|
@@ -108,6 +109,7 @@ describe("task tool ctx", () => {
|
|
|
108
109
|
task: "ordinary offer",
|
|
109
110
|
agentId: lead.id,
|
|
110
111
|
routingReason: "skill",
|
|
112
|
+
routingNote: "This test explicitly selects the target worker",
|
|
111
113
|
offerMode: true,
|
|
112
114
|
allowDuplicate: false,
|
|
113
115
|
});
|
|
@@ -101,8 +101,8 @@ describe("getAllTasks / getTasksCount requestedByUserId filter", () => {
|
|
|
101
101
|
// `GET /api/tasks` handler actually translates the `?requestedByUserId=none`
|
|
102
102
|
// sentinel into `requestedByUserIdIsNull`, or that the omitted-param path
|
|
103
103
|
// stays backwards compatible.
|
|
104
|
-
const ROUTE_TEST_DB_PATH = "./test-tasks-requested-by-filter-route.sqlite";
|
|
105
|
-
const ROUTE_API_KEY = "test-tasks-requested-by-filter-route";
|
|
104
|
+
const ROUTE_TEST_DB_PATH = "./example-test-tasks-requested-by-filter-route.sqlite";
|
|
105
|
+
const ROUTE_API_KEY = "example-test-tasks-requested-by-filter-route";
|
|
106
106
|
|
|
107
107
|
async function removeDbFiles(path: string): Promise<void> {
|
|
108
108
|
for (const suffix of ["", "-wal", "-shm"]) {
|
|
@@ -204,6 +204,14 @@ describe("initTelemetry", () => {
|
|
|
204
204
|
const metadata = (captured as { metadata: Record<string, unknown> }).metadata;
|
|
205
205
|
expect(metadata.organization_id).toBeUndefined();
|
|
206
206
|
expect(metadata.organization_name).toBeUndefined();
|
|
207
|
+
|
|
208
|
+
// Dashboard config reloads update the env after telemetry initialized.
|
|
209
|
+
process.env.SWARM_ORG_NAME = " Acme Engineering ";
|
|
210
|
+
track({ event: "test.event", properties: {} });
|
|
211
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
212
|
+
expect((captured as { metadata: Record<string, unknown> }).metadata.organization_name).toBe(
|
|
213
|
+
"Acme Engineering",
|
|
214
|
+
);
|
|
207
215
|
});
|
|
208
216
|
|
|
209
217
|
test("includes organization_id + organization_name when SWARM_ORG_* set", async () => {
|
|
@@ -756,11 +764,11 @@ describe("initTelemetry", () => {
|
|
|
756
764
|
|
|
757
765
|
describe("_hasEmbeddingKey", () => {
|
|
758
766
|
test("true when EMBEDDING_API_KEY is set", () => {
|
|
759
|
-
expect(_hasEmbeddingKey({ EMBEDDING_API_KEY: "sk-embed" })).toBe(true);
|
|
767
|
+
expect(_hasEmbeddingKey({ EMBEDDING_API_KEY: "example-sk-embed" })).toBe(true);
|
|
760
768
|
});
|
|
761
769
|
|
|
762
770
|
test("true when OPENAI_API_KEY is set", () => {
|
|
763
|
-
expect(_hasEmbeddingKey({ OPENAI_API_KEY: "sk-openai" })).toBe(true);
|
|
771
|
+
expect(_hasEmbeddingKey({ OPENAI_API_KEY: "example-sk-openai" })).toBe(true);
|
|
764
772
|
});
|
|
765
773
|
|
|
766
774
|
test("false when neither is set (onboard wizard only writes ANTHROPIC_API_KEY)", () => {
|
|
@@ -941,7 +949,7 @@ describe("initTelemetry", () => {
|
|
|
941
949
|
});
|
|
942
950
|
|
|
943
951
|
test("channels + embedding key all present", async () => {
|
|
944
|
-
process.env.EMBEDDING_API_KEY = "sk-embed";
|
|
952
|
+
process.env.EMBEDDING_API_KEY = "example-sk-embed";
|
|
945
953
|
process.env.SLACK_BOT_TOKEN = "xoxb-1";
|
|
946
954
|
process.env.SLACK_APP_TOKEN = "xapp-1";
|
|
947
955
|
process.env.AGENTMAIL_WEBHOOK_SECRET = "whsec_1";
|
|
@@ -165,6 +165,7 @@ describe("agent-id fields accept non-UUID agent ids", () => {
|
|
|
165
165
|
const parsed = sendTaskInputSchema.parse({
|
|
166
166
|
agentId: SLUG_WORKER_ID,
|
|
167
167
|
routingReason: "skill",
|
|
168
|
+
routingNote: "This test explicitly selects the target worker",
|
|
168
169
|
task: "do the thing",
|
|
169
170
|
});
|
|
170
171
|
expect(parsed.agentId).toBe(SLUG_WORKER_ID);
|
|
@@ -154,7 +154,7 @@ beforeAll(async () => {
|
|
|
154
154
|
expires_in: 3600,
|
|
155
155
|
scope: "read write",
|
|
156
156
|
};
|
|
157
|
-
if (includeRefreshToken) body.refresh_token = "rotated-refresh-token";
|
|
157
|
+
if (includeRefreshToken) body.refresh_token = "example-rotated-refresh-token";
|
|
158
158
|
return Response.json(body);
|
|
159
159
|
}
|
|
160
160
|
return new Response("not found", { status: 404 });
|
|
@@ -227,7 +227,7 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
|
|
|
227
227
|
// possible since the carve-out removal made the linear row user-manageable.
|
|
228
228
|
await upsertOAuthApp("linear", {
|
|
229
229
|
clientId: "pre-existing",
|
|
230
|
-
clientSecret: "pre-existing-secret",
|
|
230
|
+
clientSecret: "example-pre-existing-secret",
|
|
231
231
|
authorizeUrl: "https://linear.app/oauth/authorize",
|
|
232
232
|
tokenUrl: "https://api.linear.app/oauth/token",
|
|
233
233
|
redirectUri: `${appBase}/api/trackers/linear/callback`,
|
|
@@ -345,8 +345,8 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
|
|
|
345
345
|
const authorization = await upsertAuthorization({
|
|
346
346
|
appId,
|
|
347
347
|
label: "default",
|
|
348
|
-
accessToken: "stale-access",
|
|
349
|
-
refreshToken: "old-refresh",
|
|
348
|
+
accessToken: "example-stale-access",
|
|
349
|
+
refreshToken: "example-old-refresh",
|
|
350
350
|
expiresAt: new Date(Date.now() - 60_000).toISOString(),
|
|
351
351
|
status: "active",
|
|
352
352
|
});
|
|
@@ -366,7 +366,7 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
|
|
|
366
366
|
body: JSON.stringify({
|
|
367
367
|
provider: "linear",
|
|
368
368
|
clientId: "generic-linear-client",
|
|
369
|
-
clientSecret: "generic-linear-secret",
|
|
369
|
+
clientSecret: "example-generic-linear-secret",
|
|
370
370
|
authorizeUrl: "https://linear.app/oauth/authorize",
|
|
371
371
|
tokenUrl: "https://api.linear.app/oauth/token",
|
|
372
372
|
scopes: ["read", "write"],
|
|
@@ -389,8 +389,8 @@ describe("step-8: tracker fold onto the unified OAuth core", () => {
|
|
|
389
389
|
const authorization = await upsertAuthorization({
|
|
390
390
|
appId,
|
|
391
391
|
label: "default",
|
|
392
|
-
accessToken: "initial-access",
|
|
393
|
-
refreshToken: "linear-refresh",
|
|
392
|
+
accessToken: "example-initial-access",
|
|
393
|
+
refreshToken: "example-linear-refresh",
|
|
394
394
|
expiresAt: new Date(Date.now() - 60_000).toISOString(),
|
|
395
395
|
status: "active",
|
|
396
396
|
});
|
|
@@ -34,7 +34,7 @@ describe("tracker-status (DB layer)", () => {
|
|
|
34
34
|
test("returns token info after storing tokens", async () => {
|
|
35
35
|
await upsertOAuthApp("linear", {
|
|
36
36
|
clientId: "test-client",
|
|
37
|
-
clientSecret: "test-secret",
|
|
37
|
+
clientSecret: "example-test-secret",
|
|
38
38
|
authorizeUrl: "https://linear.app/oauth/authorize",
|
|
39
39
|
tokenUrl: "https://api.linear.app/oauth/token",
|
|
40
40
|
redirectUri: "http://localhost:3013/api/trackers/linear/callback",
|
|
@@ -42,8 +42,8 @@ describe("tracker-status (DB layer)", () => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
await storeOAuthTokens("linear", {
|
|
45
|
-
accessToken: "test-token",
|
|
46
|
-
refreshToken: "test-refresh",
|
|
45
|
+
accessToken: "example-test-token",
|
|
46
|
+
refreshToken: "example-test-refresh",
|
|
47
47
|
expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
|
|
48
48
|
scope: "read,write",
|
|
49
49
|
});
|
|
@@ -169,6 +169,7 @@ describe("session-UI follow-up → Lead → onward delegation", () => {
|
|
|
169
169
|
task: "please pick this up",
|
|
170
170
|
agentId: differentWorkerId,
|
|
171
171
|
routingReason: "human_pinned",
|
|
172
|
+
routingNote: "This test explicitly selects the target worker",
|
|
172
173
|
allowDuplicate: true,
|
|
173
174
|
},
|
|
174
175
|
leadAgentId,
|
|
@@ -44,7 +44,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
|
|
|
44
44
|
id: "app-linear",
|
|
45
45
|
provider: "linear",
|
|
46
46
|
clientId: "linear-client",
|
|
47
|
-
clientSecret: "linear-client-secret",
|
|
47
|
+
clientSecret: "example-linear-client-secret",
|
|
48
48
|
authorizeUrl: "https://linear.test/authorize",
|
|
49
49
|
tokenUrl: "https://linear.test/token",
|
|
50
50
|
redirectUri: "https://swarm.test/api/oauth/linear/callback",
|
|
@@ -60,7 +60,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
|
|
|
60
60
|
id: "app-jira",
|
|
61
61
|
provider: "jira",
|
|
62
62
|
clientId: "jira-client",
|
|
63
|
-
clientSecret: "jira-client-secret",
|
|
63
|
+
clientSecret: "example-jira-client-secret",
|
|
64
64
|
authorizeUrl: "https://jira.test/authorize",
|
|
65
65
|
tokenUrl: "https://jira.test/token",
|
|
66
66
|
redirectUri: "https://swarm.test/api/oauth/jira/callback",
|
|
@@ -77,7 +77,7 @@ async function pre117Database(path = ":memory:"): Promise<Database> {
|
|
|
77
77
|
id: "app-vendor",
|
|
78
78
|
provider: "vendor",
|
|
79
79
|
clientId: "vendor-client",
|
|
80
|
-
clientSecret: "vendor-client-secret",
|
|
80
|
+
clientSecret: "example-vendor-client-secret",
|
|
81
81
|
authorizeUrl: "https://vendor.test/authorize",
|
|
82
82
|
tokenUrl: "https://vendor.test/token",
|
|
83
83
|
redirectUri: "https://swarm.test/api/oauth/vendor/callback",
|
|
@@ -422,9 +422,9 @@ describe("migration 117 unified OAuth storage", () => {
|
|
|
422
422
|
)
|
|
423
423
|
.get();
|
|
424
424
|
expect(encryptedLinear?.clientSecretEncrypted).toBe(1);
|
|
425
|
-
expect(encryptedLinear?.clientSecret).not.toBe("linear-client-secret");
|
|
425
|
+
expect(encryptedLinear?.clientSecret).not.toBe("example-linear-client-secret");
|
|
426
426
|
expect(decryptSecret(encryptedLinear!.clientSecret, getEncryptionKey())).toBe(
|
|
427
|
-
"linear-client-secret",
|
|
427
|
+
"example-linear-client-secret",
|
|
428
428
|
);
|
|
429
429
|
const encryptedAuthorization = database
|
|
430
430
|
.query<{ accessToken: string; refreshToken: string | null; tokensEncrypted: number }, []>(
|
|
@@ -21,7 +21,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
|
|
|
21
21
|
import { listenOnFreePort } from "./test-net";
|
|
22
22
|
|
|
23
23
|
const TEST_DB_PATH = "./test-user-token-rest-auth.sqlite";
|
|
24
|
-
const API_KEY = "test-api-key";
|
|
24
|
+
const API_KEY = "example-test-api-key";
|
|
25
25
|
const ACTOR: IdentityActor = { kind: "operator", id: "op:test" };
|
|
26
26
|
|
|
27
27
|
function createTestServer(): Server {
|
|
@@ -14,7 +14,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
|
|
|
14
14
|
import { listenOnFreePort } from "./test-net";
|
|
15
15
|
|
|
16
16
|
const TEST_DB_PATH = "./test-user-token-routes.sqlite";
|
|
17
|
-
const API_KEY = "test-user-token-key";
|
|
17
|
+
const API_KEY = "example-test-user-token-key";
|
|
18
18
|
const ORIGINAL_API_KEY = process.env.AGENT_SWARM_API_KEY;
|
|
19
19
|
|
|
20
20
|
async function removeDbFiles(path: string): Promise<void> {
|
|
@@ -24,7 +24,7 @@ import { getPathSegments, parseQueryParams } from "../http/utils";
|
|
|
24
24
|
import { listenOnFreePort } from "./test-net";
|
|
25
25
|
|
|
26
26
|
const TEST_DB_PATH = "./test-whoami-route.sqlite";
|
|
27
|
-
const API_KEY = "test-api-key";
|
|
27
|
+
const API_KEY = "example-test-api-key";
|
|
28
28
|
const ACTOR: IdentityActor = { kind: "operator", id: "op:test" };
|
|
29
29
|
|
|
30
30
|
interface WhoamiBody {
|
|
@@ -37,7 +37,6 @@ const mockDeps: ExecutorDependencies = {
|
|
|
37
37
|
// IDs for workflow prerequisites (set in beforeAll)
|
|
38
38
|
let workflowId: string;
|
|
39
39
|
let runId: string;
|
|
40
|
-
let stepId1: string;
|
|
41
40
|
let stepId2: string;
|
|
42
41
|
|
|
43
42
|
// ─── Setup / Teardown ────────────────────────────────────────
|
|
@@ -64,14 +63,6 @@ beforeAll(async () => {
|
|
|
64
63
|
const run = await createWorkflowRun({ id: crypto.randomUUID(), workflowId: wf.id });
|
|
65
64
|
runId = run.id;
|
|
66
65
|
|
|
67
|
-
const step1 = await createWorkflowRunStep({
|
|
68
|
-
id: crypto.randomUUID(),
|
|
69
|
-
runId: run.id,
|
|
70
|
-
nodeId: "test-node-1",
|
|
71
|
-
nodeType: "agent-task",
|
|
72
|
-
});
|
|
73
|
-
stepId1 = step1.id;
|
|
74
|
-
|
|
75
66
|
const step2 = await createWorkflowRunStep({
|
|
76
67
|
id: crypto.randomUUID(),
|
|
77
68
|
runId: run.id,
|
|
@@ -159,7 +150,10 @@ describe("AgentTaskExecutor — workspace scoping", () => {
|
|
|
159
150
|
expect(parsed.success).toBe(false);
|
|
160
151
|
});
|
|
161
152
|
|
|
162
|
-
test(
|
|
153
|
+
test.each([
|
|
154
|
+
undefined,
|
|
155
|
+
"skill",
|
|
156
|
+
] as const)("execute() forwards workspace fields and routing provenance for %s", async (routingReason) => {
|
|
163
157
|
const executor = new AgentTaskExecutor(mockDeps);
|
|
164
158
|
const worker = await createAgent({
|
|
165
159
|
name: "Pinned workflow worker",
|
|
@@ -168,15 +162,22 @@ describe("AgentTaskExecutor — workspace scoping", () => {
|
|
|
168
162
|
});
|
|
169
163
|
const config = {
|
|
170
164
|
agentId: worker.id,
|
|
165
|
+
routingReason,
|
|
171
166
|
template: "List files in workspace",
|
|
172
167
|
dir: "/workspace/repos/agent-swarm",
|
|
173
168
|
vcsRepo: "desplega-ai/agent-swarm",
|
|
174
169
|
model: "sonnet",
|
|
175
170
|
};
|
|
171
|
+
const step = await createWorkflowRunStep({
|
|
172
|
+
id: crypto.randomUUID(),
|
|
173
|
+
runId,
|
|
174
|
+
nodeId: `routing-${routingReason ?? "default"}`,
|
|
175
|
+
nodeType: "agent-task",
|
|
176
|
+
});
|
|
176
177
|
const meta: ExecutorMeta = {
|
|
177
178
|
runId,
|
|
178
|
-
stepId:
|
|
179
|
-
nodeId:
|
|
179
|
+
stepId: step.id,
|
|
180
|
+
nodeId: step.nodeId,
|
|
180
181
|
workflowId,
|
|
181
182
|
dryRun: false,
|
|
182
183
|
};
|
|
@@ -195,7 +196,8 @@ describe("AgentTaskExecutor — workspace scoping", () => {
|
|
|
195
196
|
expect(task!.modelTier).toBe("regular");
|
|
196
197
|
expect(task!.source).toBe("workflow");
|
|
197
198
|
expect(task!.agentId).toBe(worker.id);
|
|
198
|
-
expect(task!.routingReason).toBe("human_pinned");
|
|
199
|
+
expect(task!.routingReason).toBe(routingReason ?? "human_pinned");
|
|
200
|
+
expect(task!.routingSource).toBe(routingReason ? "declared" : "engine_default");
|
|
199
201
|
});
|
|
200
202
|
|
|
201
203
|
test("execute() creates task without workspace fields (backward compat)", async () => {
|
|
@@ -19,7 +19,7 @@ describe("workflow-ctx: ctx.swarm proxy tool name resolution", () => {
|
|
|
19
19
|
const { ctx } = buildWorkflowCtx({
|
|
20
20
|
runId: "test-run",
|
|
21
21
|
agentId: "test-agent",
|
|
22
|
-
apiKey: "test-key",
|
|
22
|
+
apiKey: "example-test-key",
|
|
23
23
|
baseUrl: "http://localhost:9999",
|
|
24
24
|
args: {},
|
|
25
25
|
});
|
|
@@ -26,7 +26,7 @@ import { SKIP_SANDBOX_SPAWN_TESTS } from "./sandbox-spawn-test-helpers";
|
|
|
26
26
|
const spawnDescribe = describe.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
|
|
27
27
|
|
|
28
28
|
const TEST_DB_PATH = "./test-workflow-e2e.sqlite";
|
|
29
|
-
const API_KEY = "test-workflow-e2e-key-1234567890";
|
|
29
|
+
const API_KEY = "example-test-workflow-e2e-key-1234567890";
|
|
30
30
|
|
|
31
31
|
const noOpEmbeddingProvider = {
|
|
32
32
|
name: "test/noop-workflow-e2e-embedding",
|
|
@@ -43,6 +43,8 @@ const skip = test.skipIf(SKIP_SANDBOX_SPAWN_TESTS);
|
|
|
43
43
|
|
|
44
44
|
const TEST_DB_PATH = "./test-workflow-engine-v2.sqlite";
|
|
45
45
|
|
|
46
|
+
const inputRef = (name: string): string => `input.${name}`;
|
|
47
|
+
|
|
46
48
|
// ─── Test Executors ──────────────────────────────────────────
|
|
47
49
|
|
|
48
50
|
class EchoExecutor extends BaseExecutor<typeof EchoExecutor.schema, typeof EchoExecutor.outSchema> {
|
|
@@ -1158,7 +1160,7 @@ describe("interpolateNodeConfig — script node", () => {
|
|
|
1158
1160
|
test("an inputs alias pointing at workflow input is still interpolated into the script", () => {
|
|
1159
1161
|
const node = {
|
|
1160
1162
|
type: "script",
|
|
1161
|
-
inputs: { token: "
|
|
1163
|
+
inputs: { token: inputRef("API_TOKEN") },
|
|
1162
1164
|
config: { runtime: "bash", script: "curl -H 'Authorization: {{token}}' https://x" },
|
|
1163
1165
|
};
|
|
1164
1166
|
const ctx = { input: { API_TOKEN: "tok-123" }, token: "tok-123" };
|
|
@@ -594,8 +594,8 @@ describe("ScriptExecutor", () => {
|
|
|
594
594
|
|
|
595
595
|
skip("child process never inherits the server's secrets — env is scrubbed, not passed through", async () => {
|
|
596
596
|
const savedKey = process.env.AGENT_SWARM_API_KEY;
|
|
597
|
-
process.env.AGENT_SWARM_API_KEY = "super-secret-operator-bearer";
|
|
598
|
-
process.env.SOME_OTHER_SERVER_SECRET = "also-should-not-leak";
|
|
597
|
+
process.env.AGENT_SWARM_API_KEY = "example-super-secret-operator-bearer";
|
|
598
|
+
process.env.SOME_OTHER_SERVER_SECRET = "example-also-should-not-leak";
|
|
599
599
|
try {
|
|
600
600
|
const result = await executor.run(
|
|
601
601
|
input(
|