@runfusion/fusion 0.48.0 → 0.50.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/bin.js +43336 -15114
- package/dist/client/.vite/manifest.json +250 -249
- package/dist/client/assets/AgentDetailView-BzSyldiW.css +1 -0
- package/dist/client/assets/{AgentDetailView-CF6isJ51.js → AgentDetailView-D2oYUApl.js} +5 -5
- package/dist/client/assets/{AgentPermissionPolicyEditor-DFldf6aS.js → AgentPermissionPolicyEditor-DGgx46f3.js} +1 -1
- package/dist/client/assets/AgentsView-Dhf5Vq_T.js +29 -0
- package/dist/client/assets/ChatView-DpgpxHva.js +19 -0
- package/dist/client/assets/ChatView-DwIIrJxb.css +1 -0
- package/dist/client/assets/CommandCenter-B9q-zM9p.css +1 -0
- package/dist/client/assets/CommandCenter-DzQhGq_J.js +71 -0
- package/dist/client/assets/{DevServerView-D6RFaGPU.js → DevServerView-DjJYp6Jj.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DNBB-viz.js → DirectoryPicker-CYPYp9T4.js} +1 -1
- package/dist/client/assets/{DocumentsView-DXG-sctG.js → DocumentsView-CeQVRVdp.js} +1 -1
- package/dist/client/assets/{EvalsView-Ol6ECKz5.js → EvalsView-D250mVR5.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-BQc3GaE_.js → ExperimentalAgentOnboardingModal-B1EEY_bl.js} +1 -1
- package/dist/client/assets/{GoalsView-C_m90anC.js → GoalsView-MftVwE9g.js} +1 -1
- package/dist/client/assets/{InsightsView-BbFgPsDH.js → InsightsView-CbWItYe8.js} +1 -1
- package/dist/client/assets/{MemoryView-CRS7AjWK.js → MemoryView-Ct0nOTES.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-BEj5xu45.js → PiExtensionsManager-DSQwngX-.js} +1 -1
- package/dist/client/assets/{PluginManager-CzCM3XUY.js → PluginManager-DqLxCiNg.js} +1 -1
- package/dist/client/assets/{PullRequestView-9yNYCunb.js → PullRequestView-D0WgwdAi.js} +1 -1
- package/dist/client/assets/{ResearchView-BKdirpiw.js → ResearchView-CJQL9XKC.js} +1 -1
- package/dist/client/assets/{SecretsView-qGjo-0Cp.js → SecretsView-ChN9aTbi.js} +1 -1
- package/dist/client/assets/{SessionTerminal-C7YlkdGJ.js → SessionTerminal-BVon9kbr.js} +1 -1
- package/dist/client/assets/SettingsModal-B4WANQnu.js +21 -0
- package/dist/client/assets/{SettingsModal-CvbiSIHS.css → SettingsModal-BzZNPNIh.css} +1 -1
- package/dist/client/assets/{SettingsModal-DihNd7g8.js → SettingsModal-CIC5jhgo.js} +1 -1
- package/dist/client/assets/SettingsModal-tUDR6nJ9.css +1 -0
- package/dist/client/assets/{SetupWizardModal-MovTj5pY.js → SetupWizardModal-C6EGjmbd.js} +2 -2
- package/dist/client/assets/{ShadcnColorPicker-Bnf5n5R4.js → ShadcnColorPicker-4e_aXoGX.js} +1 -1
- package/dist/client/assets/{ShadcnColorPicker-pqVWCC5-.css → ShadcnColorPicker-CzZo9UOD.css} +1 -1
- package/dist/client/assets/SkillsView-Dz8dDwfP.js +1 -0
- package/dist/client/assets/SkillsView-tAW7TTCz.css +1 -0
- package/dist/client/assets/{TodoView-CIsL_uvQ.css → TodoView--YoVYWvw.css} +1 -1
- package/dist/client/assets/{TodoView-BEdk6FTU.js → TodoView-DvJFzoOv.js} +1 -1
- package/dist/client/assets/WorkflowNodeEditor-DrdTCstS.js +8 -0
- package/dist/client/assets/WorkflowNodeEditor-WYIxHTxY.css +1 -0
- package/dist/client/assets/{agentSkills-D5nDZPRY.js → agentSkills-B2dD5Nm5.js} +1 -1
- package/dist/client/assets/app-BYq4S7Cb.js +13 -0
- package/dist/client/assets/app-D27ewSC0.js +13 -0
- package/dist/client/assets/app-DFLDkeOE.js +13 -0
- package/dist/client/assets/app-OPrfgjjn.js +13 -0
- package/dist/client/assets/app-dATBczl3.js +13 -0
- package/dist/client/assets/{app-D_IT9Buz.js → app-k1K9zAjp.js} +3 -3
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BbkXWBni.js → architectureDiagram-3BPJPVTR-ClO0MnzR.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-DhaqpHqZ.js → blockDiagram-GPEHLZMM-C4cyy4WE.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-qC0WSHMZ.js → c4Diagram-AAUBKEIU-NHPC9TJo.js} +1 -1
- package/dist/client/assets/channel-Q2WKocEP.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-Dah9zMeT.js → chunk-2J33WTMH-CGYIKTVR.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-epHwnUb_.js → chunk-4BX2VUAB-BkCCD0tE.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-DpYBy44g.js → chunk-55IACEB6-Be3yOIDe.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-B9b8698e.js → chunk-727SXJPM-DxjyMaQQ.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DrM8nnhR.js → chunk-AQP2D5EJ-BC0PjN0W.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-jyT6Scwe.js → chunk-FMBD7UC4-DoWxmM8k.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-EoPfF-PK.js → chunk-ND2GUHAM-EOpuc9pP.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-qMwLVfgJ.js → chunk-QZHKN3VN-DiRyx9QZ.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-CPFl2Aqd.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CPFl2Aqd.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-DmPFKoVD.js → cose-bilkent-S5V4N54A-CfVoUUxT.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-DeHxd-ej.js → dagre-BM42HDAG-BfILvxLb.js} +1 -1
- package/dist/client/assets/{dashboard-view-DXjNQ5IF.js → dashboard-view-C9YIcx-O.js} +2 -2
- package/dist/client/assets/{dashboard-view-Cw5mMJay.js → dashboard-view-wFC1pe4d.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-C04A2mhr.js → diagram-2AECGRRQ-6mdmbH-5.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-DqtOwADI.js → diagram-5GNKFQAL-CY7MMwO1.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-CH0har-Z.js → diagram-KO2AKTUF-D05XnQqd.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-CxN-U-0W.js → diagram-LMA3HP47-B18FTOJG.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-42A7wpwF.js → diagram-OG6HWLK6-xmXlYf5m.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-CnZI5YlN.js → erDiagram-TEJ5UH35-4XlgVLCs.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-BKfQhMVF.js → flowDiagram-I6XJVG4X-BYl3ps7f.js} +1 -1
- package/dist/client/assets/{folder-open-STXgbemw.js → folder-open-BH6FwmO7.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-BfA0pME8.js → ganttDiagram-6RSMTGT7-4vxuH9Dx.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-BgDFB7PS.js → gitGraphDiagram-PVQCEYII-BESmFgXT.js} +1 -1
- package/dist/client/assets/index-B9jtBwFy.css +1 -0
- package/dist/client/assets/index-DFeBJ3GM.js +1302 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-Bb5F155s.js → infoDiagram-5YYISTIA-DvjdjtwB.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-8Oati7l_.js → ishikawaDiagram-YF4QCWOH-Cis5IoEm.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-DhHTHXTM.js → journeyDiagram-JHISSGLW-C20pB1W8.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BWB9EtUX.js → kanban-definition-UN3LZRKU-CiVfCeU3.js} +1 -1
- package/dist/client/assets/{mermaid.core-BD-L2gUQ.js → mermaid.core-CW0vCXA6.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BSKGd7LE.js → mindmap-definition-RKZ34NQL-E5rPHUdw.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BtBFPvSW.js → pieDiagram-4H26LBE5-DVIFbPjH.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-aWQWYPto.js → quadrantDiagram-W4KKPZXB-C8qPRe_x.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CprlEpIa.js → requirementDiagram-4Y6WPE33-DQ-pwXh3.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-Cw-AcRAV.js → sankeyDiagram-5OEKKPKP-BnghLuUc.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BMW5slyv.js → sequenceDiagram-3UESZ5HK-ChlGxGVk.js} +1 -1
- package/dist/client/assets/{shield-alert-Bzf8yNOc.js → shield-alert-BfOnDO6O.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-CcxvIVwM.js → stateDiagram-AJRCARHV-ByUvNEch.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-awOfoFOB.js → stateDiagram-v2-BHNVJYJU-Df38ITSP.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DIEAc2YP.js → timeline-definition-PNZ67QCA-bsAGc83D.js} +1 -1
- package/dist/client/assets/{upload-DuwyPTKe.js → upload-BK1crTqn.js} +1 -1
- package/dist/client/assets/{users-D1Qhfyro.js → users-DW8jC2Z9.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DOkqg5Wi.js → vennDiagram-CIIHVFJN-BBIj6LFN.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-DoPK1Q6d.js → wardley-L42UT6IY-De6JFroy.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-l1vun-m2.js → wardleyDiagram-YWT4CUSO-P1LOLx0_.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DcUOUKvl.js → xychartDiagram-2RQKCTM6-v1G4ki6U.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +6 -25
- package/dist/extension.js +37091 -9900
- package/dist/pi-claude-cli/index.ts +26 -22
- package/dist/pi-claude-cli/package.json +6 -20
- package/dist/pi-claude-cli/src/mcp-config.ts +58 -7
- package/dist/plugin-sdk/index.d.ts +246 -186
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +2 -9
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +250 -19
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +2 -10
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +3 -15
- package/package.json +1 -1
- package/skill/fusion/references/engine-tools.md +5 -1
- package/dist/client/assets/AgentDetailView-CgbB51Iw.css +0 -1
- package/dist/client/assets/AgentsView-DiGseTuo.js +0 -29
- package/dist/client/assets/ChatView-BjQBbDyo.js +0 -19
- package/dist/client/assets/ChatView-BtjkE0V7.css +0 -1
- package/dist/client/assets/CommandCenter-DDjpYkPe.css +0 -1
- package/dist/client/assets/CommandCenter-DwpiADSX.js +0 -71
- package/dist/client/assets/SettingsModal-DpaptT6t.js +0 -21
- package/dist/client/assets/SettingsModal-ino68pI2.css +0 -1
- package/dist/client/assets/SkillsView-Br2LkA3x.js +0 -1
- package/dist/client/assets/SkillsView-CJ8snrma.css +0 -1
- package/dist/client/assets/WorkflowNodeEditor-BOouksjw.css +0 -1
- package/dist/client/assets/WorkflowNodeEditor-e-eR6yzw.js +0 -8
- package/dist/client/assets/app-BM6bAO0b.js +0 -13
- package/dist/client/assets/app-BglOELbc.js +0 -13
- package/dist/client/assets/app-ChkCVQpq.js +0 -13
- package/dist/client/assets/app-DMn7Jt9g.js +0 -13
- package/dist/client/assets/app-S8fehQv8.js +0 -13
- package/dist/client/assets/channel-CCKvUami.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-C_HqY7AI.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-C_HqY7AI.js +0 -1
- package/dist/client/assets/index-BnfnLXyO.css +0 -1
- package/dist/client/assets/index-CHy0WNjH.js +0 -1301
|
@@ -21,13 +21,14 @@ import {
|
|
|
21
21
|
writeMcpConfig,
|
|
22
22
|
buildAcpMcpServers,
|
|
23
23
|
type McpToolDef,
|
|
24
|
+
type UserMcpServerSpec,
|
|
24
25
|
} from "./src/mcp-config.js";
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* FNXC:pi-claude-cli 2026-06-27-06:39:
|
|
29
|
+
* Route A drives Claude through the ACP bridge only when `FUSION_CLAUDE_ACP=1`
|
|
30
|
+
* AND a bridge binary path is injected via `FUSION_CLAUDE_ACP_BRIDGE`.
|
|
31
|
+
* OFF by default: the live `claude -p` path stays untouched until soak.
|
|
31
32
|
*/
|
|
32
33
|
function resolveAcpBridgePath(): string | undefined {
|
|
33
34
|
if (process.env.FUSION_CLAUDE_ACP !== "1") return undefined;
|
|
@@ -51,14 +52,12 @@ process.on("exit", killAllProcesses);
|
|
|
51
52
|
const PROVIDER_ID = "pi-claude-cli";
|
|
52
53
|
|
|
53
54
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* factory returns immediately and other requests keep flowing; the result
|
|
61
|
-
* is logged once on first run and reused thereafter.
|
|
55
|
+
* FNXC:pi-claude-cli 2026-06-27-06:39:
|
|
56
|
+
* The factory runs per `createFnAgent` call, which the dashboard does for each
|
|
57
|
+
* chat message. Synchronous `execSync` presence + auth probes froze the Node
|
|
58
|
+
* event loop while `claude` cold-started, so memoize the probes as an async
|
|
59
|
+
* Promise: the factory returns immediately, the result logs once, and later
|
|
60
|
+
* calls reuse it.
|
|
62
61
|
*/
|
|
63
62
|
let cliValidationPromise: Promise<void> | undefined;
|
|
64
63
|
|
|
@@ -83,6 +82,11 @@ function debugMcp(message: string): void {
|
|
|
83
82
|
console.error(`[pi-claude-cli] ${message}`);
|
|
84
83
|
}
|
|
85
84
|
|
|
85
|
+
function getUserMcpServers(options: unknown): UserMcpServerSpec[] {
|
|
86
|
+
const servers = (options as { mcpServers?: unknown } | undefined)?.mcpServers;
|
|
87
|
+
return Array.isArray(servers) ? servers.filter((server): server is UserMcpServerSpec => Boolean(server && typeof server === "object" && "name" in server)) : [];
|
|
88
|
+
}
|
|
89
|
+
|
|
86
90
|
/**
|
|
87
91
|
* Resolve the MCP config path for the current request, regenerating it when
|
|
88
92
|
* the set of custom tools changes.
|
|
@@ -113,6 +117,7 @@ function ensureMcpConfig(
|
|
|
113
117
|
description: string;
|
|
114
118
|
parameters: Record<string, unknown>;
|
|
115
119
|
}>,
|
|
120
|
+
userMcpServers: UserMcpServerSpec[] = [],
|
|
116
121
|
): string | undefined {
|
|
117
122
|
try {
|
|
118
123
|
let toolDefs: McpToolDef[] = toolsFromContext(contextTools);
|
|
@@ -132,13 +137,13 @@ function ensureMcpConfig(
|
|
|
132
137
|
toolDefs = getCustomToolDefs(pi);
|
|
133
138
|
}
|
|
134
139
|
|
|
135
|
-
if (toolDefs.length === 0) {
|
|
140
|
+
if (toolDefs.length === 0 && userMcpServers.length === 0) {
|
|
136
141
|
cachedMcpConfig = undefined;
|
|
137
142
|
return undefined;
|
|
138
143
|
}
|
|
139
144
|
|
|
140
145
|
const hash = createHash("sha1")
|
|
141
|
-
.update(JSON.stringify(toolDefs))
|
|
146
|
+
.update(JSON.stringify({ toolDefs, userMcpServerNames: userMcpServers.map((server) => server.name) }))
|
|
142
147
|
.digest("hex")
|
|
143
148
|
.slice(0, 12);
|
|
144
149
|
|
|
@@ -147,7 +152,7 @@ function ensureMcpConfig(
|
|
|
147
152
|
return cachedMcpConfig.configPath;
|
|
148
153
|
}
|
|
149
154
|
|
|
150
|
-
const configPath = writeMcpConfig(toolDefs, hash);
|
|
155
|
+
const configPath = writeMcpConfig(toolDefs, hash, userMcpServers);
|
|
151
156
|
cachedMcpConfig = { hash, configPath };
|
|
152
157
|
const toolNames = toolDefs.map((t) => t.name).join(", ");
|
|
153
158
|
debugMcp(
|
|
@@ -250,23 +255,22 @@ export default function (pi: ExtensionAPI) {
|
|
|
250
255
|
parameters: Record<string, unknown>;
|
|
251
256
|
}> }).tools;
|
|
252
257
|
|
|
253
|
-
// Route A
|
|
254
|
-
// is on AND a bridge path is injected. OFF by default → `-p` path below.
|
|
258
|
+
// FNXC:pi-claude-cli 2026-06-27-06:39: Route A drives Claude through the ACP bridge only when the kill-switch is on AND a bridge path is injected. OFF by default → `-p` path below.
|
|
255
259
|
const bridgePath = resolveAcpBridgePath();
|
|
256
260
|
if (bridgePath) {
|
|
257
261
|
const toolDefs = resolveToolDefs(pi, contextTools);
|
|
258
|
-
const
|
|
262
|
+
const userMcpServers = getUserMcpServers(options);
|
|
263
|
+
const hash = createHash("sha1").update(JSON.stringify({ toolDefs, userMcpServerNames: userMcpServers.map((server) => server.name) })).digest("hex").slice(0, 12);
|
|
259
264
|
return streamViaAcp(model, context, {
|
|
260
265
|
...options,
|
|
261
266
|
bridgePath,
|
|
262
|
-
mcpServers: buildAcpMcpServers(toolDefs, hash),
|
|
263
|
-
// Forward only HOME/PATH so the bridged `claude` authenticates from the
|
|
264
|
-
// login/keychain session (R17); never inherited process.env or API keys.
|
|
267
|
+
mcpServers: buildAcpMcpServers(toolDefs, hash, userMcpServers),
|
|
268
|
+
// FNXC:pi-claude-cli 2026-06-27-06:39: Forward only HOME/PATH so the bridged `claude` authenticates from the login/keychain session (R17); never inherited process.env or API keys.
|
|
265
269
|
bridgeEnv: { HOME: process.env.HOME, PATH: process.env.PATH },
|
|
266
270
|
});
|
|
267
271
|
}
|
|
268
272
|
|
|
269
|
-
const configPath = ensureMcpConfig(pi, contextTools);
|
|
273
|
+
const configPath = ensureMcpConfig(pi, contextTools, getUserMcpServers(options));
|
|
270
274
|
return streamViaCli(model, context, {
|
|
271
275
|
...options,
|
|
272
276
|
mcpConfigPath: configPath,
|
|
@@ -1,38 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"private": true,
|
|
3
|
+
"version": "0.50.0",
|
|
7
4
|
"type": "module",
|
|
5
|
+
"private": true,
|
|
8
6
|
"main": "index.ts",
|
|
9
|
-
"keywords": [
|
|
10
|
-
"pi-package"
|
|
11
|
-
],
|
|
12
7
|
"pi": {
|
|
13
8
|
"extensions": [
|
|
14
9
|
"index.ts"
|
|
15
10
|
]
|
|
16
11
|
},
|
|
17
|
-
"repository": {
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "https://github.com/Runfusion/Fusion",
|
|
20
|
-
"directory": "packages/pi-claude-cli"
|
|
21
|
-
},
|
|
22
12
|
"dependencies": {
|
|
23
13
|
"@agentclientprotocol/sdk": "0.24.0"
|
|
24
14
|
},
|
|
25
|
-
"peerDependencies": {
|
|
26
|
-
"@earendil-works/pi-ai": "*",
|
|
27
|
-
"@earendil-works/pi-coding-agent": "*"
|
|
28
|
-
},
|
|
29
15
|
"devDependencies": {
|
|
30
16
|
"@types/node": "^22.0.0",
|
|
31
17
|
"typescript": "^5.7.0",
|
|
32
18
|
"vitest": "^4.1.0"
|
|
33
19
|
},
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@earendil-works/pi-ai": "*",
|
|
22
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
37
23
|
}
|
|
38
|
-
}
|
|
24
|
+
}
|
|
@@ -92,6 +92,39 @@ export function toolsFromContext(
|
|
|
92
92
|
}));
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
export interface UserMcpServerSpec {
|
|
96
|
+
name: string;
|
|
97
|
+
enabled?: boolean;
|
|
98
|
+
transport?: "stdio" | "sse" | "streamable-http";
|
|
99
|
+
command?: string;
|
|
100
|
+
args?: string[];
|
|
101
|
+
env?: Record<string, string>;
|
|
102
|
+
url?: string;
|
|
103
|
+
headers?: Record<string, string>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function userServerToConfig(server: UserMcpServerSpec): Record<string, unknown> | undefined {
|
|
107
|
+
if (server.enabled === false) return undefined;
|
|
108
|
+
if (server.transport === "sse" || server.transport === "streamable-http") {
|
|
109
|
+
if (!server.url) return undefined;
|
|
110
|
+
return {
|
|
111
|
+
transport: server.transport,
|
|
112
|
+
url: server.url,
|
|
113
|
+
...(server.headers ? { headers: server.headers } : {}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (!server.command) return undefined;
|
|
117
|
+
return {
|
|
118
|
+
command: server.command,
|
|
119
|
+
...(server.args ? { args: server.args } : {}),
|
|
120
|
+
...(server.env ? { env: server.env } : {}),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* FNXC:McpConfig 2026-06-25-22:12:
|
|
126
|
+
* The Claude CLI MCP config combines Fusion's schema-only custom-tools server with operator-enabled user MCP servers. User env/header values are already secret-materialized by the engine, so this module must write them only to the transient MCP config and never log server contents.
|
|
127
|
+
*/
|
|
95
128
|
/**
|
|
96
129
|
* Write MCP config and tool schemas to temp files.
|
|
97
130
|
*
|
|
@@ -108,6 +141,7 @@ export function toolsFromContext(
|
|
|
108
141
|
export function writeMcpConfig(
|
|
109
142
|
toolDefs: McpToolDef[],
|
|
110
143
|
cacheKey?: string,
|
|
144
|
+
userMcpServers: UserMcpServerSpec[] = [],
|
|
111
145
|
): string {
|
|
112
146
|
const suffix = cacheKey ? `${process.pid}-${cacheKey}` : `${process.pid}`;
|
|
113
147
|
|
|
@@ -124,14 +158,17 @@ export function writeMcpConfig(
|
|
|
124
158
|
const serverPath = join(__dirname, "mcp-schema-server.cjs");
|
|
125
159
|
|
|
126
160
|
// Build MCP config
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
args: [serverPath, schemaFilePath],
|
|
132
|
-
},
|
|
161
|
+
const mcpServers: Record<string, unknown> = {
|
|
162
|
+
"custom-tools": {
|
|
163
|
+
command: "node",
|
|
164
|
+
args: [serverPath, schemaFilePath],
|
|
133
165
|
},
|
|
134
166
|
};
|
|
167
|
+
for (const server of userMcpServers) {
|
|
168
|
+
const config = userServerToConfig(server);
|
|
169
|
+
if (config) mcpServers[server.name] = config;
|
|
170
|
+
}
|
|
171
|
+
const config = { mcpServers };
|
|
135
172
|
|
|
136
173
|
// Write config to temp file
|
|
137
174
|
const configFilePath = join(
|
|
@@ -151,6 +188,16 @@ export interface AcpMcpServerSpec {
|
|
|
151
188
|
env: { name: string; value: string }[];
|
|
152
189
|
}
|
|
153
190
|
|
|
191
|
+
function userServerToAcp(server: UserMcpServerSpec): AcpMcpServerSpec | undefined {
|
|
192
|
+
if (server.enabled === false || (server.transport && server.transport !== "stdio") || !server.command) return undefined;
|
|
193
|
+
return {
|
|
194
|
+
name: server.name,
|
|
195
|
+
command: server.command,
|
|
196
|
+
args: server.args ?? [],
|
|
197
|
+
env: Object.entries(server.env ?? {}).map(([name, value]) => ({ name, value })),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
154
201
|
/**
|
|
155
202
|
* Build the ACP `mcpServers` spec for the same schema-only `custom-tools` server
|
|
156
203
|
* `writeMcpConfig` produces for `--mcp-config` — but as the inline ACP shape
|
|
@@ -161,13 +208,17 @@ export interface AcpMcpServerSpec {
|
|
|
161
208
|
export function buildAcpMcpServers(
|
|
162
209
|
toolDefs: McpToolDef[],
|
|
163
210
|
cacheKey?: string,
|
|
211
|
+
userMcpServers: UserMcpServerSpec[] = [],
|
|
164
212
|
): AcpMcpServerSpec[] {
|
|
165
|
-
if (toolDefs.length === 0)
|
|
213
|
+
if (toolDefs.length === 0) {
|
|
214
|
+
return userMcpServers.map(userServerToAcp).filter((server): server is AcpMcpServerSpec => Boolean(server));
|
|
215
|
+
}
|
|
166
216
|
const suffix = cacheKey ? `${process.pid}-${cacheKey}` : `${process.pid}`;
|
|
167
217
|
const schemaFilePath = join(tmpdir(), `pi-claude-mcp-schemas-${suffix}.json`);
|
|
168
218
|
writeFileSync(schemaFilePath, JSON.stringify(toolDefs));
|
|
169
219
|
const serverPath = join(dirname(fileURLToPath(import.meta.url)), "mcp-schema-server.cjs");
|
|
170
220
|
return [
|
|
171
221
|
{ name: "custom-tools", command: "node", args: [serverPath, schemaFilePath], env: [] },
|
|
222
|
+
...userMcpServers.map(userServerToAcp).filter((server): server is AcpMcpServerSpec => Boolean(server)),
|
|
172
223
|
];
|
|
173
224
|
}
|