@roarpeng/graphflow 1.9.4 → 1.9.12
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/CHANGELOG.md +133 -0
- package/README.md +193 -107
- package/dist/agents/atp-example-producer.d.ts +33 -0
- package/dist/agents/atp-example-producer.d.ts.map +1 -0
- package/dist/agents/atp-example-producer.js +154 -0
- package/dist/agents/atp-example-producer.js.map +1 -0
- package/dist/agents/planner.d.ts.map +1 -1
- package/dist/agents/planner.js +14 -8
- package/dist/agents/planner.js.map +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +5 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/include-extensions.d.ts +3 -1
- package/dist/config/include-extensions.d.ts.map +1 -1
- package/dist/config/include-extensions.js +6 -3
- package/dist/config/include-extensions.js.map +1 -1
- package/dist/config/loader.js +1 -1
- package/dist/config/loader.js.map +1 -1
- package/dist/core/agent-delegation.d.ts +16 -2
- package/dist/core/agent-delegation.d.ts.map +1 -1
- package/dist/core/agent-delegation.js +48 -5
- package/dist/core/agent-delegation.js.map +1 -1
- package/dist/core/merge-agent-insight.d.ts.map +1 -1
- package/dist/core/merge-agent-insight.js +10 -0
- package/dist/core/merge-agent-insight.js.map +1 -1
- package/dist/core/orchestrator-episode.d.ts.map +1 -1
- package/dist/core/orchestrator-episode.js +24 -0
- package/dist/core/orchestrator-episode.js.map +1 -1
- package/dist/core/orchestrator.js +52 -1
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/core/submit-agent-insight.d.ts +17 -0
- package/dist/core/submit-agent-insight.d.ts.map +1 -1
- package/dist/core/submit-agent-insight.js +28 -0
- package/dist/core/submit-agent-insight.js.map +1 -1
- package/dist/core/types.d.ts +35 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/graph/client-factory.d.ts +4 -0
- package/dist/graph/client-factory.d.ts.map +1 -1
- package/dist/graph/client-factory.js +83 -7
- package/dist/graph/client-factory.js.map +1 -1
- package/dist/graph/context-slicer-types.d.ts +4 -0
- package/dist/graph/context-slicer-types.d.ts.map +1 -1
- package/dist/graph/context-slicer-types.js +3 -0
- package/dist/graph/context-slicer-types.js.map +1 -1
- package/dist/graph/context-slicer.d.ts.map +1 -1
- package/dist/graph/context-slicer.js +154 -6
- package/dist/graph/context-slicer.js.map +1 -1
- package/dist/graph/document-convert.d.ts +33 -0
- package/dist/graph/document-convert.d.ts.map +1 -0
- package/dist/graph/document-convert.js +137 -0
- package/dist/graph/document-convert.js.map +1 -0
- package/dist/graph/document-semantic-bridge.d.ts +23 -0
- package/dist/graph/document-semantic-bridge.d.ts.map +1 -0
- package/dist/graph/document-semantic-bridge.js +61 -0
- package/dist/graph/document-semantic-bridge.js.map +1 -0
- package/dist/graph/document-semantic-ingest.d.ts +48 -0
- package/dist/graph/document-semantic-ingest.d.ts.map +1 -0
- package/dist/graph/document-semantic-ingest.js +229 -0
- package/dist/graph/document-semantic-ingest.js.map +1 -0
- package/dist/graph/episode-engineering-links.d.ts +29 -0
- package/dist/graph/episode-engineering-links.d.ts.map +1 -0
- package/dist/graph/episode-engineering-links.js +63 -0
- package/dist/graph/episode-engineering-links.js.map +1 -0
- package/dist/graph/file-indexer-edges.d.ts +26 -0
- package/dist/graph/file-indexer-edges.d.ts.map +1 -1
- package/dist/graph/file-indexer-edges.js +120 -20
- package/dist/graph/file-indexer-edges.js.map +1 -1
- package/dist/graph/file-indexer-nodes.d.ts +18 -0
- package/dist/graph/file-indexer-nodes.d.ts.map +1 -1
- package/dist/graph/file-indexer-nodes.js +0 -0
- package/dist/graph/file-indexer-nodes.js.map +1 -1
- package/dist/graph/file-indexer-walker.d.ts +4 -1
- package/dist/graph/file-indexer-walker.d.ts.map +1 -1
- package/dist/graph/file-indexer-walker.js +33 -16
- package/dist/graph/file-indexer-walker.js.map +1 -1
- package/dist/graph/file-indexer.d.ts +5 -0
- package/dist/graph/file-indexer.d.ts.map +1 -1
- package/dist/graph/file-indexer.js +162 -50
- package/dist/graph/file-indexer.js.map +1 -1
- package/dist/graph/graph-compression.d.ts +11 -2
- package/dist/graph/graph-compression.d.ts.map +1 -1
- package/dist/graph/graph-compression.js +153 -16
- package/dist/graph/graph-compression.js.map +1 -1
- package/dist/graph/graphify-client.d.ts +1 -0
- package/dist/graph/graphify-client.d.ts.map +1 -1
- package/dist/graph/graphify-client.js +24 -9
- package/dist/graph/graphify-client.js.map +1 -1
- package/dist/graph/graphify-file-client.d.ts +1 -0
- package/dist/graph/graphify-file-client.d.ts.map +1 -1
- package/dist/graph/graphify-file-client.js +8 -2
- package/dist/graph/graphify-file-client.js.map +1 -1
- package/dist/graph/language-indexers/c-cpp.d.ts.map +1 -1
- package/dist/graph/language-indexers/c-cpp.js +19 -13
- package/dist/graph/language-indexers/c-cpp.js.map +1 -1
- package/dist/graph/language-indexers/dart.d.ts.map +1 -1
- package/dist/graph/language-indexers/dart.js +2 -6
- package/dist/graph/language-indexers/dart.js.map +1 -1
- package/dist/graph/language-indexers/go.d.ts.map +1 -1
- package/dist/graph/language-indexers/go.js +3 -6
- package/dist/graph/language-indexers/go.js.map +1 -1
- package/dist/graph/language-indexers/java.d.ts.map +1 -1
- package/dist/graph/language-indexers/java.js +2 -6
- package/dist/graph/language-indexers/java.js.map +1 -1
- package/dist/graph/language-indexers/kotlin.d.ts.map +1 -1
- package/dist/graph/language-indexers/kotlin.js +2 -6
- package/dist/graph/language-indexers/kotlin.js.map +1 -1
- package/dist/graph/language-indexers/python.d.ts.map +1 -1
- package/dist/graph/language-indexers/python.js +4 -6
- package/dist/graph/language-indexers/python.js.map +1 -1
- package/dist/graph/language-indexers/ruby.d.ts.map +1 -1
- package/dist/graph/language-indexers/ruby.js +2 -6
- package/dist/graph/language-indexers/ruby.js.map +1 -1
- package/dist/graph/language-indexers/rust.d.ts.map +1 -1
- package/dist/graph/language-indexers/rust.js +3 -6
- package/dist/graph/language-indexers/rust.js.map +1 -1
- package/dist/graph/language-indexers/swift.d.ts.map +1 -1
- package/dist/graph/language-indexers/swift.js +2 -6
- package/dist/graph/language-indexers/swift.js.map +1 -1
- package/dist/graph/language-indexers/tree-sitter-loader.d.ts +20 -0
- package/dist/graph/language-indexers/tree-sitter-loader.d.ts.map +1 -1
- package/dist/graph/language-indexers/tree-sitter-loader.js +42 -0
- package/dist/graph/language-indexers/tree-sitter-loader.js.map +1 -1
- package/dist/graph/memory-pack.d.ts +46 -0
- package/dist/graph/memory-pack.d.ts.map +1 -0
- package/dist/graph/memory-pack.js +204 -0
- package/dist/graph/memory-pack.js.map +1 -0
- package/dist/graph/snapshot-view.d.ts.map +1 -1
- package/dist/graph/snapshot-view.js +26 -1
- package/dist/graph/snapshot-view.js.map +1 -1
- package/dist/graph/sqlite-client.d.ts +1 -0
- package/dist/graph/sqlite-client.d.ts.map +1 -1
- package/dist/graph/sqlite-client.js +15 -4
- package/dist/graph/sqlite-client.js.map +1 -1
- package/dist/graph/symbol-extract.d.ts +39 -0
- package/dist/graph/symbol-extract.d.ts.map +1 -0
- package/dist/graph/symbol-extract.js +187 -0
- package/dist/graph/symbol-extract.js.map +1 -0
- package/dist/hooks/auto-capture.d.ts +87 -0
- package/dist/hooks/auto-capture.d.ts.map +1 -0
- package/dist/hooks/auto-capture.js +182 -0
- package/dist/hooks/auto-capture.js.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/agent-mcp-installer.d.ts +87 -5
- package/dist/integrations/agent-mcp-installer.d.ts.map +1 -1
- package/dist/integrations/agent-mcp-installer.js +418 -60
- package/dist/integrations/agent-mcp-installer.js.map +1 -1
- package/dist/integrations/agent-profiles/profiles/qoder.d.ts.map +1 -1
- package/dist/integrations/agent-profiles/profiles/qoder.js +14 -2
- package/dist/integrations/agent-profiles/profiles/qoder.js.map +1 -1
- package/dist/integrations/agent-profiles/skills/qoder.js +6 -0
- package/dist/integrations/agent-profiles/skills/qoder.js.map +1 -1
- package/dist/integrations/claude-code-hooks.d.ts +95 -0
- package/dist/integrations/claude-code-hooks.d.ts.map +1 -0
- package/dist/integrations/claude-code-hooks.js +321 -0
- package/dist/integrations/claude-code-hooks.js.map +1 -0
- package/dist/integrations/ensure-anydoc.d.ts +41 -0
- package/dist/integrations/ensure-anydoc.d.ts.map +1 -0
- package/dist/integrations/ensure-anydoc.js +221 -0
- package/dist/integrations/ensure-anydoc.js.map +1 -0
- package/dist/integrations/skill-installer.d.ts +26 -3
- package/dist/integrations/skill-installer.d.ts.map +1 -1
- package/dist/integrations/skill-installer.js +148 -4
- package/dist/integrations/skill-installer.js.map +1 -1
- package/dist/learning/canary-gate.d.ts +39 -0
- package/dist/learning/canary-gate.d.ts.map +1 -0
- package/dist/learning/canary-gate.js +57 -0
- package/dist/learning/canary-gate.js.map +1 -0
- package/dist/learning/skill-consolidate.d.ts +84 -0
- package/dist/learning/skill-consolidate.d.ts.map +1 -0
- package/dist/learning/skill-consolidate.js +353 -0
- package/dist/learning/skill-consolidate.js.map +1 -0
- package/dist/learning/skill-flywheel.d.ts +26 -0
- package/dist/learning/skill-flywheel.d.ts.map +1 -1
- package/dist/learning/skill-flywheel.js +192 -29
- package/dist/learning/skill-flywheel.js.map +1 -1
- package/dist/learning/skill-opt-lite.d.ts +46 -0
- package/dist/learning/skill-opt-lite.d.ts.map +1 -0
- package/dist/learning/skill-opt-lite.js +270 -0
- package/dist/learning/skill-opt-lite.js.map +1 -0
- package/dist/learning/skill-package.d.ts.map +1 -1
- package/dist/learning/skill-package.js +80 -6
- package/dist/learning/skill-package.js.map +1 -1
- package/dist/learning/skill-store.d.ts.map +1 -1
- package/dist/learning/skill-store.js +13 -0
- package/dist/learning/skill-store.js.map +1 -1
- package/dist/learning/skill-types.d.ts +32 -0
- package/dist/learning/skill-types.d.ts.map +1 -1
- package/dist/learning/skill-types.js +17 -0
- package/dist/learning/skill-types.js.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/surfaces/cli/index.js +46 -5
- package/dist/surfaces/cli/index.js.map +1 -1
- package/dist/surfaces/cli/init.d.ts +17 -4
- package/dist/surfaces/cli/init.d.ts.map +1 -1
- package/dist/surfaces/cli/init.js +71 -8
- package/dist/surfaces/cli/init.js.map +1 -1
- package/dist/surfaces/cli/output.d.ts.map +1 -1
- package/dist/surfaces/cli/output.js +4 -2
- package/dist/surfaces/cli/output.js.map +1 -1
- package/dist/surfaces/cli/runtime/facade.d.ts +2 -1
- package/dist/surfaces/cli/runtime/facade.d.ts.map +1 -1
- package/dist/surfaces/cli/runtime/facade.js +1 -0
- package/dist/surfaces/cli/runtime/facade.js.map +1 -1
- package/dist/surfaces/cli/runtime/graph.d.ts +59 -2
- package/dist/surfaces/cli/runtime/graph.d.ts.map +1 -1
- package/dist/surfaces/cli/runtime/graph.js +120 -7
- package/dist/surfaces/cli/runtime/graph.js.map +1 -1
- package/dist/surfaces/cli/runtime/learning.d.ts +19 -0
- package/dist/surfaces/cli/runtime/learning.d.ts.map +1 -1
- package/dist/surfaces/cli/runtime/learning.js +46 -0
- package/dist/surfaces/cli/runtime/learning.js.map +1 -1
- package/dist/surfaces/cli/runtime/routing.d.ts +6 -3
- package/dist/surfaces/cli/runtime/routing.d.ts.map +1 -1
- package/dist/surfaces/cli/runtime/routing.js +70 -7
- package/dist/surfaces/cli/runtime/routing.js.map +1 -1
- package/dist/surfaces/cli/runtime/types.d.ts +54 -0
- package/dist/surfaces/cli/runtime/types.d.ts.map +1 -1
- package/dist/surfaces/cli/runtime.d.ts +3 -3
- package/dist/surfaces/cli/runtime.d.ts.map +1 -1
- package/dist/surfaces/cli/runtime.js +6 -2
- package/dist/surfaces/cli/runtime.js.map +1 -1
- package/dist/surfaces/mcp/server.d.ts +12 -4
- package/dist/surfaces/mcp/server.d.ts.map +1 -1
- package/dist/surfaces/mcp/server.js +270 -97
- package/dist/surfaces/mcp/server.js.map +1 -1
- package/dist/surfaces/mcp/tool-definitions.d.ts.map +1 -1
- package/dist/surfaces/mcp/tool-definitions.js +15 -0
- package/dist/surfaces/mcp/tool-definitions.js.map +1 -1
- package/dist/surfaces/mcp/tool-handlers.d.ts +5 -3
- package/dist/surfaces/mcp/tool-handlers.d.ts.map +1 -1
- package/dist/surfaces/mcp/tool-handlers.js +36 -6
- package/dist/surfaces/mcp/tool-handlers.js.map +1 -1
- package/dist/utils/logger.d.ts +8 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +54 -5
- package/dist/utils/logger.js.map +1 -1
- package/mcp.json +14 -0
- package/package.json +19 -1
- package/plugin.json +21 -0
- package/scripts/safe-postinstall.cjs +36 -1
- package/skills/graphflow/SKILL.md +565 -0
|
@@ -8,11 +8,17 @@ exports.isEphemeralNodePath = isEphemeralNodePath;
|
|
|
8
8
|
exports.isIdeBundledNode = isIdeBundledNode;
|
|
9
9
|
exports.resolveSystemNodeCommand = resolveSystemNodeCommand;
|
|
10
10
|
exports.resolveMcpNodeLaunch = resolveMcpNodeLaunch;
|
|
11
|
+
exports.toWindowsPathFromWsl = toWindowsPathFromWsl;
|
|
12
|
+
exports.toWslPathFromWindows = toWslPathFromWindows;
|
|
11
13
|
exports.getWindowsShortPath = getWindowsShortPath;
|
|
12
14
|
exports.preferSpaceFreeWindowsPath = preferSpaceFreeWindowsPath;
|
|
13
15
|
exports.sanitizeMcpServerNodeForWindowsClients = sanitizeMcpServerNodeForWindowsClients;
|
|
14
16
|
exports.mcpNodeNeedsWindowsSpaceRepair = mcpNodeNeedsWindowsSpaceRepair;
|
|
15
17
|
exports.repairUnsafeWindowsMcpCommands = repairUnsafeWindowsMcpCommands;
|
|
18
|
+
exports.isGraphFlowMcpLauncherPath = isGraphFlowMcpLauncherPath;
|
|
19
|
+
exports.findMissingGraphFlowMcpLauncher = findMissingGraphFlowMcpLauncher;
|
|
20
|
+
exports.repairStaleGraphFlowMcpLaunchers = repairStaleGraphFlowMcpLaunchers;
|
|
21
|
+
exports.resolveWindowsNpxLaunch = resolveWindowsNpxLaunch;
|
|
16
22
|
exports.buildMcpServerNode = buildMcpServerNode;
|
|
17
23
|
exports.removeMcpEntry = removeMcpEntry;
|
|
18
24
|
exports.removeCodexMcpEntry = removeCodexMcpEntry;
|
|
@@ -467,7 +473,11 @@ function buildAgentProfiles() {
|
|
|
467
473
|
name: "Qoder",
|
|
468
474
|
markerPaths: [
|
|
469
475
|
(0, node_path_1.join)(home, ".qoder"),
|
|
476
|
+
(0, node_path_1.join)(home, ".qoder-cn"),
|
|
477
|
+
(0, node_path_1.join)(home, ".config", "Qoder"),
|
|
478
|
+
(0, node_path_1.join)(home, ".config", "QoderCN"),
|
|
470
479
|
(0, node_path_1.join)(appData, "Qoder"),
|
|
480
|
+
(0, node_path_1.join)(appData, "QoderCN"),
|
|
471
481
|
(0, node_path_1.join)(localAppData, "Programs", "qoder"),
|
|
472
482
|
],
|
|
473
483
|
userTargets: [
|
|
@@ -476,9 +486,17 @@ function buildAgentProfiles() {
|
|
|
476
486
|
serversKey: "mcpServers",
|
|
477
487
|
},
|
|
478
488
|
{
|
|
489
|
+
// Qoder 实际读取的用户级 MCP 配置(国际版,已实测生效)
|
|
479
490
|
configPath: isWindows()
|
|
480
|
-
? (0, node_path_1.join)(appData, "Qoder", "
|
|
481
|
-
: (0, node_path_1.join)(home, ".config", "Qoder", "
|
|
491
|
+
? (0, node_path_1.join)(appData, "Qoder", "SharedClientCache", "mcp.json")
|
|
492
|
+
: (0, node_path_1.join)(home, ".config", "Qoder", "SharedClientCache", "mcp.json"),
|
|
493
|
+
serversKey: "mcpServers",
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
// Qoder CN 版实际读取的用户级 MCP 配置(已实测生效)
|
|
497
|
+
configPath: isWindows()
|
|
498
|
+
? (0, node_path_1.join)(appData, "QoderCN", "SharedClientCache", "mcp.json")
|
|
499
|
+
: (0, node_path_1.join)(home, ".config", "QoderCN", "SharedClientCache", "mcp.json"),
|
|
482
500
|
serversKey: "mcpServers",
|
|
483
501
|
},
|
|
484
502
|
],
|
|
@@ -681,19 +699,54 @@ function resolveMcpNodeLaunch(options) {
|
|
|
681
699
|
// 4. Last resort: bare "node" (relies on PATH resolution at MCP launch time)
|
|
682
700
|
return { command: "node", env: { ...MCP_STDIO_ENV } };
|
|
683
701
|
}
|
|
702
|
+
/** Convert `/mnt/c/foo` ↔ `C:\foo` for WSL ↔ Windows path bridging. */
|
|
703
|
+
function toWindowsPathFromWsl(pathValue) {
|
|
704
|
+
const normalized = pathValue.replace(/\//g, "\\");
|
|
705
|
+
const mnt = normalized.match(/^\\mnt\\([A-Za-z])\\(.*)$/);
|
|
706
|
+
if (mnt?.[1] && mnt[2] !== undefined) {
|
|
707
|
+
return `${mnt[1].toUpperCase()}:\\${mnt[2]}`;
|
|
708
|
+
}
|
|
709
|
+
return pathValue.includes("/") ? pathValue.replace(/\//g, "\\") : pathValue;
|
|
710
|
+
}
|
|
711
|
+
function toWslPathFromWindows(pathValue) {
|
|
712
|
+
const match = pathValue.replace(/\//g, "\\").match(/^([A-Za-z]):\\(.*)$/);
|
|
713
|
+
if (match?.[1] && match[2] !== undefined) {
|
|
714
|
+
return `/mnt/${match[1].toLowerCase()}/${match[2].replace(/\\/g, "/")}`;
|
|
715
|
+
}
|
|
716
|
+
return pathValue;
|
|
717
|
+
}
|
|
718
|
+
function pathExistsOnWindowsHost(windowsPath) {
|
|
719
|
+
if (isWindows()) {
|
|
720
|
+
return (0, node_fs_1.existsSync)(windowsPath);
|
|
721
|
+
}
|
|
722
|
+
if (isWsl()) {
|
|
723
|
+
return (0, node_fs_1.existsSync)(toWslPathFromWindows(windowsPath));
|
|
724
|
+
}
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
684
727
|
/**
|
|
685
|
-
* On Windows, convert a long path containing spaces
|
|
686
|
-
* Many MCP clients (e.g., TRAE) spawn
|
|
687
|
-
* quoting, so
|
|
688
|
-
*
|
|
728
|
+
* On Windows (or via cmd.exe from WSL), convert a long path containing spaces
|
|
729
|
+
* to its 8.3 short form. Many MCP clients (e.g., TRAE / Codex) spawn `command`
|
|
730
|
+
* without reliable quoting, so "C:\Program Files\..." breaks. Short names like
|
|
731
|
+
* "C:\PROGRA~1\..." avoid this. Codex on Windows also needs NODE/NPX_CLI env
|
|
732
|
+
* pointing at these short paths for npx-cli registration to succeed.
|
|
689
733
|
*/
|
|
690
734
|
function getWindowsShortPath(longPath) {
|
|
691
|
-
if (!
|
|
735
|
+
if (!longPath) {
|
|
692
736
|
return longPath;
|
|
693
737
|
}
|
|
694
|
-
|
|
738
|
+
const windowsPath = isWsl() && longPath.startsWith("/mnt/")
|
|
739
|
+
? toWindowsPathFromWsl(longPath)
|
|
740
|
+
: longPath;
|
|
741
|
+
if (!windowsPath.includes(" ")) {
|
|
742
|
+
return windowsPath;
|
|
743
|
+
}
|
|
744
|
+
if (!isWindows() && !isWsl()) {
|
|
745
|
+
return undefined;
|
|
746
|
+
}
|
|
747
|
+
// Try cmd.exe first (works on native Windows and from WSL)
|
|
695
748
|
try {
|
|
696
|
-
const result = (0, node_child_process_1.execSync)(`for %A in ("${
|
|
749
|
+
const result = (0, node_child_process_1.execSync)(`for %A in ("${windowsPath}") do @echo %~sA`, {
|
|
697
750
|
encoding: "utf8",
|
|
698
751
|
stdio: ["ignore", "pipe", "ignore"],
|
|
699
752
|
timeout: 3000,
|
|
@@ -701,34 +754,36 @@ function getWindowsShortPath(longPath) {
|
|
|
701
754
|
}).trim();
|
|
702
755
|
const lines = result.split(/\r?\n/).filter((l) => l.trim());
|
|
703
756
|
const shortPath = lines[lines.length - 1]?.trim();
|
|
704
|
-
if (shortPath && !shortPath.includes(" ") && (
|
|
757
|
+
if (shortPath && !shortPath.includes(" ") && pathExistsOnWindowsHost(shortPath)) {
|
|
705
758
|
return shortPath;
|
|
706
759
|
}
|
|
707
760
|
}
|
|
708
761
|
catch {
|
|
709
762
|
// fall through to PowerShell
|
|
710
763
|
}
|
|
711
|
-
// Fallback: PowerShell with FileSystemObject COM
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
764
|
+
// Fallback: PowerShell with FileSystemObject COM (native Windows only)
|
|
765
|
+
if (isWindows()) {
|
|
766
|
+
try {
|
|
767
|
+
const escaped = windowsPath.replace(/'/g, "''");
|
|
768
|
+
const result = (0, node_child_process_1.execSync)(`$fso = New-Object -ComObject Scripting.FileSystemObject; if (Test-Path -LiteralPath '${escaped}') { if ((Get-Item -LiteralPath '${escaped}') -is [System.IO.DirectoryInfo]) { $fso.GetFolder('${escaped}').ShortPath } else { $fso.GetFile('${escaped}').ShortPath } }`, {
|
|
769
|
+
encoding: "utf8",
|
|
770
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
771
|
+
timeout: 5000,
|
|
772
|
+
shell: "powershell.exe",
|
|
773
|
+
}).trim();
|
|
774
|
+
if (result && !result.includes(" ") && (0, node_fs_1.existsSync)(result)) {
|
|
775
|
+
return result;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
catch {
|
|
779
|
+
// 8.3 name generation may be disabled on some volumes
|
|
722
780
|
}
|
|
723
|
-
}
|
|
724
|
-
catch {
|
|
725
|
-
// 8.3 name generation may be disabled on some volumes
|
|
726
781
|
}
|
|
727
782
|
return undefined;
|
|
728
783
|
}
|
|
729
784
|
/** Prefer 8.3 short path on Windows when the input contains spaces; otherwise keep as-is. */
|
|
730
785
|
function preferSpaceFreeWindowsPath(pathValue) {
|
|
731
|
-
if (!isWindows() || !pathValue.includes(" ")) {
|
|
786
|
+
if ((!isWindows() && !isWsl()) || !pathValue.includes(" ")) {
|
|
732
787
|
return pathValue;
|
|
733
788
|
}
|
|
734
789
|
return getWindowsShortPath(pathValue) ?? pathValue;
|
|
@@ -848,32 +903,270 @@ function repairUnsafeWindowsMcpCommands(serverName = "graphflow", options) {
|
|
|
848
903
|
}
|
|
849
904
|
return results;
|
|
850
905
|
}
|
|
851
|
-
|
|
852
|
-
|
|
906
|
+
/** True when a path looks like GraphFlow's extension mcp-launcher script. */
|
|
907
|
+
function isGraphFlowMcpLauncherPath(filePath) {
|
|
908
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
909
|
+
const base = (0, node_path_1.basename)(normalized).toLowerCase();
|
|
910
|
+
return base === "mcp-launcher.cjs" || base === "mcp-launcher.cmd";
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Find a missing GraphFlow mcp-launcher path referenced by an MCP server node.
|
|
914
|
+
* Returns the stale path when the node points at a launcher that is not on disk.
|
|
915
|
+
*/
|
|
916
|
+
function findMissingGraphFlowMcpLauncher(node) {
|
|
917
|
+
const candidates = [];
|
|
918
|
+
if (typeof node.command === "string" && isGraphFlowMcpLauncherPath(node.command)) {
|
|
919
|
+
candidates.push(node.command);
|
|
920
|
+
}
|
|
921
|
+
if (Array.isArray(node.args)) {
|
|
922
|
+
for (const arg of node.args) {
|
|
923
|
+
if (typeof arg === "string" && isGraphFlowMcpLauncherPath(arg)) {
|
|
924
|
+
candidates.push(arg);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
for (const candidate of candidates) {
|
|
929
|
+
if (!(0, node_fs_1.existsSync)(candidate)) {
|
|
930
|
+
return candidate;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
return undefined;
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* After VSIX upgrades, user/workspace MCP configs often still point at the previous
|
|
937
|
+
* extension folder (`…/roarpeng.graphflow-1.9.6/mcp-launcher.cjs`). Cursor Agents
|
|
938
|
+
* Window prefers project MCP and fails hard when that file is gone, while the IDE
|
|
939
|
+
* may still work via a newer user-level entry. Rewrite missing launcher refs to the
|
|
940
|
+
* active extension launcher on activate (and when Install MCP runs).
|
|
941
|
+
*/
|
|
942
|
+
function repairStaleGraphFlowMcpLaunchers(options) {
|
|
943
|
+
const launcherPath = options.launcherPath?.trim();
|
|
944
|
+
if (!launcherPath || !(0, node_fs_1.existsSync)(launcherPath)) {
|
|
945
|
+
return [];
|
|
946
|
+
}
|
|
947
|
+
const serverName = options.serverName ?? "graphflow";
|
|
948
|
+
const results = [];
|
|
949
|
+
const seen = new Set();
|
|
950
|
+
const targets = options.targets ??
|
|
951
|
+
buildAgentProfiles().flatMap((profile) => {
|
|
952
|
+
const user = profile.userTargets
|
|
953
|
+
.filter((t) => (t.configFormat ?? "json") !== "codex-toml" && (t.configFormat ?? "json") !== "opencode")
|
|
954
|
+
.map((t) => ({
|
|
955
|
+
agentId: profile.id,
|
|
956
|
+
agentName: profile.name,
|
|
957
|
+
configPath: t.configPath,
|
|
958
|
+
serversKey: t.serversKey,
|
|
959
|
+
}));
|
|
960
|
+
const workspace = options.workspaceRoot && profile.workspaceRelativePaths
|
|
961
|
+
? profile.workspaceRelativePaths
|
|
962
|
+
.filter((t) => (t.configFormat ?? "json") !== "codex-toml" && (t.configFormat ?? "json") !== "opencode")
|
|
963
|
+
.map((t) => ({
|
|
964
|
+
agentId: profile.id,
|
|
965
|
+
agentName: `${profile.name} (workspace)`,
|
|
966
|
+
configPath: (0, node_path_1.join)(options.workspaceRoot, t.relativePath),
|
|
967
|
+
serversKey: t.serversKey,
|
|
968
|
+
}))
|
|
969
|
+
: [];
|
|
970
|
+
return [...user, ...workspace];
|
|
971
|
+
});
|
|
972
|
+
for (const target of targets) {
|
|
973
|
+
const key = `${target.configPath}::${target.serversKey}`;
|
|
974
|
+
if (seen.has(key) || !(0, node_fs_1.existsSync)(target.configPath)) {
|
|
975
|
+
continue;
|
|
976
|
+
}
|
|
977
|
+
seen.add(key);
|
|
978
|
+
try {
|
|
979
|
+
const json = readJsonConfig(target.configPath);
|
|
980
|
+
const servers = json[target.serversKey] ?? {};
|
|
981
|
+
const previous = servers[serverName];
|
|
982
|
+
if (!previous || typeof previous.command !== "string") {
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
const missingLauncher = findMissingGraphFlowMcpLauncher({
|
|
986
|
+
...previous,
|
|
987
|
+
args: Array.isArray(previous.args) ? previous.args : [],
|
|
988
|
+
});
|
|
989
|
+
if (!missingLauncher) {
|
|
990
|
+
const existingLauncher = Array.isArray(previous.args)
|
|
991
|
+
? previous.args.find((a) => typeof a === "string" && isGraphFlowMcpLauncherPath(a))
|
|
992
|
+
: undefined;
|
|
993
|
+
const unrepaired = {
|
|
994
|
+
agentId: target.agentId,
|
|
995
|
+
agentName: target.agentName,
|
|
996
|
+
configPath: target.configPath,
|
|
997
|
+
repaired: false,
|
|
998
|
+
beforeCommand: previous.command,
|
|
999
|
+
afterCommand: previous.command,
|
|
1000
|
+
};
|
|
1001
|
+
if (existingLauncher) {
|
|
1002
|
+
unrepaired.beforeLauncher = existingLauncher;
|
|
1003
|
+
unrepaired.afterLauncher = existingLauncher;
|
|
1004
|
+
}
|
|
1005
|
+
results.push(unrepaired);
|
|
1006
|
+
continue;
|
|
1007
|
+
}
|
|
1008
|
+
const explicitCommand = options.command?.trim();
|
|
1009
|
+
const nextCommand = explicitCommand ||
|
|
1010
|
+
(previous.command && !isGraphFlowMcpLauncherPath(previous.command)
|
|
1011
|
+
? previous.command
|
|
1012
|
+
: "node");
|
|
1013
|
+
const nextCwd = options.cwd ?? previous.cwd;
|
|
1014
|
+
const next = {
|
|
1015
|
+
command: nextCommand,
|
|
1016
|
+
args: [launcherPath],
|
|
1017
|
+
...(nextCwd ? { cwd: nextCwd } : {}),
|
|
1018
|
+
...(previous.env ? { env: { ...previous.env } } : {}),
|
|
1019
|
+
};
|
|
1020
|
+
servers[serverName] = next;
|
|
1021
|
+
json[target.serversKey] = servers;
|
|
1022
|
+
writeJsonConfig(target.configPath, json);
|
|
1023
|
+
results.push({
|
|
1024
|
+
agentId: target.agentId,
|
|
1025
|
+
agentName: target.agentName,
|
|
1026
|
+
configPath: target.configPath,
|
|
1027
|
+
repaired: true,
|
|
1028
|
+
beforeCommand: previous.command,
|
|
1029
|
+
afterCommand: next.command,
|
|
1030
|
+
beforeLauncher: missingLauncher,
|
|
1031
|
+
afterLauncher: launcherPath,
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
1034
|
+
catch {
|
|
1035
|
+
// Config may be malformed; skip — install path will recreate.
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
return results;
|
|
1039
|
+
}
|
|
1040
|
+
function windowsDirname(windowsPath) {
|
|
1041
|
+
const normalized = windowsPath.replace(/\//g, "\\");
|
|
1042
|
+
const idx = normalized.lastIndexOf("\\");
|
|
1043
|
+
return idx >= 0 ? normalized.slice(0, idx) : ".";
|
|
1044
|
+
}
|
|
1045
|
+
function windowsJoin(...parts) {
|
|
1046
|
+
return parts
|
|
1047
|
+
.map((p, i) => {
|
|
1048
|
+
const n = p.replace(/\//g, "\\");
|
|
1049
|
+
if (i === 0) {
|
|
1050
|
+
return n.replace(/\\+$/g, "");
|
|
1051
|
+
}
|
|
1052
|
+
return n.replace(/^\\+|\\+$/g, "");
|
|
1053
|
+
})
|
|
1054
|
+
.filter((p) => p.length > 0)
|
|
1055
|
+
.join("\\");
|
|
1056
|
+
}
|
|
1057
|
+
function resolveWindowsNodeCandidates(options) {
|
|
1058
|
+
const candidates = [];
|
|
1059
|
+
if (options?.windowsNodePath?.trim()) {
|
|
1060
|
+
candidates.push(options.windowsNodePath.trim());
|
|
1061
|
+
}
|
|
1062
|
+
const wantWindows = Boolean(options?.windowsHost) || isWindows();
|
|
1063
|
+
if (!wantWindows) {
|
|
1064
|
+
return candidates;
|
|
1065
|
+
}
|
|
1066
|
+
if (isWindows()) {
|
|
1067
|
+
const system = resolveSystemNodeCommand();
|
|
1068
|
+
if (system) {
|
|
1069
|
+
candidates.push(system);
|
|
1070
|
+
}
|
|
1071
|
+
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
1072
|
+
candidates.push(windowsJoin(programFiles, "nodejs", "node.exe"));
|
|
1073
|
+
candidates.push("C:\\PROGRA~1\\nodejs\\node.exe");
|
|
1074
|
+
return candidates;
|
|
1075
|
+
}
|
|
1076
|
+
// WSL → Windows host: resolve via cmd.exe, then common mount points.
|
|
1077
|
+
try {
|
|
1078
|
+
const output = (0, node_child_process_1.execFileSync)("cmd.exe", ["/c", "where node"], {
|
|
1079
|
+
encoding: "utf8",
|
|
1080
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
1081
|
+
timeout: 3000,
|
|
1082
|
+
}).trim();
|
|
1083
|
+
for (const line of output.split(/\r?\n/).map((l) => l.trim()).filter(Boolean)) {
|
|
1084
|
+
if (/^[A-Za-z]:\\/.test(line) && !isIdeBundledNode(line)) {
|
|
1085
|
+
candidates.push(line);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
catch {
|
|
1090
|
+
// ignore
|
|
1091
|
+
}
|
|
1092
|
+
candidates.push("C:\\Program Files\\nodejs\\node.exe", "C:\\PROGRA~1\\nodejs\\node.exe", "/mnt/c/Program Files/nodejs/node.exe", "/mnt/c/PROGRA~1/nodejs/node.exe");
|
|
1093
|
+
return candidates;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* Resolve `node.exe` + `npx-cli.js` with space-free (8.3) Windows paths and
|
|
1097
|
+
* NODE/NPX_CLI env — required for Codex MCP registration on Windows.
|
|
1098
|
+
*/
|
|
1099
|
+
function resolveWindowsNpxLaunch(options) {
|
|
1100
|
+
const wantWindows = Boolean(options?.windowsHost) || isWindows();
|
|
1101
|
+
if (!wantWindows) {
|
|
1102
|
+
return undefined;
|
|
1103
|
+
}
|
|
1104
|
+
const explicitNode = options?.windowsNodePath?.trim();
|
|
1105
|
+
const explicitNpxCli = options?.windowsNpxCliPath?.trim();
|
|
1106
|
+
// Test / forced injection: trust caller paths (already short-form recommended).
|
|
1107
|
+
if (explicitNode && explicitNpxCli) {
|
|
1108
|
+
const node = explicitNode.startsWith("/mnt/")
|
|
1109
|
+
? toWindowsPathFromWsl(explicitNode)
|
|
1110
|
+
: explicitNode.replace(/\//g, "\\");
|
|
1111
|
+
const npxCli = explicitNpxCli.startsWith("/mnt/")
|
|
1112
|
+
? toWindowsPathFromWsl(explicitNpxCli)
|
|
1113
|
+
: explicitNpxCli.replace(/\//g, "\\");
|
|
1114
|
+
const shortNode = getWindowsShortPath(node) ?? node;
|
|
1115
|
+
const shortNpxCli = getWindowsShortPath(npxCli) ?? npxCli;
|
|
1116
|
+
if (shortNode.includes(" ") || shortNpxCli.includes(" ")) {
|
|
1117
|
+
return undefined;
|
|
1118
|
+
}
|
|
1119
|
+
return {
|
|
1120
|
+
command: shortNode,
|
|
1121
|
+
args: [shortNpxCli, "-y", "--package=@roarpeng/graphflow", "graphflow-mcp"],
|
|
1122
|
+
env: {
|
|
1123
|
+
NODE: shortNode,
|
|
1124
|
+
NPX_CLI: shortNpxCli,
|
|
1125
|
+
},
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
const nodeCandidates = resolveWindowsNodeCandidates(options);
|
|
1129
|
+
let node;
|
|
1130
|
+
for (const candidate of nodeCandidates) {
|
|
1131
|
+
const windowsStyle = candidate.startsWith("/mnt/")
|
|
1132
|
+
? toWindowsPathFromWsl(candidate)
|
|
1133
|
+
: candidate;
|
|
1134
|
+
if (pathExistsOnWindowsHost(windowsStyle) || pathExistsOnWindowsHost(candidate)) {
|
|
1135
|
+
node = windowsStyle;
|
|
1136
|
+
break;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
853
1139
|
if (!node) {
|
|
854
1140
|
return undefined;
|
|
855
1141
|
}
|
|
856
|
-
const nodeDir = (
|
|
857
|
-
const
|
|
858
|
-
(
|
|
859
|
-
|
|
1142
|
+
const nodeDir = windowsDirname(node);
|
|
1143
|
+
const npxCandidates = [
|
|
1144
|
+
windowsJoin(nodeDir, "node_modules", "npm", "bin", "npx-cli.js"),
|
|
1145
|
+
// Some installs put npm next to node under Program Files
|
|
1146
|
+
windowsJoin(windowsDirname(nodeDir), "node_modules", "npm", "bin", "npx-cli.js"),
|
|
860
1147
|
];
|
|
861
|
-
for (const
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
if (shortNode.includes(" ") || shortNpxCli.includes(" ")) {
|
|
868
|
-
// Can't resolve to a space-free path; fall back to npx.cmd which
|
|
869
|
-
// relies on PATH resolution and handles quoting internally.
|
|
870
|
-
return undefined;
|
|
871
|
-
}
|
|
872
|
-
return {
|
|
873
|
-
command: shortNode,
|
|
874
|
-
args: [shortNpxCli, "-y", "--package=@roarpeng/graphflow", "graphflow-mcp"],
|
|
875
|
-
};
|
|
1148
|
+
for (const npxCliRaw of npxCandidates) {
|
|
1149
|
+
const npxCli = npxCliRaw.startsWith("/mnt/")
|
|
1150
|
+
? toWindowsPathFromWsl(npxCliRaw)
|
|
1151
|
+
: npxCliRaw.replace(/\//g, "\\");
|
|
1152
|
+
if (!pathExistsOnWindowsHost(npxCli) && !pathExistsOnWindowsHost(npxCliRaw)) {
|
|
1153
|
+
continue;
|
|
876
1154
|
}
|
|
1155
|
+
const shortNode = getWindowsShortPath(node) ?? node;
|
|
1156
|
+
const shortNpxCli = getWindowsShortPath(npxCli) ?? npxCli;
|
|
1157
|
+
if (shortNode.includes(" ") || shortNpxCli.includes(" ")) {
|
|
1158
|
+
// Can't resolve to a space-free path; fall back to npx.cmd which
|
|
1159
|
+
// relies on PATH resolution and handles quoting internally.
|
|
1160
|
+
return undefined;
|
|
1161
|
+
}
|
|
1162
|
+
return {
|
|
1163
|
+
command: shortNode,
|
|
1164
|
+
args: [shortNpxCli, "-y", "--package=@roarpeng/graphflow", "graphflow-mcp"],
|
|
1165
|
+
env: {
|
|
1166
|
+
NODE: shortNode,
|
|
1167
|
+
NPX_CLI: shortNpxCli,
|
|
1168
|
+
},
|
|
1169
|
+
};
|
|
877
1170
|
}
|
|
878
1171
|
return undefined;
|
|
879
1172
|
}
|
|
@@ -947,21 +1240,26 @@ function buildMcpServerNodeRaw(options) {
|
|
|
947
1240
|
// 写入 Cursor/VS Code 可展开的 ${workspaceFolder},让 MCP 子进程拿到真实项目根。
|
|
948
1241
|
// 不支持插值的宿主会留下字面量;discover-workspace 会忽略 unresolved placeholder
|
|
949
1242
|
// 并回退到 WORKSPACE_FOLDER_PATHS / rootDir。
|
|
1243
|
+
// Codex 不支持 ${workspaceFolder},由 omitWorkspaceFolderPlaceholder 跳过。
|
|
950
1244
|
const npxEnv = {
|
|
951
1245
|
...MCP_STDIO_ENV,
|
|
952
|
-
GRAPHFLOW_WORKSPACE_ROOT: "${workspaceFolder}",
|
|
953
1246
|
};
|
|
954
|
-
if (
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1247
|
+
if (!options.omitWorkspaceFolderPlaceholder) {
|
|
1248
|
+
npxEnv.GRAPHFLOW_WORKSPACE_ROOT = "${workspaceFolder}";
|
|
1249
|
+
}
|
|
1250
|
+
const winNpx = resolveWindowsNpxLaunch({
|
|
1251
|
+
...(options.windowsHost !== undefined ? { windowsHost: options.windowsHost } : {}),
|
|
1252
|
+
...(options.windowsNodePath !== undefined ? { windowsNodePath: options.windowsNodePath } : {}),
|
|
1253
|
+
...(options.windowsNpxCliPath !== undefined ? { windowsNpxCliPath: options.windowsNpxCliPath } : {}),
|
|
1254
|
+
});
|
|
1255
|
+
if (winNpx) {
|
|
1256
|
+
return {
|
|
1257
|
+
command: winNpx.command,
|
|
1258
|
+
args: winNpx.args,
|
|
1259
|
+
env: { ...npxEnv, ...winNpx.env },
|
|
1260
|
+
};
|
|
963
1261
|
}
|
|
964
|
-
const npxCmd = isWindows() ? "npx.cmd" : "npx";
|
|
1262
|
+
const npxCmd = isWindows() || options.windowsHost ? "npx.cmd" : "npx";
|
|
965
1263
|
return {
|
|
966
1264
|
command: npxCmd,
|
|
967
1265
|
args: ["-y", "--package=@roarpeng/graphflow", "graphflow-mcp"],
|
|
@@ -1255,9 +1553,22 @@ function installMcpToDetectedAgents(options) {
|
|
|
1255
1553
|
for (const target of targets) {
|
|
1256
1554
|
try {
|
|
1257
1555
|
const { workspaceRoot, ...restOptions } = options;
|
|
1556
|
+
const windowsHost = Boolean(restOptions.windowsHost) ||
|
|
1557
|
+
isWindows() ||
|
|
1558
|
+
target.agentId.endsWith("-windows");
|
|
1559
|
+
const isCodex = target.configFormat === "codex-toml";
|
|
1258
1560
|
const node = buildMcpServerNode(target.scope === "workspace" && workspaceRoot
|
|
1259
|
-
? {
|
|
1260
|
-
|
|
1561
|
+
? {
|
|
1562
|
+
...restOptions,
|
|
1563
|
+
workspaceRoot,
|
|
1564
|
+
windowsHost,
|
|
1565
|
+
omitWorkspaceFolderPlaceholder: Boolean(restOptions.omitWorkspaceFolderPlaceholder) || isCodex,
|
|
1566
|
+
}
|
|
1567
|
+
: {
|
|
1568
|
+
...restOptions,
|
|
1569
|
+
windowsHost,
|
|
1570
|
+
omitWorkspaceFolderPlaceholder: Boolean(restOptions.omitWorkspaceFolderPlaceholder) || isCodex,
|
|
1571
|
+
});
|
|
1261
1572
|
const status = injectIntoAgentConfig(target.configPath, target.serversKey, target.configFormat, serverName, node);
|
|
1262
1573
|
results.push({
|
|
1263
1574
|
agentId: target.agentId,
|
|
@@ -1280,12 +1591,13 @@ function installMcpToDetectedAgents(options) {
|
|
|
1280
1591
|
}
|
|
1281
1592
|
return results;
|
|
1282
1593
|
}
|
|
1283
|
-
/** 从所有检测到的 agent 中移除 GraphFlow MCP
|
|
1594
|
+
/** 从所有检测到的 agent 中移除 GraphFlow MCP 配置(user + optional workspace) */
|
|
1284
1595
|
function uninstallMcpFromDetectedAgents(options) {
|
|
1285
1596
|
const profiles = buildAgentProfiles();
|
|
1286
1597
|
const detectedIds = new Set(detectInstalledAgents().map((agent) => agent.id));
|
|
1287
1598
|
const serverName = options?.serverName ?? "graphflow";
|
|
1288
1599
|
const targetAgentId = options?.agentId;
|
|
1600
|
+
const workspaceRoot = options?.workspaceRoot?.trim() || process.cwd();
|
|
1289
1601
|
const results = [];
|
|
1290
1602
|
for (const profile of profiles) {
|
|
1291
1603
|
// 如果指定了 agent,则仅处理该 agent
|
|
@@ -1318,6 +1630,7 @@ function uninstallMcpFromDetectedAgents(options) {
|
|
|
1318
1630
|
agentName: profile.name,
|
|
1319
1631
|
configPath: userTarget.configPath,
|
|
1320
1632
|
removed,
|
|
1633
|
+
scope: "user",
|
|
1321
1634
|
message: removed ? "已移除" : "未找到配置(可能已移除)",
|
|
1322
1635
|
});
|
|
1323
1636
|
}
|
|
@@ -1327,10 +1640,54 @@ function uninstallMcpFromDetectedAgents(options) {
|
|
|
1327
1640
|
agentName: profile.name,
|
|
1328
1641
|
configPath: userTarget.configPath,
|
|
1329
1642
|
removed: false,
|
|
1643
|
+
scope: "user",
|
|
1330
1644
|
message: error instanceof Error ? error.message : String(error),
|
|
1331
1645
|
});
|
|
1332
1646
|
}
|
|
1333
1647
|
}
|
|
1648
|
+
if (workspaceRoot && profile.workspaceRelativePaths) {
|
|
1649
|
+
for (const workspaceTarget of profile.workspaceRelativePaths) {
|
|
1650
|
+
const configPath = (0, node_path_1.join)(workspaceRoot, workspaceTarget.relativePath);
|
|
1651
|
+
const key = `${configPath}::${workspaceTarget.serversKey}::${workspaceTarget.configFormat ?? "json"}`;
|
|
1652
|
+
if (seen.has(key)) {
|
|
1653
|
+
continue;
|
|
1654
|
+
}
|
|
1655
|
+
seen.add(key);
|
|
1656
|
+
if (!(0, node_fs_1.existsSync)(configPath)) {
|
|
1657
|
+
continue;
|
|
1658
|
+
}
|
|
1659
|
+
try {
|
|
1660
|
+
let removed = false;
|
|
1661
|
+
if (workspaceTarget.configFormat === "codex-toml") {
|
|
1662
|
+
removed = removeCodexMcpEntry(configPath, serverName);
|
|
1663
|
+
}
|
|
1664
|
+
else if (workspaceTarget.configFormat === "opencode") {
|
|
1665
|
+
removed = removeOpencodeMcpEntry(configPath, serverName);
|
|
1666
|
+
}
|
|
1667
|
+
else {
|
|
1668
|
+
removed = removeMcpEntry(configPath, workspaceTarget.serversKey, serverName);
|
|
1669
|
+
}
|
|
1670
|
+
results.push({
|
|
1671
|
+
agentId: profile.id,
|
|
1672
|
+
agentName: `${profile.name} (workspace)`,
|
|
1673
|
+
configPath,
|
|
1674
|
+
removed,
|
|
1675
|
+
scope: "workspace",
|
|
1676
|
+
message: removed ? "已移除" : "未找到配置(可能已移除)",
|
|
1677
|
+
});
|
|
1678
|
+
}
|
|
1679
|
+
catch (error) {
|
|
1680
|
+
results.push({
|
|
1681
|
+
agentId: profile.id,
|
|
1682
|
+
agentName: `${profile.name} (workspace)`,
|
|
1683
|
+
configPath,
|
|
1684
|
+
removed: false,
|
|
1685
|
+
scope: "workspace",
|
|
1686
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1334
1691
|
}
|
|
1335
1692
|
return results;
|
|
1336
1693
|
}
|
|
@@ -1361,6 +1718,7 @@ function formatModelConfigGuide(workspaceRoot) {
|
|
|
1361
1718
|
'> "使用 graphflow 预览当前项目的 orchestrator 相关上下文"',
|
|
1362
1719
|
"",
|
|
1363
1720
|
"Codex 配置写入 `~/.codex/config.toml` 的 `[mcp_servers.graphflow]`;Trae 写入 `User/mcp.json`。",
|
|
1721
|
+
"Windows 上 Codex 使用 node.exe + npx-cli.js,并写入 NODE / NPX_CLI(优先 8.3 短路径,如 C:\\PROGRA~1\\nodejs\\...)。",
|
|
1364
1722
|
"",
|
|
1365
1723
|
"## 6. 验证路由",
|
|
1366
1724
|
"运行 `GraphFlow: Settings` 保存后,在 Chat 输入 `@graphflow /diagnose` 查看 provider 健康状态。",
|