@desplega.ai/agent-swarm 1.158.0 → 1.159.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/dist/{acp-adapter-xaq4n6pc.js → acp-adapter-qhch0n2v.js} +1 -1
- package/dist/{actions-p9hz5yat.js → actions-dtsh1mfb.js} +33 -29
- package/dist/{anthropic-messages-51pz26qe.js → anthropic-messages-f2h06k64.js} +8 -3
- package/dist/{app-g26wdcz6.js → app-y1b9srva.js} +10 -9
- package/dist/{assistant-wydfqkb3.js → assistant-31hwy5xj.js} +34 -30
- package/dist/{azure-openai-responses-8gksqtmz.js → azure-openai-responses-0k1mfax5.js} +12 -13
- package/dist/{boot-reembed-se8zmdcp.js → boot-reembed-48d2qpkt.js} +11 -11
- package/dist/{boot-reembed-g5ckg9yb.js → boot-reembed-w0bryhkr.js} +12 -12
- package/dist/{boot-scrub-logs-wfxqan61.js → boot-scrub-logs-t65wbrn7.js} +9 -8
- package/dist/{boot-seeds-s3q01xj3.js → boot-seeds-h7c32hvm.js} +12 -11
- package/dist/{claude-adapter-tv2x4f36.js → claude-adapter-1t6611ne.js} +26 -21
- package/dist/{claude-managed-adapter-41b2s7fd.js → claude-managed-adapter-werp659j.js} +4 -2
- package/dist/{claude-managed-setup-60g8aazx.js → claude-managed-setup-y6rdgbc1.js} +11 -2
- package/dist/claude-sdk-session-zhkyk8yw.js +29319 -0
- package/dist/{cli-vj6h9kc2.js → cli-0m7wct0d.js} +59 -1
- package/dist/{cli-wscdvcqz.js → cli-0n2e4x49.js} +1 -1
- package/dist/cli-0xqde53b.js +176 -0
- package/dist/{cli-xberxa1r.js → cli-10ym38qc.js} +2 -2
- package/dist/{cli-5b6b62tz.js → cli-13hw4z91.js} +1 -1
- package/dist/{cli-rqz8qbw7.js → cli-20035trh.js} +50 -18
- package/dist/{cli-k0g1sjzm.js → cli-31nkw3g3.js} +3 -3
- package/dist/cli-3gvrr8vj.js +1422 -0
- package/dist/{cli-c07r9a2m.js → cli-48527fpw.js} +9 -8
- package/dist/{cli-24k806sc.js → cli-4aj25szq.js} +2 -2
- package/dist/{cli-7gtvvpbh.js → cli-4tvgz99m.js} +7 -7
- package/dist/cli-503ya656.js +455 -0
- package/dist/{cli-cw9zck8j.js → cli-5f2hq128.js} +8 -4
- package/dist/{cli-s8eet254.js → cli-68bmme5p.js} +11078 -27833
- package/dist/{cli-ftfvggzx.js → cli-79aq9cgb.js} +794 -563
- package/dist/cli-7cxw8b60.js +14910 -0
- package/dist/cli-7kyk9jr3.js +22 -0
- package/dist/cli-7zttzetj.js +324 -0
- package/dist/{cli-y95wp3tg.js → cli-96qd5psa.js} +1 -1
- package/dist/{cli-g8djp6qe.js → cli-9yg65c1j.js} +22 -0
- package/dist/{cli-3gmcwfyx.js → cli-ardpzhjm.js} +5 -5
- package/dist/{cli-7s3syk22.js → cli-b6thtzac.js} +5 -5
- package/dist/{cli-00w2c66p.js → cli-bgv70kym.js} +13 -2
- package/dist/{cli-j55n64b6.js → cli-bv0a38v9.js} +163 -44
- package/dist/cli-ca2w7zv7.js +115 -0
- package/dist/cli-cpvsaqsw.js +333 -0
- package/dist/cli-cygyqj3b.js +754 -0
- package/dist/{cli-x24pshtq.js → cli-dvjpkkjd.js} +6 -6
- package/dist/{cli-5d10vd2m.js → cli-e0ndxhtk.js} +4 -4
- package/dist/{cli-4198qc9v.js → cli-e4xnc0qp.js} +15 -3
- package/dist/{cli-rjehvrts.js → cli-eg7cdg68.js} +8 -8
- package/dist/cli-ejpygnqz.js +3815 -0
- package/dist/{cli-fgqxwrpv.js → cli-fjtp3463.js} +1631 -127
- package/dist/{cli-zt1227k1.js → cli-fkqhbg8g.js} +5 -3
- package/dist/{cli-47m6dkd3.js → cli-g9df2m37.js} +409 -168
- package/dist/cli-gzyh0j0g.js +8455 -0
- package/dist/cli-hgqfttfc.js +183 -0
- package/dist/cli-hj65wsts.js +17755 -0
- package/dist/cli-j9z8mfx3.js +476 -0
- package/dist/{cli-aehm1rbq.js → cli-kc3dp84d.js} +1135 -61
- package/dist/{cli-h38x0qhg.js → cli-kdnehe0t.js} +4 -3
- package/dist/{cli-20cj37vt.js → cli-m4excttz.js} +136 -2216
- package/dist/{cli-8qmme6vd.js → cli-mg24hkt4.js} +2 -2
- package/dist/{cli-xhaeg2nc.js → cli-mzkqpxee.js} +1 -1
- package/dist/{cli-q67y4wzm.js → cli-phsaj4xq.js} +24 -2
- package/dist/{cli-pw9rj5t9.js → cli-pqetb83f.js} +1 -176
- package/dist/{cli-rj19hc34.js → cli-qjxy52w7.js} +1 -1
- package/dist/{cli-53sz8gkz.js → cli-qv4jv8bx.js} +1 -1
- package/dist/cli-qvnnx4ct.js +1051 -0
- package/dist/cli-rb9m6rpe.js +4980 -0
- package/dist/{cli-tt9k8r35.js → cli-rfezr056.js} +476 -909
- package/dist/{cli-ggm92wcn.js → cli-rgjprct3.js} +1 -0
- package/dist/{cli-9httdpyq.js → cli-rrqmqr1s.js} +1 -1
- package/dist/cli-rykfmgwg.js +102 -0
- package/dist/{cli-eetrvv91.js → cli-t3p77qk1.js} +1 -1
- package/dist/{cli-68w09sjw.js → cli-vn0qv9cj.js} +25 -88
- package/dist/{cli-987hg0aa.js → cli-vwbbaecp.js} +2 -2
- package/dist/cli-wd9hz40d.js +69 -0
- package/dist/{cli-j57qkrpq.js → cli-wgjx0q33.js} +13 -13
- package/dist/cli-xgpf00sk.js +2149 -0
- package/dist/{cli-mcnhgnn1.js → cli-ykk5jaax.js} +184 -26
- package/dist/{cli-aky8tctm.js → cli-z9x0sh1t.js} +3 -3
- package/dist/{cli-1hkrch3k.js → cli-zw65mab6.js} +5 -5
- package/dist/cli.js +38 -29
- package/dist/cloudflare-workers-ai-system-one-1sg586qv.js +46 -0
- package/dist/{codex-adapter-cnm8wk11.js → codex-adapter-jqfqqa21.js} +21 -14
- package/dist/{codex-hook-9hptmdhj.js → codex-hook-5eys3dya.js} +2 -2
- package/dist/{codex-session-runner-gfg547zj.js → codex-session-runner-zd341dsm.js} +21 -14
- package/dist/{commands-e3bn0p75.js → commands-vfsysz4s.js} +9 -8
- package/dist/{db-03v9kzr2.js → db-s3znhvbn.js} +15 -10
- package/dist/{dispatcher-nrmg8yht.js → dispatcher-5xn0c7rf.js} +32 -28
- package/dist/{dsh-adapter-k03nfqa6.js → dsh-adapter-894mgfvs.js} +3 -3
- package/dist/{e2b-93x1k0j5.js → e2b-ez07znam.js} +4 -3
- package/dist/execute-71ysgv35.js +965 -0
- package/dist/{google-generative-ai-bxmv50nc.js → google-generative-ai-1nfcdphp.js} +5 -4
- package/dist/{google-vertex-809af514.js → google-vertex-1tqcd7b1.js} +5 -4
- package/dist/{handlers-aqcedbyb.js → handlers-5w4jwycr.js} +35 -31
- package/dist/{hook-7vkskkre.js → hook-853bxrr6.js} +16 -13
- package/dist/{hook-ybvmrmhq.js → hook-z0hbxj85.js} +16 -13
- package/dist/{http-2eqa8t24.js → http-akc3wy3m.js} +600 -123
- package/dist/{index-f6cryxwe.js → index-4a5njnm1.js} +2 -59
- package/dist/{index-a3vn96n8.js → index-5sz16ksh.js} +187 -47
- package/dist/{index-c6zsv1bd.js → index-bjmjh9h4.js} +11 -11
- package/dist/{index-chgdkq36.js → index-cd151qkq.js} +32 -28
- package/dist/{index-x71bvq0p.js → index-k661dzzr.js} +33 -29
- package/dist/{index-1yks3qcr.js → index-ttpbhnjg.js} +32 -28
- package/dist/{keepalive-vtkf5n99.js → keepalive-8p9rpvz5.js} +11 -10
- package/dist/{lead-h3sp357x.js → lead-jp69z5h3.js} +49 -45
- package/dist/llama-cpp-classify-t2tccams.js +335 -0
- package/dist/{maintenance-jzeqtk3q.js → maintenance-fwx4ev0k.js} +12 -12
- package/dist/{mistral-conversations-zx0kn554.js → mistral-conversations-bhvwqcnk.js} +14 -17
- package/dist/{oauth-refresh-sweep-qp3dzmdp.js → oauth-refresh-sweep-cwcq1ctx.js} +10 -9
- package/dist/{onboard-tmsp0qbz.js → onboard-2b4q0t84.js} +6 -5
- package/dist/{openai-codex-responses-4vjqzvjp.js → openai-codex-responses-nekthgks.js} +21 -8
- package/dist/{openai-completions-9hjrqbw8.js → openai-completions-hxtzwj0s.js} +8 -11
- package/dist/{openai-responses-7b1pn0xt.js → openai-responses-w4r118w7.js} +22 -17
- package/dist/{opencode-adapter-x6x2da1z.js → opencode-adapter-zz7xvjj6.js} +6 -4
- package/dist/{openrouter-images-9f9ek4rw.js → openrouter-images-b6sqqjgn.js} +4 -6
- package/dist/{otel-impl-9mz73q65.js → otel-impl-g8rs4vwr.js} +1 -1
- package/dist/{pi-messages-txpjj39q.js → pi-messages-vxdt8v7j.js} +2 -1
- package/dist/{pi-mono-adapter-m6dvv0dz.js → pi-mono-adapter-n0me28wt.js} +29 -17
- package/dist/pricing-refresh-0v77385v.js +39 -0
- package/dist/{rbac-roles-c9wqz83x.js → rbac-roles-krjyazbj.js} +10 -9
- package/dist/{render-v2-gryrh9h8.js → render-v2-3wjsp9aw.js} +10 -9
- package/dist/runtime-ktjysacx.js +24 -0
- package/dist/{setup-q9720bt6.js → setup-yeqryke6.js} +6 -5
- package/dist/typesafe-system-one-96960jxp.js +27 -0
- package/dist/{virtual-modules-3htpgn8x.js → virtual-modules-dzdeq1sf.js} +21 -13
- package/dist/{work-objects-b76x7deb.js → work-objects-3pakpkw0.js} +35 -31
- package/dist/{worker-6vrxbv41.js → worker-85testgj.js} +49 -45
- package/openapi.json +863 -14
- package/package.json +9 -8
- package/src/be/db/agents.ts +20 -0
- package/src/be/db/tasks/human-free.ts +442 -0
- package/src/be/db/tasks/read.ts +56 -1
- package/src/be/db/tasks/write.ts +107 -11
- package/src/be/db.ts +89 -165
- package/src/be/harness-model-support.ts +182 -0
- package/src/be/human-free-drain.ts +67 -0
- package/src/be/migrations/182_task_human_free_flag.sql +63 -0
- package/src/be/migrations/183_human_free_reclassify_queue.sql +25 -0
- package/src/be/migrations/184_model_catalog.sql +120 -0
- package/src/be/model-catalog-store.ts +644 -0
- package/src/be/model-tier-keys.ts +31 -0
- package/src/be/model-tier-resolution.ts +489 -0
- package/src/be/model-validation.ts +112 -0
- package/src/be/models-catalog.ts +61 -7
- package/src/be/modelsdev-cache.json +82 -0
- package/src/be/modelsdev-cache.ts +2 -0
- package/src/be/pricing-refresh.ts +154 -12
- package/src/be/scripts/typecheck.ts +15 -0
- package/src/be/seed-scripts/catalog/task-failure-audit.ts +61 -9
- package/src/be/swarm-config-guard.ts +6 -0
- package/src/cli.tsx +10 -0
- package/src/commands/claude-managed-setup.ts +3 -1
- package/src/commands/runner.ts +76 -2
- package/src/extensions/contract-types.generated.ts +1 -1
- package/src/heartbeat/heartbeat.ts +64 -15
- package/src/heartbeat/templates.ts +2 -2
- package/src/http/agents.ts +49 -1
- package/src/http/index.ts +8 -0
- package/src/http/models-catalog.ts +357 -8
- package/src/http/poll.ts +45 -2
- package/src/http/schedules.ts +36 -6
- package/src/http/session-data.ts +2 -5
- package/src/http/stats.ts +6 -8
- package/src/http/tasks.ts +26 -1
- package/src/http/usage-cache.ts +56 -15
- package/src/http/workflows.ts +35 -8
- package/src/prompts/session-templates.ts +1 -0
- package/src/providers/claude-managed-models.ts +47 -161
- package/src/providers/codex-adapter.ts +4 -4
- package/src/providers/codex-models.ts +65 -198
- package/src/providers/reasoning-effort.ts +44 -140
- package/src/rbac/legacy-policy.ts +25 -0
- package/src/rbac/permissions.ts +10 -0
- package/src/scripts-runtime/sdk-allowlist.ts +4 -0
- package/src/scripts-runtime/types/stdlib.d.ts +15 -0
- package/src/scripts-runtime/types/swarm-extension.d.ts +3 -0
- package/src/scripts-runtime/types/swarm-sdk.d.ts +15 -0
- package/src/server.ts +6 -0
- package/src/slack/message-text.ts +56 -2
- package/src/slack/thread-buffer.ts +10 -2
- package/src/tests/agents-list-model-display.test.ts +4 -6
- package/src/tests/base-prompt.test.ts +3 -0
- package/src/tests/claude-adapter.test.ts +10 -0
- package/src/tests/claude-managed-adapter.test.ts +12 -18
- package/src/tests/codex-adapter.test.ts +2 -1
- package/src/tests/codex-gpt6-release.test.ts +66 -5
- package/src/tests/context-window.test.ts +7 -5
- package/src/tests/db-extraction-contract.test.ts +1 -0
- package/src/tests/db-task-read-contract.test.ts +5 -1
- package/src/tests/db-task-write-contract.test.ts +4 -1
- package/src/tests/docs-index-footprint.test.js +3 -3
- package/src/tests/explicit-model-validation.test.ts +332 -0
- package/src/tests/harness-model-support.test.ts +374 -0
- package/src/tests/heartbeat-checklist-config.test.ts +71 -0
- package/src/tests/heartbeat-checklist.test.ts +4 -2
- package/src/tests/heartbeat-orphan-resume.test.ts +48 -0
- package/src/tests/human-free-flag.test.ts +279 -0
- package/src/tests/human-free-oracle.ts +57 -0
- package/src/tests/human-free-reclassify.test.ts +669 -0
- package/src/tests/migration-046-budgets.test.ts +3 -3
- package/src/tests/model-catalog-migration.test.ts +134 -0
- package/src/tests/model-catalog-table.test.ts +249 -0
- package/src/tests/model-catalog-write-access.test.ts +387 -0
- package/src/tests/model-tier-resolution.test.ts +519 -0
- package/src/tests/models-catalog.test.ts +1 -1
- package/src/tests/multi-runtime-enabled-stats.test.ts +65 -1
- package/src/tests/package-publish.test.ts +137 -36
- package/src/tests/pricing-routes.test.ts +2 -2
- package/src/tests/rbac-engine.test.ts +42 -2
- package/src/tests/reasoning-effort.test.ts +109 -0
- package/src/tests/refresh-modelsdev-carryforward.test.ts +5 -5
- package/src/tests/runtime-model-catalog.test.ts +86 -0
- package/src/tests/script-connections.test.ts +5 -0
- package/src/tests/seed-scripts.test.ts +89 -0
- package/src/tests/session-costs.test.ts +14 -11
- package/src/tests/slack-message-text.test.ts +101 -0
- package/src/tests/slack-thread-buffer-context.test.ts +93 -0
- package/src/tests/task-cascade-fail.test.ts +148 -2
- package/src/tests/tool-annotations.test.ts +1 -1
- package/src/tests/usage-cache.test.ts +166 -0
- package/src/tests/workflow-executors.test.ts +5 -2
- package/src/tests/workflow-system-one-decision-review.test.ts +1021 -0
- package/src/tests/workflow-system-one-decision-save-warnings.test.ts +365 -0
- package/src/tests/workflow-system-one-decision.test.ts +2063 -0
- package/src/tools/model-catalog/index.ts +137 -0
- package/src/tools/schedules/create-schedule.ts +16 -1
- package/src/tools/schedules/patch-schedule.ts +17 -0
- package/src/tools/schedules/update-schedule.ts +17 -0
- package/src/tools/send-task.ts +14 -0
- package/src/tools/task-action.ts +12 -0
- package/src/tools/tool-config.ts +3 -1
- package/src/tools/workflows/create-workflow.ts +9 -2
- package/src/tools/workflows/patch-workflow-node.ts +17 -7
- package/src/tools/workflows/patch-workflow.ts +9 -2
- package/src/tools/workflows/update-workflow.ts +9 -2
- package/src/types.ts +30 -1
- package/src/utils/context-window.ts +47 -53
- package/src/utils/harness-cli-version.ts +115 -0
- package/src/utils/harness-model-error.ts +33 -0
- package/src/utils/runtime-model-catalog.ts +137 -0
- package/src/workflows/approval-resolution.ts +39 -0
- package/src/workflows/definition.ts +7 -0
- package/src/workflows/engine.ts +69 -1
- package/src/workflows/executors/agent-task.ts +9 -0
- package/src/workflows/executors/base.ts +53 -0
- package/src/workflows/executors/human-in-the-loop.ts +8 -8
- package/src/workflows/executors/index.ts +1 -0
- package/src/workflows/executors/registry.ts +2 -0
- package/src/workflows/executors/system-one-decision.ts +1232 -0
- package/src/workflows/executors/system-one-providers.ts +301 -0
- package/src/workflows/executors/workflow-llm.ts +13 -1
- package/src/workflows/readiness.ts +86 -0
- package/src/workflows/recovery.ts +12 -12
- package/src/workflows/resume.ts +23 -9
- package/templates/schedules/daily-blocker-digest/content.md +4 -5
- package/templates/skills/agent-browser/SKILL.md +6 -5
- package/templates/skills/agent-browser/content.md +6 -5
- package/templates/skills/heartbeat-runbook/config.json +1 -1
- package/templates/skills/heartbeat-runbook/content.md +2 -2
- package/templates/skills/swarm-scripts/SKILL.md +1 -1
- package/templates/skills/swarm-scripts/content.md +1 -1
- package/templates/skills/workflow-iterate/content.md +81 -1
- package/templates/workflows/claude-code-changelog-watch/content.md +2 -0
- package/templates/workflows/pr-review-status-sweep/content.md +2 -0
- package/dist/claude-sdk-session-t442qz6f.js +0 -39108
- package/dist/cli-0xjkj1j7.js +0 -61
- package/dist/cli-65hjmev5.js +0 -1141
- package/dist/cli-aw1jwp1r.js +0 -14075
- package/dist/cli-h967nb6r.js +0 -6603
- package/dist/cli-vapyk8sw.js +0 -20
- package/dist/cli-ws6rqycm.js +0 -247
- package/dist/pricing-refresh-v1cbr9te.js +0 -27
- package/src/providers/modelsdev-reasoning.json +0 -6453
- package/dist/{codex-login-x3jk4etn.js → codex-login-he9vrn90.js} +3 -3
- package/dist/{index-f24115ge.js → index-2wsdsnmm.js} +3 -3
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProjectTrustStore,
|
|
3
|
+
addMcpServerConfig,
|
|
4
|
+
getMcpToolExposure,
|
|
5
|
+
loadMcpConfig,
|
|
6
|
+
openBrowser,
|
|
7
|
+
removeMcpServerConfig,
|
|
8
|
+
validateMcpServerConfig
|
|
9
|
+
} from "./cli-503ya656.js";
|
|
10
|
+
import {
|
|
11
|
+
McpOAuthCredentialStore,
|
|
12
|
+
McpServerConnection,
|
|
13
|
+
McpServerLog,
|
|
14
|
+
McpSignInCancelledError,
|
|
15
|
+
createDefaultTransport,
|
|
16
|
+
signInMcpServer
|
|
17
|
+
} from "./cli-3gvrr8vj.js";
|
|
18
|
+
import"./cli-ejpygnqz.js";
|
|
19
|
+
import {
|
|
20
|
+
APP_NAME,
|
|
21
|
+
CONFIG_DIR_NAME,
|
|
22
|
+
source_default
|
|
23
|
+
} from "./cli-hj65wsts.js";
|
|
24
|
+
import"./cli-5bfdm1ah.js";
|
|
25
|
+
import"./cli-0m7wct0d.js";
|
|
26
|
+
import"./cli-rykfmgwg.js";
|
|
27
|
+
import"./cli-0xqde53b.js";
|
|
28
|
+
import"./cli-pqetb83f.js";
|
|
29
|
+
import"./cli-bc05qbss.js";
|
|
30
|
+
|
|
31
|
+
// node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/cli.js
|
|
32
|
+
import { existsSync } from "node:fs";
|
|
33
|
+
import { join } from "node:path";
|
|
34
|
+
import { createInterface } from "node:readline/promises";
|
|
35
|
+
var HELP = `${source_default.bold("Usage:")}
|
|
36
|
+
${APP_NAME} mcp add <server> [options] -- <command> [args...]
|
|
37
|
+
${APP_NAME} mcp add <server> [options] --url <url>
|
|
38
|
+
${APP_NAME} mcp remove <server> [-l]
|
|
39
|
+
${APP_NAME} mcp list [--json]
|
|
40
|
+
${APP_NAME} mcp login <server> [--timeout <seconds>]
|
|
41
|
+
${APP_NAME} mcp logout <server>
|
|
42
|
+
|
|
43
|
+
Configure and check MCP servers and sign in to OAuth servers without starting a session.
|
|
44
|
+
Reads ~/${CONFIG_DIR_NAME}/agent/mcp.json and, in trusted projects, ${CONFIG_DIR_NAME}/mcp.json.
|
|
45
|
+
|
|
46
|
+
Commands:
|
|
47
|
+
add <server> Add or replace a server in mcp.json
|
|
48
|
+
remove <server> Remove a server from mcp.json
|
|
49
|
+
list Show state, tools, and errors (exits 1 on failure)
|
|
50
|
+
login <server> Sign in through the browser
|
|
51
|
+
logout <server> Delete the stored OAuth credentials
|
|
52
|
+
|
|
53
|
+
Options for add and remove:
|
|
54
|
+
-l, --local Use ${CONFIG_DIR_NAME}/mcp.json in the current project instead of the global file
|
|
55
|
+
|
|
56
|
+
Options for add:
|
|
57
|
+
--url <url> Streamable HTTP server URL (instead of a command)
|
|
58
|
+
--env <KEY=VALUE> Environment variable for a stdio server (repeatable)
|
|
59
|
+
--cwd <dir> Working directory for a stdio server
|
|
60
|
+
--header <KEY=VALUE> HTTP header (repeatable)
|
|
61
|
+
--bearer-token-env-var <NAME>
|
|
62
|
+
Send "Authorization: Bearer \${NAME}"
|
|
63
|
+
--oauth-client-id <id> Pre-registered OAuth client id
|
|
64
|
+
--oauth-client-secret <secret>
|
|
65
|
+
OAuth client secret (may be \${NAME} or !command)
|
|
66
|
+
--oauth-callback-port <port>
|
|
67
|
+
Fixed OAuth callback port
|
|
68
|
+
--exposure <mode> codemode (default), codemode-deferred, deferred, direct,
|
|
69
|
+
or hidden
|
|
70
|
+
|
|
71
|
+
Other options:
|
|
72
|
+
--json Print the list as JSON
|
|
73
|
+
--timeout <seconds> How long login waits for the browser (default: 300)`;
|
|
74
|
+
var HELP_HINT = source_default.dim(`Use "${APP_NAME} mcp --help" for usage.`);
|
|
75
|
+
var DEFAULT_LOGIN_TIMEOUT_SECONDS = 300;
|
|
76
|
+
function errorMessage(error) {
|
|
77
|
+
return error instanceof Error ? error.message : String(error);
|
|
78
|
+
}
|
|
79
|
+
function describeTransport(entry) {
|
|
80
|
+
const { config } = entry;
|
|
81
|
+
return "url" in config ? config.url : [config.command, ...config.args ?? []].join(" ");
|
|
82
|
+
}
|
|
83
|
+
function createConnection(entry, options, credentials) {
|
|
84
|
+
return new McpServerConnection({
|
|
85
|
+
entry,
|
|
86
|
+
cwd: options.cwd,
|
|
87
|
+
createTransport: createDefaultTransport,
|
|
88
|
+
credentials,
|
|
89
|
+
log: new McpServerLog(join(options.agentDir, "mcp.log")),
|
|
90
|
+
onTools: () => {}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
var OPTION_ALIASES = new Map([["-l", "--local"]]);
|
|
94
|
+
function parseOptions(args, known, error, maxPositionals = Number.POSITIVE_INFINITY) {
|
|
95
|
+
const positional = [];
|
|
96
|
+
const values = new Map;
|
|
97
|
+
const lists = new Map;
|
|
98
|
+
for (let index = 0;index < args.length; index++) {
|
|
99
|
+
const arg = OPTION_ALIASES.get(args[index]) ?? args[index];
|
|
100
|
+
if (arg === "--" || positional.length >= maxPositionals) {
|
|
101
|
+
positional.push(...args.slice(arg === "--" ? index + 1 : index));
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
if (!arg.startsWith("--")) {
|
|
105
|
+
positional.push(arg);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const name = arg.slice(2);
|
|
109
|
+
const kind = known[name];
|
|
110
|
+
if (!kind) {
|
|
111
|
+
error(`Unknown option ${arg}.
|
|
112
|
+
${HELP_HINT}`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (kind === "flag") {
|
|
116
|
+
values.set(name, true);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
const value = args[++index];
|
|
120
|
+
if (value === undefined) {
|
|
121
|
+
error(`${arg} needs a value.`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (kind === "list")
|
|
125
|
+
lists.set(name, [...lists.get(name) ?? [], value]);
|
|
126
|
+
else
|
|
127
|
+
values.set(name, value);
|
|
128
|
+
}
|
|
129
|
+
return { positional, values, lists };
|
|
130
|
+
}
|
|
131
|
+
async function runMcpCommand(args, options) {
|
|
132
|
+
const log = options.log ?? ((line) => console.log(line));
|
|
133
|
+
const error = options.error ?? ((line) => console.error(line));
|
|
134
|
+
const [command, ...rest] = args;
|
|
135
|
+
if (command === undefined || command === "help" || args.includes("--help") || args.includes("-h")) {
|
|
136
|
+
log(HELP);
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
const projectConfig = join(options.cwd, CONFIG_DIR_NAME, "mcp.json");
|
|
140
|
+
if (command === "add" || command === "remove") {
|
|
141
|
+
return command === "add" ? add(rest, projectConfig, options, log, error) : remove(rest, projectConfig, options, log, error);
|
|
142
|
+
}
|
|
143
|
+
const projectTrusted = new ProjectTrustStore(options.agentDir).get(options.cwd) === true;
|
|
144
|
+
const loaded = loadMcpConfig({ agentDir: options.agentDir, cwd: options.cwd, projectTrusted });
|
|
145
|
+
const untrustedNote = !projectTrusted && existsSync(projectConfig) ? `${projectConfig} is ignored because the project is not trusted. Start ${APP_NAME} in the project to trust it.` : undefined;
|
|
146
|
+
const credentials = options.credentials ?? new McpOAuthCredentialStore;
|
|
147
|
+
switch (command) {
|
|
148
|
+
case "list": {
|
|
149
|
+
const parsed = parseOptions(rest, { json: "flag" }, error);
|
|
150
|
+
if (!parsed)
|
|
151
|
+
return 1;
|
|
152
|
+
if (parsed.positional.length > 0) {
|
|
153
|
+
error(`Usage: ${APP_NAME} mcp list [--json]
|
|
154
|
+
${HELP_HINT}`);
|
|
155
|
+
return 1;
|
|
156
|
+
}
|
|
157
|
+
return list(loaded, parsed.values.has("json"), untrustedNote, options, credentials, log);
|
|
158
|
+
}
|
|
159
|
+
case "login":
|
|
160
|
+
case "logout": {
|
|
161
|
+
const parsed = parseOptions(rest, command === "login" ? { timeout: "value" } : {}, error);
|
|
162
|
+
if (!parsed)
|
|
163
|
+
return 1;
|
|
164
|
+
const [name, ...extra] = parsed.positional;
|
|
165
|
+
if (!name || extra.length > 0) {
|
|
166
|
+
error(`Usage: ${APP_NAME} mcp ${command} <server>
|
|
167
|
+
${HELP_HINT}`);
|
|
168
|
+
return 1;
|
|
169
|
+
}
|
|
170
|
+
const entry = loaded.servers.find((server) => server.name === name);
|
|
171
|
+
if (!entry) {
|
|
172
|
+
error(`No MCP server named "${name}".${untrustedNote ? ` ${untrustedNote}` : ""} Configured: ${loaded.servers.map((server) => server.name).join(", ") || "none"}.`);
|
|
173
|
+
return 1;
|
|
174
|
+
}
|
|
175
|
+
const connection = createConnection(entry, options, credentials);
|
|
176
|
+
const url = connection.oauthUrl;
|
|
177
|
+
if (!url) {
|
|
178
|
+
error(`MCP server "${name}" does not use OAuth. Only HTTP servers without an Authorization header do.`);
|
|
179
|
+
return 1;
|
|
180
|
+
}
|
|
181
|
+
if (command === "logout") {
|
|
182
|
+
const removed = credentials.remove(url);
|
|
183
|
+
log(removed ? `Signed out of MCP server "${name}".` : `No stored credentials for MCP server "${name}".`);
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
const timeout = Number(parsed.values.get("timeout") ?? DEFAULT_LOGIN_TIMEOUT_SECONDS);
|
|
187
|
+
if (!Number.isFinite(timeout) || timeout <= 0) {
|
|
188
|
+
error("--timeout must be a positive number of seconds.");
|
|
189
|
+
return 1;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
return await login(entry, connection, url, timeout * 1000, options, credentials, log, error);
|
|
193
|
+
} finally {
|
|
194
|
+
await connection.close();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
default:
|
|
198
|
+
error(`Unknown mcp command "${command}".
|
|
199
|
+
${HELP_HINT}`);
|
|
200
|
+
return 1;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function parsePairs(option, pairs, error) {
|
|
204
|
+
if (!pairs)
|
|
205
|
+
return {};
|
|
206
|
+
const record = {};
|
|
207
|
+
for (const pair of pairs) {
|
|
208
|
+
const separator = pair.indexOf("=");
|
|
209
|
+
if (separator <= 0) {
|
|
210
|
+
error(`--${option} expects KEY=VALUE, got "${pair}".`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
record[pair.slice(0, separator)] = pair.slice(separator + 1);
|
|
214
|
+
}
|
|
215
|
+
return record;
|
|
216
|
+
}
|
|
217
|
+
function add(args, projectConfig, options, log, error) {
|
|
218
|
+
const usage = `Usage: ${APP_NAME} mcp add <server> [options] (--url <url> | -- <command> [args...])
|
|
219
|
+
${HELP_HINT}`;
|
|
220
|
+
const parsed = parseOptions(args, {
|
|
221
|
+
local: "flag",
|
|
222
|
+
url: "value",
|
|
223
|
+
env: "list",
|
|
224
|
+
cwd: "value",
|
|
225
|
+
header: "list",
|
|
226
|
+
"bearer-token-env-var": "value",
|
|
227
|
+
"oauth-client-id": "value",
|
|
228
|
+
"oauth-client-secret": "value",
|
|
229
|
+
"oauth-callback-port": "value",
|
|
230
|
+
exposure: "value"
|
|
231
|
+
}, error, 2);
|
|
232
|
+
if (!parsed)
|
|
233
|
+
return 1;
|
|
234
|
+
const { positional, values, lists } = parsed;
|
|
235
|
+
const [name, ...command] = positional;
|
|
236
|
+
const url = values.get("url");
|
|
237
|
+
if (!name || url === undefined === (command.length === 0)) {
|
|
238
|
+
error(usage);
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
const value = (option) => {
|
|
242
|
+
const found = values.get(option);
|
|
243
|
+
return typeof found === "string" ? found : undefined;
|
|
244
|
+
};
|
|
245
|
+
const exposure = value("exposure");
|
|
246
|
+
const httpOnly = ["header", "bearer-token-env-var", "oauth-client-id", "oauth-client-secret", "oauth-callback-port"];
|
|
247
|
+
const stdioOnly = ["env", "cwd"];
|
|
248
|
+
const misplaced = (url === undefined ? httpOnly : stdioOnly).find((option) => values.has(option) || lists.has(option));
|
|
249
|
+
if (misplaced) {
|
|
250
|
+
error(`--${misplaced} only applies to ${url === undefined ? "HTTP servers (--url)" : "stdio servers"}.`);
|
|
251
|
+
return 1;
|
|
252
|
+
}
|
|
253
|
+
let config;
|
|
254
|
+
if (typeof url === "string") {
|
|
255
|
+
const headers = parsePairs("header", lists.get("header"), error);
|
|
256
|
+
if (!headers)
|
|
257
|
+
return 1;
|
|
258
|
+
const bearer = value("bearer-token-env-var");
|
|
259
|
+
if (bearer !== undefined)
|
|
260
|
+
headers.Authorization = `Bearer \${${bearer}}`;
|
|
261
|
+
const port = value("oauth-callback-port");
|
|
262
|
+
const oauth = {
|
|
263
|
+
...value("oauth-client-id") === undefined ? {} : { clientId: value("oauth-client-id") },
|
|
264
|
+
...value("oauth-client-secret") === undefined ? {} : { clientSecret: value("oauth-client-secret") },
|
|
265
|
+
...port === undefined ? {} : { callbackPort: Number(port) }
|
|
266
|
+
};
|
|
267
|
+
config = {
|
|
268
|
+
url,
|
|
269
|
+
...Object.keys(headers).length > 0 ? { headers } : {},
|
|
270
|
+
...Object.keys(oauth).length > 0 ? { oauth } : {}
|
|
271
|
+
};
|
|
272
|
+
} else {
|
|
273
|
+
const env = parsePairs("env", lists.get("env"), error);
|
|
274
|
+
if (!env)
|
|
275
|
+
return 1;
|
|
276
|
+
const [executable, ...commandArgs] = command;
|
|
277
|
+
config = {
|
|
278
|
+
command: executable,
|
|
279
|
+
...commandArgs.length > 0 ? { args: commandArgs } : {},
|
|
280
|
+
...Object.keys(env).length > 0 ? { env } : {},
|
|
281
|
+
...value("cwd") === undefined ? {} : { cwd: value("cwd") }
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
if (exposure !== undefined)
|
|
285
|
+
config.exposure = exposure;
|
|
286
|
+
const validated = validateMcpServerConfig(name, config);
|
|
287
|
+
if (typeof validated === "string") {
|
|
288
|
+
error(validated);
|
|
289
|
+
return 1;
|
|
290
|
+
}
|
|
291
|
+
const project = values.has("local");
|
|
292
|
+
const path = project ? projectConfig : join(options.agentDir, "mcp.json");
|
|
293
|
+
const scope = project ? "project" : "global";
|
|
294
|
+
let replaced;
|
|
295
|
+
try {
|
|
296
|
+
replaced = addMcpServerConfig(path, name, validated);
|
|
297
|
+
} catch (addError) {
|
|
298
|
+
error(`Could not update ${path}: ${errorMessage(addError)}`);
|
|
299
|
+
return 1;
|
|
300
|
+
}
|
|
301
|
+
log(`${replaced ? "Replaced" : "Added"} ${scope} MCP server "${name}" in ${path}.`);
|
|
302
|
+
if (project && new ProjectTrustStore(options.agentDir).get(options.cwd) !== true) {
|
|
303
|
+
log(`The project is not trusted, so ${path} is ignored until you start ${APP_NAME} in the project and trust it.`);
|
|
304
|
+
}
|
|
305
|
+
const mayNeedSignIn = "url" in validated && !Object.keys(validated.headers ?? {}).some((header) => header.toLowerCase() === "authorization");
|
|
306
|
+
log(`Check it with: ${APP_NAME} mcp list${mayNeedSignIn ? `. If it requires sign-in: ${APP_NAME} mcp login ${name}` : ""}`);
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
function remove(args, projectConfig, options, log, error) {
|
|
310
|
+
const parsed = parseOptions(args, { local: "flag" }, error);
|
|
311
|
+
if (!parsed)
|
|
312
|
+
return 1;
|
|
313
|
+
const [name, ...extra] = parsed.positional;
|
|
314
|
+
if (!name || extra.length > 0) {
|
|
315
|
+
error(`Usage: ${APP_NAME} mcp remove <server> [-l]
|
|
316
|
+
${HELP_HINT}`);
|
|
317
|
+
return 1;
|
|
318
|
+
}
|
|
319
|
+
const project = parsed.values.has("local");
|
|
320
|
+
const globalConfig = join(options.agentDir, "mcp.json");
|
|
321
|
+
const path = project ? projectConfig : globalConfig;
|
|
322
|
+
const scope = project ? "project" : "global";
|
|
323
|
+
let removed;
|
|
324
|
+
try {
|
|
325
|
+
removed = removeMcpServerConfig(path, name);
|
|
326
|
+
} catch (removeError) {
|
|
327
|
+
error(`Could not update ${path}: ${errorMessage(removeError)}`);
|
|
328
|
+
return 1;
|
|
329
|
+
}
|
|
330
|
+
if (removed) {
|
|
331
|
+
log(`Removed ${scope} MCP server "${name}" from ${path}.`);
|
|
332
|
+
return 0;
|
|
333
|
+
}
|
|
334
|
+
const other = loadMcpConfig({ agentDir: options.agentDir, cwd: options.cwd, projectTrusted: true }).servers.find((server) => server.name === name && server.scope !== scope);
|
|
335
|
+
error(`No ${scope} MCP server named "${name}" in ${path}.${other ? ` It is defined in ${other.source}${other.scope === "project" ? "; use --local" : "; omit --local"}.` : ""}`);
|
|
336
|
+
return 1;
|
|
337
|
+
}
|
|
338
|
+
async function list(loaded, json, untrustedNote, options, credentials, log) {
|
|
339
|
+
const reports = await Promise.all(loaded.servers.map(async (entry) => {
|
|
340
|
+
const report = {
|
|
341
|
+
name: entry.name,
|
|
342
|
+
scope: entry.scope ?? "global",
|
|
343
|
+
source: entry.source,
|
|
344
|
+
enabled: entry.config.enabled !== false,
|
|
345
|
+
exposure: entry.config.exposure ?? "codemode",
|
|
346
|
+
transport: describeTransport(entry),
|
|
347
|
+
state: "disabled",
|
|
348
|
+
tools: []
|
|
349
|
+
};
|
|
350
|
+
if (!report.enabled)
|
|
351
|
+
return report;
|
|
352
|
+
const connection = createConnection(entry, options, credentials);
|
|
353
|
+
try {
|
|
354
|
+
await connection.getClient();
|
|
355
|
+
} catch {}
|
|
356
|
+
report.state = connection.state;
|
|
357
|
+
report.tools = connection.tools.map((tool) => tool.name);
|
|
358
|
+
const overrides = connection.tools.flatMap((tool) => {
|
|
359
|
+
const exposure = getMcpToolExposure(entry.config, tool.name);
|
|
360
|
+
return exposure === report.exposure ? [] : [[tool.name, exposure]];
|
|
361
|
+
});
|
|
362
|
+
if (overrides.length > 0)
|
|
363
|
+
report.toolExposure = Object.fromEntries(overrides);
|
|
364
|
+
if (connection.hasResources) {
|
|
365
|
+
report.resources = connection.resources.length;
|
|
366
|
+
report.resourceTemplates = connection.resourceTemplates.length;
|
|
367
|
+
}
|
|
368
|
+
if (connection.state !== "connected" && connection.error)
|
|
369
|
+
report.error = connection.error;
|
|
370
|
+
await connection.close();
|
|
371
|
+
return report;
|
|
372
|
+
}));
|
|
373
|
+
const failed = loaded.errors.length > 0 || reports.some((report) => report.enabled && report.state !== "connected");
|
|
374
|
+
if (json) {
|
|
375
|
+
log(JSON.stringify({ servers: reports, errors: loaded.errors, ...untrustedNote ? { note: untrustedNote } : {} }, null, 2));
|
|
376
|
+
return failed ? 1 : 0;
|
|
377
|
+
}
|
|
378
|
+
if (reports.length === 0 && loaded.errors.length === 0) {
|
|
379
|
+
log(`No MCP servers configured. Add them to ${join(options.agentDir, "mcp.json")} or .pi/mcp.json.`);
|
|
380
|
+
}
|
|
381
|
+
for (const report of reports) {
|
|
382
|
+
const state = report.state === "connected" ? `connected, ${report.tools.length} tool${report.tools.length === 1 ? "" : "s"}` : report.state === "needs-auth" ? "needs sign-in" : report.state;
|
|
383
|
+
log(`${report.name}: ${state} (${report.exposure}, ${report.scope})`);
|
|
384
|
+
log(` ${report.transport}`);
|
|
385
|
+
if (report.state === "needs-auth")
|
|
386
|
+
log(` sign in with: ${APP_NAME} mcp login ${report.name}`);
|
|
387
|
+
if (report.tools.length > 0) {
|
|
388
|
+
const tools = report.tools.map((tool) => {
|
|
389
|
+
const exposure = report.toolExposure?.[tool];
|
|
390
|
+
return exposure ? `${tool} [${exposure}]` : tool;
|
|
391
|
+
});
|
|
392
|
+
log(` tools: ${tools.join(", ")}`);
|
|
393
|
+
}
|
|
394
|
+
if (report.resources !== undefined) {
|
|
395
|
+
log(` resources: ${report.resources}, URI templates: ${report.resourceTemplates ?? 0}`);
|
|
396
|
+
}
|
|
397
|
+
if (report.error)
|
|
398
|
+
log(` ${report.error.split(`
|
|
399
|
+
`).join(`
|
|
400
|
+
`)}`);
|
|
401
|
+
}
|
|
402
|
+
for (const configError of loaded.errors)
|
|
403
|
+
log(`config error: ${configError}`);
|
|
404
|
+
if (untrustedNote)
|
|
405
|
+
log(untrustedNote);
|
|
406
|
+
return failed ? 1 : 0;
|
|
407
|
+
}
|
|
408
|
+
async function login(entry, connection, url, timeoutMs, options, credentials, log, error) {
|
|
409
|
+
const { name } = entry;
|
|
410
|
+
try {
|
|
411
|
+
await connection.getClient();
|
|
412
|
+
log(`Already signed in to MCP server "${name}" (${connection.tools.length} tools).`);
|
|
413
|
+
return 0;
|
|
414
|
+
} catch {
|
|
415
|
+
if (connection.state !== "needs-auth") {
|
|
416
|
+
error(`MCP server "${name}" failed to connect: ${connection.error ?? "unknown error"}`);
|
|
417
|
+
return 1;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
const openUrl = options.openUrl ?? openBrowser;
|
|
421
|
+
const interactive = process.stdin.isTTY === true && options.openUrl === undefined;
|
|
422
|
+
try {
|
|
423
|
+
await signInMcpServer({
|
|
424
|
+
serverUrl: url,
|
|
425
|
+
store: credentials.forServer(url),
|
|
426
|
+
settings: connection.oauthSettings(),
|
|
427
|
+
challenge: connection.challenge,
|
|
428
|
+
prompt: {
|
|
429
|
+
showAuthorizationUrl: (authorizationUrl) => {
|
|
430
|
+
log(`Sign in to MCP server "${name}" in your browser:
|
|
431
|
+
${authorizationUrl.href}`);
|
|
432
|
+
openUrl(authorizationUrl.href);
|
|
433
|
+
},
|
|
434
|
+
promptForRedirectUrl: (signal) => waitForRedirectUrl(signal, timeoutMs, interactive)
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
} catch (signInError) {
|
|
438
|
+
error(signInError instanceof McpSignInCancelledError ? `Sign-in to MCP server "${name}" was cancelled or not completed within ${Math.round(timeoutMs / 1000)} seconds.` : `Sign-in to MCP server "${name}" failed: ${errorMessage(signInError)}`);
|
|
439
|
+
return 1;
|
|
440
|
+
}
|
|
441
|
+
connection.challenge = undefined;
|
|
442
|
+
try {
|
|
443
|
+
await connection.reconnect();
|
|
444
|
+
} catch (connectError) {
|
|
445
|
+
error(`Signed in, but ${errorMessage(connectError)}`);
|
|
446
|
+
return 1;
|
|
447
|
+
}
|
|
448
|
+
log(`Signed in to MCP server "${name}" (${connection.tools.length} tools).`);
|
|
449
|
+
return 0;
|
|
450
|
+
}
|
|
451
|
+
async function waitForRedirectUrl(signal, timeoutMs, interactive) {
|
|
452
|
+
const controller = new AbortController;
|
|
453
|
+
const abort = () => controller.abort();
|
|
454
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
455
|
+
const timer = setTimeout(abort, timeoutMs);
|
|
456
|
+
try {
|
|
457
|
+
if (!interactive) {
|
|
458
|
+
await new Promise((resolve) => controller.signal.addEventListener("abort", () => resolve(), { once: true }));
|
|
459
|
+
return;
|
|
460
|
+
}
|
|
461
|
+
const readline = createInterface({ input: process.stdin, output: process.stderr });
|
|
462
|
+
try {
|
|
463
|
+
return await readline.question("If the browser cannot reach this machine, paste the URL it was redirected to: ", { signal: controller.signal });
|
|
464
|
+
} catch {
|
|
465
|
+
return;
|
|
466
|
+
} finally {
|
|
467
|
+
readline.close();
|
|
468
|
+
}
|
|
469
|
+
} finally {
|
|
470
|
+
clearTimeout(timer);
|
|
471
|
+
signal.removeEventListener("abort", abort);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
export {
|
|
475
|
+
runMcpCommand
|
|
476
|
+
};
|