@runfusion/fusion 0.77.0-beta.0 → 0.77.0-beta.2
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 +387 -72
- package/dist/child-process-worker.js +2479 -2196
- package/dist/client/.vite/manifest.json +262 -262
- package/dist/client/assets/{AgentDetailView-0G9qFd4j.js → AgentDetailView-Dew3af1O.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-BM68g7wo.js → AgentPermissionPolicyEditor-CxPQffiY.js} +1 -1
- package/dist/client/assets/{AgentsView-DkOUZWw4.js → AgentsView-Cr4LDGdt.js} +3 -3
- package/dist/client/assets/ChatView-cNYtYx05.js +13 -0
- package/dist/client/assets/{CommandCenter-DxRSFWNc.js → CommandCenter-DCC90LOP.js} +1 -1
- package/dist/client/assets/{DevServerView-DO-bqJFE.js → DevServerView-B5b520w6.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-Cp2gddTE.js → DirectoryPicker-1JvRd5mC.js} +1 -1
- package/dist/client/assets/{DocumentsView-D0E-3G96.js → DocumentsView-ksK9f7xt.js} +1 -1
- package/dist/client/assets/{EvalsView-BoFVq5hw.js → EvalsView-a3LhgRSo.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CS1Sdogm.js → ExperimentalAgentOnboardingModal-vdVa8h7F.js} +1 -1
- package/dist/client/assets/{GoalsView-sybf7JY4.js → GoalsView-Dz2o91fd.js} +1 -1
- package/dist/client/assets/{InsightsView-nHa7aShn.js → InsightsView-De3R_46d.js} +1 -1
- package/dist/client/assets/{MemoryView-D0IG44za.js → MemoryView-Cagk2wZG.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-CU76weJe.js → PiExtensionsManager-C9JABO_4.js} +1 -1
- package/dist/client/assets/{PluginManager-DyT8XbcG.js → PluginManager-D2csmdQa.js} +1 -1
- package/dist/client/assets/{PullRequestView-CnxWUSen.js → PullRequestView-DT8vTeVi.js} +1 -1
- package/dist/client/assets/{ReportModal-CMrmMQjD.js → ReportModal-YMP6V4vu.js} +1 -1
- package/dist/client/assets/{ResearchView-BTytQSgy.js → ResearchView-cNsjYu8F.js} +1 -1
- package/dist/client/assets/{SecretsView-BuSH5J87.js → SecretsView-BAmf7KyS.js} +1 -1
- package/dist/client/assets/{SessionTerminal-D04kYRrT.js → SessionTerminal-BjGcxq22.js} +1 -1
- package/dist/client/assets/{SettingsModal-Dm-ngbRr.js → SettingsModal-C_9RiEI7.js} +1 -1
- package/dist/client/assets/{SettingsModal-xSLhH7Tr.js → SettingsModal-DLfy2e_5.js} +4 -4
- package/dist/client/assets/{SettingsTextareaRow-CHPgocEp.js → SettingsTextareaRow-D8RHSj8b.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-y88aXNIQ.js → SetupWizardModal-DRJ96pHQ.js} +2 -2
- package/dist/client/assets/{SkillsView-CYyQW1Hv.js → SkillsView-DyeCwYit.js} +1 -1
- package/dist/client/assets/{WorkflowNodeEditor-hYeoz1X8.js → WorkflowNodeEditor-C5Jc9w_A.js} +3 -3
- package/dist/client/assets/{agent-import-generation-CjiYXzCr.js → agent-import-generation-SCPNeF25.js} +1 -1
- package/dist/client/assets/{agentsOrgChartLayout-C0UP_X3z.js → agentsOrgChartLayout-CqKtNCjy.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-Dd6GPcqM.js → architectureDiagram-3BPJPVTR-Cz2HYn0b.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-CC6pLxlz.js → blockDiagram-GPEHLZMM-IimJVscG.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-DxMP_l6y.js → c4Diagram-AAUBKEIU-C-xii7zn.js} +1 -1
- package/dist/client/assets/channel-D-UHgx8G.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-BKYToL43.js → chunk-2J33WTMH-DQ-9Xccu.js} +1 -1
- package/dist/client/assets/{chunk-4BX2VUAB-Bg6rjQb3.js → chunk-4BX2VUAB-DmdAX9Bx.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CPUwbbGa.js → chunk-55IACEB6-IF2bk5IL.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DScQBCvv.js → chunk-727SXJPM-AeYpIzVu.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-DbX7uaXK.js → chunk-AQP2D5EJ-DV942DD9.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-DvYKea1c.js → chunk-FMBD7UC4-Bt_riVlZ.js} +1 -1
- package/dist/client/assets/{chunk-ND2GUHAM-CH-Tvw7w.js → chunk-ND2GUHAM-CbyjNbXR.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-CbyEvOoM.js → chunk-QZHKN3VN-DqiRniYQ.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-Do-8MdAc.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Do-8MdAc.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-BPB5fV3A.js → cose-bilkent-S5V4N54A-UCvthviL.js} +1 -1
- package/dist/client/assets/{dagre-BM42HDAG-CilYJ3rR.js → dagre-BM42HDAG-DnMlT1Oi.js} +1 -1
- package/dist/client/assets/{dashboard-view-dChSM_So.js → dashboard-view-C9D0aoRW.js} +1 -1
- package/dist/client/assets/dashboard-view-Cz0sp2Wl.js +1 -0
- package/dist/client/assets/{dashboard-view-DoLU6FxZ.js → dashboard-view-JysoyDRX.js} +1 -1
- package/dist/client/assets/{dashboard-view-DnVf3tmI.js → dashboard-view-myjM9tr8.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-m9u1Qhyx.js → diagram-2AECGRRQ-BYFiqXGw.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-DVr7Kf0N.js → diagram-5GNKFQAL-DZU3pSYq.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-D7sgJDFx.js → diagram-KO2AKTUF-0ybdKuMm.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DNKNDS6r.js → diagram-LMA3HP47-Rxbgnbsp.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-1Bff4FWn.js → diagram-OG6HWLK6-BAU_hTeV.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-DGua1UHN.js → erDiagram-TEJ5UH35-zr8HrwTt.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-UDfDtwsE.js → flowDiagram-I6XJVG4X-CrTw0iFw.js} +1 -1
- package/dist/client/assets/{folder-open-CteOypVk.js → folder-open-DnAlsXXn.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-COdmD328.js → ganttDiagram-6RSMTGT7-CCORsxxz.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-SUSls7Kw.js → gitGraphDiagram-PVQCEYII-C07wWSjj.js} +1 -1
- package/dist/client/assets/index-B_z7OKl4.js +2818 -0
- package/dist/client/assets/index-DPo-IAb2.css +1 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-e_DloXj7.js → infoDiagram-5YYISTIA-hAeccD_4.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-DVWqihXg.js → ishikawaDiagram-YF4QCWOH-WLCzv-NH.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BcPY-XP0.js → journeyDiagram-JHISSGLW-ClnasNhy.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-BCFG2Jle.js → kanban-definition-UN3LZRKU-CAuARhUz.js} +1 -1
- package/dist/client/assets/{mermaid.core-5yPje9Bi.js → mermaid.core-Bh02RvfX.js} +4 -4
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-DDApeT3K.js → mindmap-definition-RKZ34NQL-KNTlbW4V.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-N61_jyeP.js → pieDiagram-4H26LBE5-BouAfBEw.js} +1 -1
- package/dist/client/assets/{puzzle-BkaCP30D.js → puzzle-CC8Ur3Cy.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-C5qHiApF.js → quadrantDiagram-W4KKPZXB-wTdkCUJU.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-C71okgzt.js → requirementDiagram-4Y6WPE33-BnjY4Tc_.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-B2iKyLjB.js → sankeyDiagram-5OEKKPKP-C-QsS08u.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DfdoYKKk.js → sequenceDiagram-3UESZ5HK-DD36MILE.js} +1 -1
- package/dist/client/assets/{shield-alert-BNSeDB8l.js → shield-alert-DcXc56Fy.js} +1 -1
- package/dist/client/assets/{standing-instructions-template-pZtzo1lK.js → standing-instructions-template-BF5y1BLz.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-lS-sUi12.js → stateDiagram-AJRCARHV-WTq1wQr1.js} +1 -1
- package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-DXJNDrV9.js → stateDiagram-v2-BHNVJYJU-eILJdjII.js} +1 -1
- package/dist/client/assets/{timeline-definition-PNZ67QCA-CCwvX81K.js → timeline-definition-PNZ67QCA-PRNwI0NR.js} +1 -1
- package/dist/client/assets/{upload-CDovVbu2.js → upload-qH_64O-B.js} +1 -1
- package/dist/client/assets/{useDiscoveredSkillsCache-BYqP-afh.js → useDiscoveredSkillsCache-C-GPCNaO.js} +1 -1
- package/dist/client/assets/{users-CTqECGLo.js → users-D2UesRE4.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-DaiR5nv9.js → vennDiagram-CIIHVFJN-CG2Z4T4O.js} +1 -1
- package/dist/client/assets/{wardley-L42UT6IY-hA5IHyPW.js → wardley-L42UT6IY-gO_fGvF9.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-CILUNESc.js → wardleyDiagram-YWT4CUSO-BkyNpjUb.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-72eNMmjz.js → xychartDiagram-2RQKCTM6-CMlZsiPq.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +345 -61
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugin-sdk/index.js +29 -2
- package/dist/plugins/fusion-plugin-acp-runtime/bundled.js +269 -16
- package/dist/plugins/fusion-plugin-acp-runtime/mcp-schema-server.cjs +171 -0
- package/dist/plugins/fusion-plugin-acp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-claude-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-claude-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-compound-engineering/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-compound-engineering/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-grok-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-grok-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-linear-import/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-linear-import/package.json +1 -1
- package/dist/plugins/fusion-plugin-omp-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-omp-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-quality/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-quality/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-todos/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-todos/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/bundled.js +29 -2
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/ChatView-BPSm2JIH.js +0 -13
- package/dist/client/assets/channel-DlCEMoEf.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-Bc92O8Ks.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bc92O8Ks.js +0 -1
- package/dist/client/assets/dashboard-view-BnGe8cWo.js +0 -1
- package/dist/client/assets/index-0ovTXt3t.css +0 -1
- package/dist/client/assets/index-DpCHwyiD.js +0 -2818
package/dist/plugin-sdk/index.js
CHANGED
|
@@ -16105,6 +16105,7 @@ function applyPromptOverridesToIr(ir, overrides) {
|
|
|
16105
16105
|
function defaultCodingWorkflowIr() {
|
|
16106
16106
|
return resolveDefaultWorkflowIr();
|
|
16107
16107
|
}
|
|
16108
|
+
var inflightSelectionReads = /* @__PURE__ */ new WeakMap();
|
|
16108
16109
|
async function resolveWorkflowIrById(store, workflowId, irCache) {
|
|
16109
16110
|
let projectId;
|
|
16110
16111
|
try {
|
|
@@ -16148,8 +16149,34 @@ function didFallBackToDefault(ir) {
|
|
|
16148
16149
|
async function resolveWorkflowIrForTaskWithProvenance(store, taskId, irCache, selectionCache) {
|
|
16149
16150
|
let workflowId;
|
|
16150
16151
|
try {
|
|
16151
|
-
const
|
|
16152
|
-
|
|
16152
|
+
const isSelectionCached = selectionCache?.has(taskId) ?? false;
|
|
16153
|
+
let selection = isSelectionCached && selectionCache ? selectionCache.get(taskId) : void 0;
|
|
16154
|
+
if (!isSelectionCached) {
|
|
16155
|
+
let inflight;
|
|
16156
|
+
let coalesced = false;
|
|
16157
|
+
if (selectionCache) {
|
|
16158
|
+
inflight = inflightSelectionReads.get(selectionCache);
|
|
16159
|
+
if (!inflight) {
|
|
16160
|
+
inflight = /* @__PURE__ */ new Map();
|
|
16161
|
+
inflightSelectionReads.set(selectionCache, inflight);
|
|
16162
|
+
}
|
|
16163
|
+
const pending = inflight.get(taskId);
|
|
16164
|
+
if (pending) {
|
|
16165
|
+
selection = await pending;
|
|
16166
|
+
coalesced = true;
|
|
16167
|
+
}
|
|
16168
|
+
}
|
|
16169
|
+
if (!coalesced) {
|
|
16170
|
+
const readPromise = store.getTaskWorkflowSelectionAsync ? store.getTaskWorkflowSelectionAsync(taskId) : Promise.resolve(store.getTaskWorkflowSelection(taskId));
|
|
16171
|
+
if (inflight) inflight.set(taskId, readPromise);
|
|
16172
|
+
try {
|
|
16173
|
+
selection = await readPromise;
|
|
16174
|
+
} finally {
|
|
16175
|
+
inflight?.delete(taskId);
|
|
16176
|
+
}
|
|
16177
|
+
}
|
|
16178
|
+
selectionCache?.set(taskId, selection);
|
|
16179
|
+
}
|
|
16153
16180
|
workflowId = selection?.workflowId;
|
|
16154
16181
|
} catch {
|
|
16155
16182
|
return { ir: defaultCodingWorkflowIr(), source: "default" };
|
|
@@ -1074,7 +1074,7 @@ function sql(strings, ...params) {
|
|
|
1074
1074
|
return new SQL([new StringChunk(str)]);
|
|
1075
1075
|
}
|
|
1076
1076
|
sql2.raw = raw;
|
|
1077
|
-
function
|
|
1077
|
+
function join5(chunks, separator) {
|
|
1078
1078
|
const result = [];
|
|
1079
1079
|
for (const [i, chunk] of chunks.entries()) {
|
|
1080
1080
|
if (i > 0 && separator !== void 0) {
|
|
@@ -1084,7 +1084,7 @@ function sql(strings, ...params) {
|
|
|
1084
1084
|
}
|
|
1085
1085
|
return new SQL(result);
|
|
1086
1086
|
}
|
|
1087
|
-
sql2.join =
|
|
1087
|
+
sql2.join = join5;
|
|
1088
1088
|
function identifier(value) {
|
|
1089
1089
|
return new Name(value);
|
|
1090
1090
|
}
|
|
@@ -4535,7 +4535,7 @@ var PgSelectQueryBuilderBase = class extends TypedQueryBuilder {
|
|
|
4535
4535
|
const baseTableName = this.tableName;
|
|
4536
4536
|
const tableName = getTableLikeName(table);
|
|
4537
4537
|
for (const item of extractUsedTable(table)) this.usedTables.add(item);
|
|
4538
|
-
if (typeof tableName === "string" && this.config.joins?.some((
|
|
4538
|
+
if (typeof tableName === "string" && this.config.joins?.some((join5) => join5.alias === tableName)) {
|
|
4539
4539
|
throw new Error(`Alias "${tableName}" is already used in this query`);
|
|
4540
4540
|
}
|
|
4541
4541
|
if (!this.isPartialSelect) {
|
|
@@ -10713,26 +10713,26 @@ function validateParallelism(nodes2, outgoing, nodesById) {
|
|
|
10713
10713
|
}
|
|
10714
10714
|
const joinsReached = /* @__PURE__ */ new Set();
|
|
10715
10715
|
for (const edge of branchEdges) {
|
|
10716
|
-
const
|
|
10717
|
-
if (!
|
|
10716
|
+
const join6 = walkBranchToJoin(edge.to, split.id, outgoing, nodesById);
|
|
10717
|
+
if (!join6) {
|
|
10718
10718
|
throw new WorkflowIrError(`split '${split.id}' has a branch with no reachable matching join`);
|
|
10719
10719
|
}
|
|
10720
|
-
joinsReached.add(
|
|
10720
|
+
joinsReached.add(join6);
|
|
10721
10721
|
}
|
|
10722
10722
|
if (joinsReached.size !== 1) {
|
|
10723
10723
|
throw new WorkflowIrError(`split '${split.id}' branches converge on more than one join`);
|
|
10724
10724
|
}
|
|
10725
10725
|
const joinId = [...joinsReached][0];
|
|
10726
|
-
const
|
|
10727
|
-
const mode =
|
|
10726
|
+
const join5 = nodesById.get(joinId);
|
|
10727
|
+
const mode = join5.config?.mode;
|
|
10728
10728
|
if (mode && typeof mode === "object" && "quorum" in mode) {
|
|
10729
10729
|
const n = mode.quorum;
|
|
10730
10730
|
if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
|
|
10731
|
-
throw new WorkflowIrError(`join '${
|
|
10731
|
+
throw new WorkflowIrError(`join '${join5.id}' quorum must be a positive integer`);
|
|
10732
10732
|
}
|
|
10733
10733
|
if (n > branchEdges.length) {
|
|
10734
10734
|
throw new WorkflowIrError(
|
|
10735
|
-
`join '${
|
|
10735
|
+
`join '${join5.id}' quorum(${n}) exceeds the split's ${branchEdges.length} branches`
|
|
10736
10736
|
);
|
|
10737
10737
|
}
|
|
10738
10738
|
}
|
|
@@ -16113,6 +16113,7 @@ function applyPromptOverridesToIr(ir, overrides) {
|
|
|
16113
16113
|
function defaultCodingWorkflowIr() {
|
|
16114
16114
|
return resolveDefaultWorkflowIr();
|
|
16115
16115
|
}
|
|
16116
|
+
var inflightSelectionReads = /* @__PURE__ */ new WeakMap();
|
|
16116
16117
|
async function resolveWorkflowIrById(store, workflowId, irCache) {
|
|
16117
16118
|
let projectId;
|
|
16118
16119
|
try {
|
|
@@ -16156,8 +16157,34 @@ function didFallBackToDefault(ir) {
|
|
|
16156
16157
|
async function resolveWorkflowIrForTaskWithProvenance(store, taskId, irCache, selectionCache) {
|
|
16157
16158
|
let workflowId;
|
|
16158
16159
|
try {
|
|
16159
|
-
const
|
|
16160
|
-
|
|
16160
|
+
const isSelectionCached = selectionCache?.has(taskId) ?? false;
|
|
16161
|
+
let selection = isSelectionCached && selectionCache ? selectionCache.get(taskId) : void 0;
|
|
16162
|
+
if (!isSelectionCached) {
|
|
16163
|
+
let inflight;
|
|
16164
|
+
let coalesced = false;
|
|
16165
|
+
if (selectionCache) {
|
|
16166
|
+
inflight = inflightSelectionReads.get(selectionCache);
|
|
16167
|
+
if (!inflight) {
|
|
16168
|
+
inflight = /* @__PURE__ */ new Map();
|
|
16169
|
+
inflightSelectionReads.set(selectionCache, inflight);
|
|
16170
|
+
}
|
|
16171
|
+
const pending = inflight.get(taskId);
|
|
16172
|
+
if (pending) {
|
|
16173
|
+
selection = await pending;
|
|
16174
|
+
coalesced = true;
|
|
16175
|
+
}
|
|
16176
|
+
}
|
|
16177
|
+
if (!coalesced) {
|
|
16178
|
+
const readPromise = store.getTaskWorkflowSelectionAsync ? store.getTaskWorkflowSelectionAsync(taskId) : Promise.resolve(store.getTaskWorkflowSelection(taskId));
|
|
16179
|
+
if (inflight) inflight.set(taskId, readPromise);
|
|
16180
|
+
try {
|
|
16181
|
+
selection = await readPromise;
|
|
16182
|
+
} finally {
|
|
16183
|
+
inflight?.delete(taskId);
|
|
16184
|
+
}
|
|
16185
|
+
}
|
|
16186
|
+
selectionCache?.set(taskId, selection);
|
|
16187
|
+
}
|
|
16161
16188
|
workflowId = selection?.workflowId;
|
|
16162
16189
|
} catch {
|
|
16163
16190
|
return { ir: defaultCodingWorkflowIr(), source: "default" };
|
|
@@ -37619,6 +37646,207 @@ function buildPromptBlocks(prompt, opts) {
|
|
|
37619
37646
|
return blocks;
|
|
37620
37647
|
}
|
|
37621
37648
|
|
|
37649
|
+
// ../../plugins/fusion-plugin-acp-runtime/src/tool-bridge.ts
|
|
37650
|
+
import { createServer } from "node:http";
|
|
37651
|
+
import { existsSync as existsSync2, unlinkSync, writeFileSync } from "node:fs";
|
|
37652
|
+
import { tmpdir } from "node:os";
|
|
37653
|
+
import { dirname as dirname4, join as join4 } from "node:path";
|
|
37654
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
37655
|
+
import { randomBytes as randomBytes2, randomUUID as randomUUID2 } from "node:crypto";
|
|
37656
|
+
var BUILT_IN_TOOL_NAMES = /* @__PURE__ */ new Set(["read", "write", "edit", "bash", "grep", "find"]);
|
|
37657
|
+
var TOOL_DRAIN_TIMEOUT_MS = 5e3;
|
|
37658
|
+
function toolsToMcpToolDefs(tools) {
|
|
37659
|
+
if (!Array.isArray(tools)) return [];
|
|
37660
|
+
return tools.filter((tool) => tool && typeof tool.name === "string" && tool.name.trim().length > 0 && !BUILT_IN_TOOL_NAMES.has(tool.name) && typeof tool.execute === "function").map((tool) => ({
|
|
37661
|
+
name: tool.name,
|
|
37662
|
+
description: typeof tool.description === "string" ? tool.description : "",
|
|
37663
|
+
inputSchema: tool.parameters ?? { type: "object", properties: {} }
|
|
37664
|
+
}));
|
|
37665
|
+
}
|
|
37666
|
+
function fusionToolsMcpServerPath() {
|
|
37667
|
+
return join4(dirname4(fileURLToPath2(import.meta.url)), "mcp-schema-server.cjs");
|
|
37668
|
+
}
|
|
37669
|
+
function missingMcpSchemaServerError(serverPath) {
|
|
37670
|
+
const error51 = new Error(`Fusion MCP schema server is missing: ${serverPath}`);
|
|
37671
|
+
error51.code = "mcp-schema-server-missing";
|
|
37672
|
+
return error51;
|
|
37673
|
+
}
|
|
37674
|
+
function resultToText(result) {
|
|
37675
|
+
if (result == null) return "";
|
|
37676
|
+
if (typeof result === "string") return result;
|
|
37677
|
+
if (typeof result === "object") {
|
|
37678
|
+
const obj = result;
|
|
37679
|
+
if (typeof obj.text === "string") return obj.text;
|
|
37680
|
+
if (Array.isArray(obj.content)) {
|
|
37681
|
+
return obj.content.map((block) => {
|
|
37682
|
+
if (block && typeof block === "object" && "text" in block && typeof block.text === "string") {
|
|
37683
|
+
return block.text;
|
|
37684
|
+
}
|
|
37685
|
+
return JSON.stringify(block);
|
|
37686
|
+
}).join("\n");
|
|
37687
|
+
}
|
|
37688
|
+
}
|
|
37689
|
+
try {
|
|
37690
|
+
return JSON.stringify(result);
|
|
37691
|
+
} catch {
|
|
37692
|
+
return String(result);
|
|
37693
|
+
}
|
|
37694
|
+
}
|
|
37695
|
+
async function startFusionToolBridge(tools) {
|
|
37696
|
+
const defs = toolsToMcpToolDefs(tools);
|
|
37697
|
+
if (defs.length === 0) return null;
|
|
37698
|
+
const serverPath = fusionToolsMcpServerPath();
|
|
37699
|
+
if (!existsSync2(serverPath)) {
|
|
37700
|
+
throw missingMcpSchemaServerError(serverPath);
|
|
37701
|
+
}
|
|
37702
|
+
const byName = /* @__PURE__ */ new Map();
|
|
37703
|
+
for (const tool of tools ?? []) {
|
|
37704
|
+
if (tool && typeof tool.name === "string" && !BUILT_IN_TOOL_NAMES.has(tool.name) && typeof tool.execute === "function") {
|
|
37705
|
+
byName.set(tool.name, tool);
|
|
37706
|
+
}
|
|
37707
|
+
}
|
|
37708
|
+
const token = randomBytes2(24).toString("hex");
|
|
37709
|
+
const schemaPath = join4(tmpdir(), `fusion-acp-mcp-schemas-${process.pid}-${randomUUID2()}.json`);
|
|
37710
|
+
writeFileSync(schemaPath, JSON.stringify(defs));
|
|
37711
|
+
const activeExecutions = /* @__PURE__ */ new Set();
|
|
37712
|
+
const activeControllers = /* @__PURE__ */ new Set();
|
|
37713
|
+
const server = createServer((req, res) => {
|
|
37714
|
+
void (async () => {
|
|
37715
|
+
if (req.method !== "POST" || req.url !== "/tool-call") {
|
|
37716
|
+
res.statusCode = 404;
|
|
37717
|
+
res.end(JSON.stringify({ isError: true, text: "not found" }));
|
|
37718
|
+
return;
|
|
37719
|
+
}
|
|
37720
|
+
const auth = req.headers.authorization;
|
|
37721
|
+
if (auth !== `Bearer ${token}`) {
|
|
37722
|
+
res.statusCode = 401;
|
|
37723
|
+
res.end(JSON.stringify({ isError: true, text: "unauthorized" }));
|
|
37724
|
+
return;
|
|
37725
|
+
}
|
|
37726
|
+
let body = "";
|
|
37727
|
+
for await (const chunk of req) body += chunk;
|
|
37728
|
+
if (disposed) {
|
|
37729
|
+
res.statusCode = 503;
|
|
37730
|
+
res.end(JSON.stringify({ isError: true, text: "tool bridge disposed" }));
|
|
37731
|
+
return;
|
|
37732
|
+
}
|
|
37733
|
+
let parsed;
|
|
37734
|
+
try {
|
|
37735
|
+
parsed = JSON.parse(body || "{}");
|
|
37736
|
+
} catch {
|
|
37737
|
+
res.statusCode = 400;
|
|
37738
|
+
res.end(JSON.stringify({ isError: true, text: "invalid JSON body" }));
|
|
37739
|
+
return;
|
|
37740
|
+
}
|
|
37741
|
+
const name = typeof parsed.name === "string" ? parsed.name : "";
|
|
37742
|
+
const tool = byName.get(name);
|
|
37743
|
+
if (!tool?.execute) {
|
|
37744
|
+
res.statusCode = 404;
|
|
37745
|
+
res.end(JSON.stringify({ isError: true, text: `Unknown Fusion tool: ${name}` }));
|
|
37746
|
+
return;
|
|
37747
|
+
}
|
|
37748
|
+
const execute = tool.execute;
|
|
37749
|
+
const controller = new AbortController();
|
|
37750
|
+
activeControllers.add(controller);
|
|
37751
|
+
const execution = (async () => {
|
|
37752
|
+
try {
|
|
37753
|
+
const result = await execute(
|
|
37754
|
+
(typeof parsed.toolCallId === "string" || typeof parsed.toolCallId === "number") && String(parsed.toolCallId) ? String(parsed.toolCallId) : `acp-mcp-${randomUUID2()}`,
|
|
37755
|
+
parsed.arguments ?? {},
|
|
37756
|
+
controller.signal,
|
|
37757
|
+
void 0,
|
|
37758
|
+
void 0
|
|
37759
|
+
);
|
|
37760
|
+
res.statusCode = 200;
|
|
37761
|
+
res.setHeader("content-type", "application/json");
|
|
37762
|
+
res.end(
|
|
37763
|
+
JSON.stringify({
|
|
37764
|
+
isError: typeof result === "object" && result !== null && "isError" in result && result.isError === true,
|
|
37765
|
+
content: [{ type: "text", text: resultToText(result) }]
|
|
37766
|
+
})
|
|
37767
|
+
);
|
|
37768
|
+
} catch (err) {
|
|
37769
|
+
res.statusCode = 200;
|
|
37770
|
+
res.setHeader("content-type", "application/json");
|
|
37771
|
+
res.end(
|
|
37772
|
+
JSON.stringify({
|
|
37773
|
+
isError: true,
|
|
37774
|
+
content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }]
|
|
37775
|
+
})
|
|
37776
|
+
);
|
|
37777
|
+
}
|
|
37778
|
+
})();
|
|
37779
|
+
activeExecutions.add(execution);
|
|
37780
|
+
try {
|
|
37781
|
+
await execution;
|
|
37782
|
+
} finally {
|
|
37783
|
+
activeExecutions.delete(execution);
|
|
37784
|
+
activeControllers.delete(controller);
|
|
37785
|
+
}
|
|
37786
|
+
})().catch(() => {
|
|
37787
|
+
});
|
|
37788
|
+
});
|
|
37789
|
+
let address;
|
|
37790
|
+
try {
|
|
37791
|
+
address = await new Promise((resolve5, reject) => {
|
|
37792
|
+
server.once("error", reject);
|
|
37793
|
+
server.listen(0, "127.0.0.1", () => {
|
|
37794
|
+
const addr = server.address();
|
|
37795
|
+
if (!addr || typeof addr === "string") {
|
|
37796
|
+
reject(new Error("tool bridge failed to bind"));
|
|
37797
|
+
return;
|
|
37798
|
+
}
|
|
37799
|
+
resolve5({ port: addr.port });
|
|
37800
|
+
});
|
|
37801
|
+
});
|
|
37802
|
+
} catch (error51) {
|
|
37803
|
+
server.close();
|
|
37804
|
+
try {
|
|
37805
|
+
unlinkSync(schemaPath);
|
|
37806
|
+
} catch {
|
|
37807
|
+
}
|
|
37808
|
+
throw error51;
|
|
37809
|
+
}
|
|
37810
|
+
const bridgeUrl = `http://127.0.0.1:${address.port}`;
|
|
37811
|
+
let disposed = false;
|
|
37812
|
+
return {
|
|
37813
|
+
toolCount: defs.length,
|
|
37814
|
+
mcpServer: {
|
|
37815
|
+
name: "fusion-custom-tools",
|
|
37816
|
+
command: process.execPath,
|
|
37817
|
+
args: [serverPath, schemaPath],
|
|
37818
|
+
env: [
|
|
37819
|
+
{ name: "FUSION_ACP_TOOL_BRIDGE_URL", value: bridgeUrl },
|
|
37820
|
+
{ name: "FUSION_ACP_TOOL_BRIDGE_TOKEN", value: token }
|
|
37821
|
+
]
|
|
37822
|
+
},
|
|
37823
|
+
dispose: async () => {
|
|
37824
|
+
if (disposed) return;
|
|
37825
|
+
disposed = true;
|
|
37826
|
+
for (const controller of activeControllers) controller.abort();
|
|
37827
|
+
server.close(() => void 0);
|
|
37828
|
+
if (typeof server.closeAllConnections === "function") {
|
|
37829
|
+
server.closeAllConnections();
|
|
37830
|
+
}
|
|
37831
|
+
await Promise.allSettled(
|
|
37832
|
+
[...activeExecutions].map(
|
|
37833
|
+
(execution) => Promise.race([
|
|
37834
|
+
execution,
|
|
37835
|
+
new Promise((resolve5) => {
|
|
37836
|
+
const timer = setTimeout(resolve5, TOOL_DRAIN_TIMEOUT_MS);
|
|
37837
|
+
timer.unref?.();
|
|
37838
|
+
})
|
|
37839
|
+
])
|
|
37840
|
+
)
|
|
37841
|
+
);
|
|
37842
|
+
try {
|
|
37843
|
+
unlinkSync(schemaPath);
|
|
37844
|
+
} catch {
|
|
37845
|
+
}
|
|
37846
|
+
}
|
|
37847
|
+
};
|
|
37848
|
+
}
|
|
37849
|
+
|
|
37622
37850
|
// ../../plugins/fusion-plugin-acp-runtime/src/runtime-adapter.ts
|
|
37623
37851
|
var AcpRuntimeAdapter = class {
|
|
37624
37852
|
id = "acp";
|
|
@@ -37658,20 +37886,38 @@ var AcpRuntimeAdapter = class {
|
|
|
37658
37886
|
clientHandler,
|
|
37659
37887
|
...this.settings.authenticate ? { authenticate: this.settings.authenticate } : {}
|
|
37660
37888
|
});
|
|
37889
|
+
let toolBridge = null;
|
|
37890
|
+
let toolBridgeFailure;
|
|
37661
37891
|
let sessionId;
|
|
37892
|
+
const customTools = Array.isArray(options.customTools) ? options.customTools : [];
|
|
37662
37893
|
try {
|
|
37894
|
+
if (customTools.length > 0) {
|
|
37895
|
+
try {
|
|
37896
|
+
toolBridge = await startFusionToolBridge(customTools);
|
|
37897
|
+
} catch (error51) {
|
|
37898
|
+
toolBridgeFailure = error51.code === "mcp-schema-server-missing" ? "mcp-schema-server-missing" : "bridge-start-failed";
|
|
37899
|
+
options.onText?.(`FUSION_TOOL_BRIDGE_FAILED: ${toolBridgeFailure}`);
|
|
37900
|
+
}
|
|
37901
|
+
}
|
|
37663
37902
|
const sessionMeta = options && typeof options === "object" && "sessionMeta" in options ? options.sessionMeta : void 0;
|
|
37664
37903
|
const opened = await newAcpSession(connection, {
|
|
37665
37904
|
cwd: options.cwd,
|
|
37666
|
-
mcpServers: options.mcpServers,
|
|
37905
|
+
mcpServers: [...options.mcpServers ?? [], ...toolBridge ? [toolBridge.mcpServer] : []],
|
|
37667
37906
|
meta: sessionMeta
|
|
37668
37907
|
});
|
|
37669
37908
|
sessionId = opened.sessionId;
|
|
37670
37909
|
} catch (err) {
|
|
37910
|
+
await toolBridge?.dispose();
|
|
37671
37911
|
connection.dispose();
|
|
37672
37912
|
throw err;
|
|
37673
37913
|
}
|
|
37674
37914
|
let disposed = false;
|
|
37915
|
+
let bridgeDisposePromise;
|
|
37916
|
+
let disposePromise = Promise.resolve();
|
|
37917
|
+
const disposeBridge = () => {
|
|
37918
|
+
bridgeDisposePromise ??= toolBridge?.dispose() ?? Promise.resolve();
|
|
37919
|
+
return bridgeDisposePromise;
|
|
37920
|
+
};
|
|
37675
37921
|
const session = {
|
|
37676
37922
|
model,
|
|
37677
37923
|
systemPrompt: options.systemPrompt,
|
|
@@ -37679,6 +37925,7 @@ var AcpRuntimeAdapter = class {
|
|
|
37679
37925
|
cwd: options.cwd,
|
|
37680
37926
|
lastModelDescription: `acp/${model}`,
|
|
37681
37927
|
callbacks,
|
|
37928
|
+
fusionToolBridgeError: toolBridgeFailure ? { reasonCode: toolBridgeFailure } : void 0,
|
|
37682
37929
|
// Persist the per-run gate (KTD3) so U5/U7 can reach the live action gate.
|
|
37683
37930
|
gate: options.actionGateContext,
|
|
37684
37931
|
connection,
|
|
@@ -37686,10 +37933,15 @@ var AcpRuntimeAdapter = class {
|
|
|
37686
37933
|
// turn that trips the per-turn output cap can't latch and suppress every
|
|
37687
37934
|
// subsequent turn (FIX 1).
|
|
37688
37935
|
resetTurn,
|
|
37936
|
+
disposeBridge,
|
|
37937
|
+
get disposePromise() {
|
|
37938
|
+
return disposePromise;
|
|
37939
|
+
},
|
|
37689
37940
|
dispose: () => {
|
|
37690
37941
|
if (disposed) return;
|
|
37691
37942
|
disposed = true;
|
|
37692
37943
|
cancelPending();
|
|
37944
|
+
disposePromise = disposeBridge();
|
|
37693
37945
|
connection.dispose();
|
|
37694
37946
|
}
|
|
37695
37947
|
};
|
|
@@ -37714,13 +37966,14 @@ var AcpRuntimeAdapter = class {
|
|
|
37714
37966
|
if (acp.connection && acp.sessionId) {
|
|
37715
37967
|
await cancelAcpSession(acp.connection, acp.sessionId);
|
|
37716
37968
|
}
|
|
37969
|
+
await acp.disposeBridge?.();
|
|
37717
37970
|
session.dispose();
|
|
37718
37971
|
}
|
|
37719
37972
|
};
|
|
37720
37973
|
|
|
37721
37974
|
// ../../plugins/fusion-plugin-acp-runtime/src/setup.ts
|
|
37722
|
-
import { dirname as
|
|
37723
|
-
import { fileURLToPath as
|
|
37975
|
+
import { dirname as dirname5, relative, resolve as resolve4, sep as sep2 } from "node:path";
|
|
37976
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
37724
37977
|
|
|
37725
37978
|
// ../../plugins/fusion-plugin-acp-runtime/src/probe.ts
|
|
37726
37979
|
function isMissingBinary(err) {
|
|
@@ -37789,7 +38042,7 @@ function isInside(parent, child) {
|
|
|
37789
38042
|
return rel === "" || !rel.startsWith("..") && !rel.includes(`..${sep2}`);
|
|
37790
38043
|
}
|
|
37791
38044
|
function defaultPluginRoot() {
|
|
37792
|
-
return resolve4(
|
|
38045
|
+
return resolve4(dirname5(fileURLToPath3(import.meta.url)), "..");
|
|
37793
38046
|
}
|
|
37794
38047
|
function validateBundledBridgeIdentity(binaryPath, pluginRoot = defaultPluginRoot()) {
|
|
37795
38048
|
const expectedBin = resolve4(bundledClaudeBridgeBinPath(pluginRoot));
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
FNXC:AcpCustomTools 2026-08-16-00:30:
|
|
4
|
+
Executable MCP bridge for Fusion custom tools (fn_*) on generic ACP paths
|
|
5
|
+
(Hermes ACP, Prime, ...). tools/list is served from a schema file; tools/call
|
|
6
|
+
POSTs to a localhost bridge owned by AcpRuntimeAdapter so ToolDefinition.execute
|
|
7
|
+
runs in-process with the engine's closures. The bridge authenticates the POST
|
|
8
|
+
with a per-session bearer token passed via FUSION_ACP_TOOL_BRIDGE_TOKEN.
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const http = require("http");
|
|
14
|
+
const readline = require("readline");
|
|
15
|
+
// FNXC:AcpCustomTools 2026-08-16-00:30: CJS has no global URL under eslint no-undef; use node:url.
|
|
16
|
+
const { URL } = require("node:url");
|
|
17
|
+
|
|
18
|
+
const schemaPath = process.argv[2];
|
|
19
|
+
const bridgeUrl = process.env.FUSION_ACP_TOOL_BRIDGE_URL;
|
|
20
|
+
const bridgeToken = process.env.FUSION_ACP_TOOL_BRIDGE_TOKEN;
|
|
21
|
+
if (!schemaPath || !bridgeUrl) {
|
|
22
|
+
process.stderr.write("fusion-custom-tools-mcp: missing schema path or FUSION_ACP_TOOL_BRIDGE_URL\n");
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let tools = [];
|
|
27
|
+
try {
|
|
28
|
+
tools = JSON.parse(fs.readFileSync(schemaPath, "utf-8"));
|
|
29
|
+
if (!Array.isArray(tools)) tools = [];
|
|
30
|
+
} catch {
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function write(msg) {
|
|
35
|
+
process.stdout.write(JSON.stringify(msg) + "\n");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function callBridge(toolName, toolCallId, args) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const body = JSON.stringify({ name: toolName, toolCallId, arguments: args ?? {} });
|
|
41
|
+
const url = new URL("/tool-call", bridgeUrl);
|
|
42
|
+
const req = http.request(
|
|
43
|
+
{
|
|
44
|
+
hostname: url.hostname,
|
|
45
|
+
port: url.port,
|
|
46
|
+
path: url.pathname,
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: {
|
|
49
|
+
"content-type": "application/json",
|
|
50
|
+
"content-length": Buffer.byteLength(body),
|
|
51
|
+
...(bridgeToken ? { authorization: `Bearer ${bridgeToken}` } : {}),
|
|
52
|
+
},
|
|
53
|
+
timeout: 120_000,
|
|
54
|
+
},
|
|
55
|
+
(res) => {
|
|
56
|
+
let data = "";
|
|
57
|
+
res.on("data", (chunk) => {
|
|
58
|
+
data += chunk;
|
|
59
|
+
});
|
|
60
|
+
res.on("end", () => {
|
|
61
|
+
// A non-2xx bridge response is a transport failure, not a tool result:
|
|
62
|
+
// surface it as an error instead of fabricating an empty "success".
|
|
63
|
+
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
64
|
+
reject(new Error(`tool bridge responded ${res.statusCode}: ${data.slice(0, 200)}`));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
resolve(JSON.parse(data || "{}"));
|
|
69
|
+
} catch (err) {
|
|
70
|
+
reject(err);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
req.on("error", reject);
|
|
76
|
+
req.on("timeout", () => {
|
|
77
|
+
req.destroy(new Error("tool bridge timeout"));
|
|
78
|
+
});
|
|
79
|
+
req.write(body);
|
|
80
|
+
req.end();
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const rl = readline.createInterface({ input: process.stdin });
|
|
85
|
+
rl.on("line", (line) => {
|
|
86
|
+
let msg;
|
|
87
|
+
try {
|
|
88
|
+
msg = JSON.parse(line);
|
|
89
|
+
} catch {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (msg.method === "initialize") {
|
|
94
|
+
write({
|
|
95
|
+
jsonrpc: "2.0",
|
|
96
|
+
id: msg.id,
|
|
97
|
+
result: {
|
|
98
|
+
protocolVersion: "2024-11-05",
|
|
99
|
+
capabilities: { tools: {} },
|
|
100
|
+
serverInfo: { name: "fusion-custom-tools", version: "1.0.0" },
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Ping must answer: some clients (Hermes ACP) treat a missing handler as a
|
|
107
|
+
// method-not-found and back off.
|
|
108
|
+
if (msg.method === "ping") {
|
|
109
|
+
write({ jsonrpc: "2.0", id: msg.id, result: {} });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (msg.method === "notifications/initialized" || msg.method === "initialized") {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (msg.method === "tools/list") {
|
|
118
|
+
write({
|
|
119
|
+
jsonrpc: "2.0",
|
|
120
|
+
id: msg.id,
|
|
121
|
+
result: {
|
|
122
|
+
tools: tools.map((tool) => ({
|
|
123
|
+
name: tool.name,
|
|
124
|
+
description: tool.description ?? "",
|
|
125
|
+
inputSchema: tool.inputSchema ?? { type: "object", properties: {} },
|
|
126
|
+
})),
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (msg.method === "tools/call") {
|
|
133
|
+
const toolName = msg.params?.name;
|
|
134
|
+
const args = msg.params?.arguments ?? {};
|
|
135
|
+
// JSON-RPC ids are commonly numbers; coerce so the bridge threads the real
|
|
136
|
+
// request id as the toolCallId instead of falling back to a fabricated id.
|
|
137
|
+
const toolCallId = typeof msg.id === "string" ? msg.id : String(msg.id);
|
|
138
|
+
callBridge(toolName, toolCallId, args)
|
|
139
|
+
.then((result) => {
|
|
140
|
+
write({
|
|
141
|
+
jsonrpc: "2.0",
|
|
142
|
+
id: msg.id,
|
|
143
|
+
result: {
|
|
144
|
+
content: Array.isArray(result.content)
|
|
145
|
+
? result.content
|
|
146
|
+
: [{ type: "text", text: typeof result.text === "string" ? result.text : JSON.stringify(result) }],
|
|
147
|
+
isError: result.isError === true,
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
})
|
|
151
|
+
.catch((err) => {
|
|
152
|
+
write({
|
|
153
|
+
jsonrpc: "2.0",
|
|
154
|
+
id: msg.id,
|
|
155
|
+
result: {
|
|
156
|
+
content: [{ type: "text", text: err instanceof Error ? err.message : String(err) }],
|
|
157
|
+
isError: true,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (msg.id !== undefined) {
|
|
165
|
+
write({
|
|
166
|
+
jsonrpc: "2.0",
|
|
167
|
+
id: msg.id,
|
|
168
|
+
error: { code: -32601, message: `Method not found: ${msg.method}` },
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
@@ -16113,6 +16113,7 @@ function applyPromptOverridesToIr(ir, overrides) {
|
|
|
16113
16113
|
function defaultCodingWorkflowIr() {
|
|
16114
16114
|
return resolveDefaultWorkflowIr();
|
|
16115
16115
|
}
|
|
16116
|
+
var inflightSelectionReads = /* @__PURE__ */ new WeakMap();
|
|
16116
16117
|
async function resolveWorkflowIrById(store, workflowId, irCache) {
|
|
16117
16118
|
let projectId;
|
|
16118
16119
|
try {
|
|
@@ -16156,8 +16157,34 @@ function didFallBackToDefault(ir) {
|
|
|
16156
16157
|
async function resolveWorkflowIrForTaskWithProvenance(store, taskId, irCache, selectionCache) {
|
|
16157
16158
|
let workflowId;
|
|
16158
16159
|
try {
|
|
16159
|
-
const
|
|
16160
|
-
|
|
16160
|
+
const isSelectionCached = selectionCache?.has(taskId) ?? false;
|
|
16161
|
+
let selection = isSelectionCached && selectionCache ? selectionCache.get(taskId) : void 0;
|
|
16162
|
+
if (!isSelectionCached) {
|
|
16163
|
+
let inflight;
|
|
16164
|
+
let coalesced = false;
|
|
16165
|
+
if (selectionCache) {
|
|
16166
|
+
inflight = inflightSelectionReads.get(selectionCache);
|
|
16167
|
+
if (!inflight) {
|
|
16168
|
+
inflight = /* @__PURE__ */ new Map();
|
|
16169
|
+
inflightSelectionReads.set(selectionCache, inflight);
|
|
16170
|
+
}
|
|
16171
|
+
const pending = inflight.get(taskId);
|
|
16172
|
+
if (pending) {
|
|
16173
|
+
selection = await pending;
|
|
16174
|
+
coalesced = true;
|
|
16175
|
+
}
|
|
16176
|
+
}
|
|
16177
|
+
if (!coalesced) {
|
|
16178
|
+
const readPromise = store.getTaskWorkflowSelectionAsync ? store.getTaskWorkflowSelectionAsync(taskId) : Promise.resolve(store.getTaskWorkflowSelection(taskId));
|
|
16179
|
+
if (inflight) inflight.set(taskId, readPromise);
|
|
16180
|
+
try {
|
|
16181
|
+
selection = await readPromise;
|
|
16182
|
+
} finally {
|
|
16183
|
+
inflight?.delete(taskId);
|
|
16184
|
+
}
|
|
16185
|
+
}
|
|
16186
|
+
selectionCache?.set(taskId, selection);
|
|
16187
|
+
}
|
|
16161
16188
|
workflowId = selection?.workflowId;
|
|
16162
16189
|
} catch {
|
|
16163
16190
|
return { ir: defaultCodingWorkflowIr(), source: "default" };
|