mcp-probe-kit 3.0.11 → 3.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -20
- package/build/lib/__tests__/gitnexus-bridge.unit.test.js +78 -19
- package/build/lib/gitnexus-bridge.d.ts +35 -2
- package/build/lib/gitnexus-bridge.js +311 -68
- package/build/tools/__tests__/code_insight.unit.test.js +51 -1
- package/build/tools/code_insight.d.ts +31 -1
- package/build/tools/code_insight.js +204 -71
- package/docs/i18n/en.json +20 -0
- package/docs/i18n/ja.json +20 -0
- package/docs/i18n/ko.json +20 -0
- package/docs/i18n/zh-CN.json +20 -0
- package/docs/pages/getting-started.html +71 -10
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -316,10 +316,10 @@ No installation needed, use the latest version directly.
|
|
|
316
316
|
}
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
-
### Method 2: Global Installation
|
|
320
|
-
|
|
321
|
-
```bash
|
|
322
|
-
npm install -g mcp-probe-kit
|
|
319
|
+
### Method 2: Global Installation
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npm install -g mcp-probe-kit
|
|
323
323
|
```
|
|
324
324
|
|
|
325
325
|
Use in config file:
|
|
@@ -330,12 +330,44 @@ Use in config file:
|
|
|
330
330
|
"command": "mcp-probe-kit"
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
|
-
}
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
###
|
|
337
|
-
|
|
338
|
-
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Windows Notes for Graph Tools
|
|
337
|
+
|
|
338
|
+
Applies to `code_insight`, `start_feature`, `start_bugfix`, and `init_project_context`.
|
|
339
|
+
|
|
340
|
+
- The GitNexus bridge uses `npx -y gitnexus@latest mcp` by default.
|
|
341
|
+
- On Windows, the first cold start can take 20+ seconds because `npx` may check/download packages.
|
|
342
|
+
- Some GitNexus dependencies use `tree-sitter-*` native modules. If your machine lacks Visual Studio Build Tools, the first install may fail with errors like `gyp ERR! find VS could not find a version of Visual Studio 2017 or newer to use`.
|
|
343
|
+
|
|
344
|
+
Recommended on Windows:
|
|
345
|
+
|
|
346
|
+
1. Install Visual Studio Build Tools with the C++ workload if you use graph-aware tools regularly.
|
|
347
|
+
2. Prefer stable local/global CLI usage for GitNexus when your MCP client supports `env`.
|
|
348
|
+
3. Increase GitNexus connect/call timeouts on slower or first-run environments.
|
|
349
|
+
|
|
350
|
+
Example config using a preinstalled `gitnexus` CLI:
|
|
351
|
+
|
|
352
|
+
```json
|
|
353
|
+
{
|
|
354
|
+
"mcpServers": {
|
|
355
|
+
"mcp-probe-kit": {
|
|
356
|
+
"command": "mcp-probe-kit",
|
|
357
|
+
"env": {
|
|
358
|
+
"MCP_GITNEXUS_COMMAND": "gitnexus",
|
|
359
|
+
"MCP_GITNEXUS_ARGS": "mcp",
|
|
360
|
+
"MCP_GITNEXUS_CONNECT_TIMEOUT_MS": "30000",
|
|
361
|
+
"MCP_GITNEXUS_TIMEOUT_MS": "45000"
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Restart Client
|
|
369
|
+
|
|
370
|
+
After configuration, **completely quit and reopen** your MCP client.
|
|
339
371
|
|
|
340
372
|
**👉 [Detailed Installation Guide](https://mcp-probe-kit.bytezonex.com/pages/getting-started.html)**
|
|
341
373
|
|
|
@@ -426,17 +458,41 @@ npx -y mcp-probe-kit@latest 2>&1 | tee ./mcp-probe-kit.log
|
|
|
426
458
|
3. Confirm JSON format is correct, no syntax errors
|
|
427
459
|
4. Check client developer tools or logs for error messages
|
|
428
460
|
|
|
429
|
-
### Q3: How to update to latest version?
|
|
430
|
-
|
|
431
|
-
**npx method (Recommended):**
|
|
432
|
-
Use `@latest` tag in config, automatically uses latest version.
|
|
433
|
-
|
|
434
|
-
**Global installation method:**
|
|
435
|
-
```bash
|
|
436
|
-
npm update -g mcp-probe-kit
|
|
437
|
-
```
|
|
461
|
+
### Q3: How to update to latest version?
|
|
462
|
+
|
|
463
|
+
**npx method (Recommended):**
|
|
464
|
+
Use `@latest` tag in config, automatically uses latest version.
|
|
438
465
|
|
|
439
|
-
|
|
466
|
+
**Global installation method:**
|
|
467
|
+
```bash
|
|
468
|
+
npm update -g mcp-probe-kit
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Q4: Why are graph-aware tools slow or timing out on Windows the first time?
|
|
472
|
+
|
|
473
|
+
This usually affects `code_insight`, `start_feature`, `start_bugfix`, and `init_project_context`.
|
|
474
|
+
|
|
475
|
+
Common causes:
|
|
476
|
+
|
|
477
|
+
1. `npx -y gitnexus@latest mcp` performs a cold start and may spend 20+ seconds checking/downloading packages.
|
|
478
|
+
2. GitNexus may need native `tree-sitter-*` modules, which can require Visual Studio Build Tools on Windows.
|
|
479
|
+
|
|
480
|
+
If you see logs like:
|
|
481
|
+
|
|
482
|
+
```text
|
|
483
|
+
gyp ERR! find VS could not find a version of Visual Studio 2017 or newer to use
|
|
484
|
+
gyp ERR! find VS - missing any VC++ toolset
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
Try this:
|
|
488
|
+
|
|
489
|
+
1. Install Visual Studio Build Tools with the C++ workload.
|
|
490
|
+
2. Retry once after dependencies finish installing.
|
|
491
|
+
3. If your client supports `env`, switch the bridge to a preinstalled `gitnexus` CLI and raise:
|
|
492
|
+
`MCP_GITNEXUS_CONNECT_TIMEOUT_MS`
|
|
493
|
+
`MCP_GITNEXUS_TIMEOUT_MS`
|
|
494
|
+
|
|
495
|
+
**👉 [More FAQ](https://mcp-probe-kit.bytezonex.com/pages/getting-started.html)**
|
|
440
496
|
|
|
441
497
|
---
|
|
442
498
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import spawn from "cross-spawn";
|
|
4
5
|
import { afterEach, describe, expect, test } from "vitest";
|
|
5
|
-
import { prepareBridgeWorkspace, resolveExecutableCommand, resolveSpawnCommand } from "../gitnexus-bridge.js";
|
|
6
|
+
import { prepareBridgeWorkspace, resolveExecutableCommand, resolveGitNexusBridgeCommand, resolveSpawnCommand, rerankQueryStructuredContent, } from "../gitnexus-bridge.js";
|
|
6
7
|
const tempRoots = [];
|
|
7
8
|
afterEach(() => {
|
|
8
9
|
while (tempRoots.length > 0) {
|
|
@@ -17,6 +18,23 @@ function makeTempDir(prefix) {
|
|
|
17
18
|
tempRoots.push(dir);
|
|
18
19
|
return dir;
|
|
19
20
|
}
|
|
21
|
+
async function runSpawned(command, args) {
|
|
22
|
+
return await new Promise((resolve, reject) => {
|
|
23
|
+
const child = spawn(command, args, { windowsHide: true });
|
|
24
|
+
let stdout = "";
|
|
25
|
+
let stderr = "";
|
|
26
|
+
child.stdout?.on("data", (chunk) => {
|
|
27
|
+
stdout += String(chunk);
|
|
28
|
+
});
|
|
29
|
+
child.stderr?.on("data", (chunk) => {
|
|
30
|
+
stderr += String(chunk);
|
|
31
|
+
});
|
|
32
|
+
child.on("error", reject);
|
|
33
|
+
child.on("close", (code) => {
|
|
34
|
+
resolve({ code, stdout, stderr });
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
20
38
|
describe("gitnexus-bridge workspace preparation", () => {
|
|
21
39
|
test("Windows 下将 npx/git 解析为 cmd 可执行文件", () => {
|
|
22
40
|
const npxResolved = resolveExecutableCommand("npx", "win32").toLowerCase();
|
|
@@ -27,34 +45,75 @@ describe("gitnexus-bridge workspace preparation", () => {
|
|
|
27
45
|
expect(resolveExecutableCommand("git", "win32").toLowerCase()).toContain("git");
|
|
28
46
|
expect(resolveExecutableCommand("npx", "linux").toLowerCase()).toContain("npx");
|
|
29
47
|
});
|
|
30
|
-
test("Windows
|
|
48
|
+
test("Windows 下 npx 命令直接交给底层 spawn 处理", () => {
|
|
31
49
|
const wrapped = resolveSpawnCommand("npx", ["-y", "gitnexus@latest", "mcp"], "win32");
|
|
32
|
-
expect(wrapped.command.toLowerCase()).toContain("cmd");
|
|
33
|
-
expect(wrapped.
|
|
34
|
-
expect(
|
|
50
|
+
expect(wrapped.command.toLowerCase()).not.toContain("cmd.exe");
|
|
51
|
+
expect(wrapped.command.toLowerCase()).toContain("npx");
|
|
52
|
+
expect(wrapped.args).toEqual(["-y", "gitnexus@latest", "mcp"]);
|
|
53
|
+
});
|
|
54
|
+
test("优先使用本地 gitnexus CLI 启动 bridge", () => {
|
|
55
|
+
const root = makeTempDir("gitnexus-cli-");
|
|
56
|
+
const executable = path.join(root, "gitnexus.cmd");
|
|
57
|
+
fs.writeFileSync(executable, "@echo off\r\necho gitnexus %*\r\n", "utf-8");
|
|
58
|
+
const resolved = resolveGitNexusBridgeCommand({
|
|
59
|
+
PATH: root,
|
|
60
|
+
PATHEXT: ".CMD;.EXE;.BAT",
|
|
61
|
+
}, "win32");
|
|
62
|
+
expect(resolved.strategy).toBe("local");
|
|
63
|
+
expect(resolved.command).toBe(executable);
|
|
64
|
+
expect(resolved.args).toEqual(["mcp"]);
|
|
65
|
+
});
|
|
66
|
+
test("显式 MCP_GITNEXUS_COMMAND 配置优先于本地 CLI 自动发现", () => {
|
|
67
|
+
const resolved = resolveGitNexusBridgeCommand({
|
|
68
|
+
MCP_GITNEXUS_COMMAND: "npx",
|
|
69
|
+
MCP_GITNEXUS_ARGS: "-y gitnexus@1.4.1 mcp",
|
|
70
|
+
PATH: "",
|
|
71
|
+
}, "win32");
|
|
72
|
+
expect(resolved.strategy).toBe("env");
|
|
73
|
+
expect(resolved.command.toLowerCase()).toContain("npx");
|
|
74
|
+
expect(resolved.args).toEqual(["-y", "gitnexus@1.4.1", "mcp"]);
|
|
35
75
|
});
|
|
36
|
-
test("
|
|
76
|
+
test("query 结果会按关键词对流程做轻量重排", () => {
|
|
77
|
+
const reranked = rerankQueryStructuredContent({
|
|
78
|
+
processes: [
|
|
79
|
+
{ heuristicLabel: "Main -> Sleep", priority: 0.12, summary: "background idle loop" },
|
|
80
|
+
{ heuristicLabel: "Login -> GenerateToken", priority: 0.08, filePath: "src/auth/login.ts" },
|
|
81
|
+
],
|
|
82
|
+
}, {
|
|
83
|
+
query: "login authentication user signin auth",
|
|
84
|
+
goal: "理解登录流程",
|
|
85
|
+
});
|
|
86
|
+
expect(reranked.changed).toBe(true);
|
|
87
|
+
expect(reranked.structuredContent.processes[0].heuristicLabel).toBe("Login -> GenerateToken");
|
|
88
|
+
expect(reranked.note).toMatch(/Top matches/i);
|
|
89
|
+
});
|
|
90
|
+
test.runIf(process.platform === "win32")("Windows 下带空格路径的 cmd 可执行文件可以真实启动", async () => {
|
|
37
91
|
const root = makeTempDir("gitnexus-space-");
|
|
38
|
-
const executable = path.join(root, "Program Files", "
|
|
92
|
+
const executable = path.join(root, "Program Files", "tool.cmd");
|
|
39
93
|
fs.mkdirSync(path.dirname(executable), { recursive: true });
|
|
40
|
-
fs.writeFileSync(executable, "@echo off\r\n", "utf-8");
|
|
94
|
+
fs.writeFileSync(executable, "@echo off\r\necho ok %*\r\n", "utf-8");
|
|
41
95
|
const wrapped = resolveSpawnCommand(executable, ["-y", "gitnexus@latest", "mcp"], "win32");
|
|
42
|
-
|
|
43
|
-
expect(wrapped.
|
|
44
|
-
expect(wrapped.args
|
|
96
|
+
const result = await runSpawned(wrapped.command, wrapped.args);
|
|
97
|
+
expect(wrapped.command).toBe(executable);
|
|
98
|
+
expect(wrapped.args).toEqual(["-y", "gitnexus@latest", "mcp"]);
|
|
99
|
+
expect(result.code).toBe(0);
|
|
100
|
+
expect(result.stdout).toContain("ok");
|
|
101
|
+
expect(result.stdout).toContain("-y");
|
|
102
|
+
expect(result.stdout).toContain("gitnexus@latest");
|
|
103
|
+
expect(result.stdout).toContain("mcp");
|
|
104
|
+
});
|
|
105
|
+
test.runIf(process.platform === "win32")("Windows 下 resolveSpawnCommand 生成的 npx 命令可真实执行", async () => {
|
|
106
|
+
const spawned = resolveSpawnCommand("npx", ["--version"], "win32");
|
|
107
|
+
const result = await runSpawned(spawned.command, spawned.args);
|
|
108
|
+
expect(result.code).toBe(0);
|
|
109
|
+
expect(result.stdout.trim().length).toBeGreaterThan(0);
|
|
45
110
|
});
|
|
46
111
|
test("Windows 下 git.exe 直接启动,不走 git.cmd 壳层", () => {
|
|
47
112
|
const resolved = resolveExecutableCommand("git", "win32").toLowerCase();
|
|
48
113
|
const spawned = resolveSpawnCommand("git", ["init", "-q"], "win32");
|
|
49
114
|
expect(resolved).toContain("git");
|
|
50
|
-
expect(resolved.endsWith(".exe") || resolved === "git").toBe(true);
|
|
51
|
-
expect(spawned.command.toLowerCase()).
|
|
52
|
-
if (spawned.command.toLowerCase().includes("cmd")) {
|
|
53
|
-
expect(String(spawned.args[3]).toLowerCase()).not.toContain("git.cmd");
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
expect(spawned.command.toLowerCase()).toContain("git");
|
|
57
|
-
}
|
|
115
|
+
expect(resolved.endsWith(".exe") || resolved === "git" || resolved === "git.cmd").toBe(true);
|
|
116
|
+
expect(spawned.command.toLowerCase()).toContain("git");
|
|
58
117
|
});
|
|
59
118
|
test("git 目录直接使用源仓库", async () => {
|
|
60
119
|
const repoRoot = makeTempDir("gitnexus-direct-");
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
export type CodeInsightMode = "auto" | "query" | "context" | "impact";
|
|
2
2
|
export type CodeInsightDirection = "upstream" | "downstream";
|
|
3
|
+
export type GitNexusLaunchStrategy = "local" | "npx" | "env";
|
|
4
|
+
export interface CodeInsightCandidate {
|
|
5
|
+
uid?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
file_path?: string;
|
|
8
|
+
kind?: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}
|
|
11
|
+
export interface CodeInsightAmbiguity {
|
|
12
|
+
tool: string;
|
|
13
|
+
message?: string;
|
|
14
|
+
candidates: CodeInsightCandidate[];
|
|
15
|
+
}
|
|
3
16
|
export interface CodeInsightRequest {
|
|
4
17
|
mode?: CodeInsightMode;
|
|
5
18
|
query?: string;
|
|
6
19
|
target?: string;
|
|
20
|
+
uid?: string;
|
|
21
|
+
filePath?: string;
|
|
7
22
|
repo?: string;
|
|
8
23
|
projectRoot?: string;
|
|
9
24
|
goal?: string;
|
|
@@ -11,6 +26,7 @@ export interface CodeInsightRequest {
|
|
|
11
26
|
direction?: CodeInsightDirection;
|
|
12
27
|
maxDepth?: number;
|
|
13
28
|
includeTests?: boolean;
|
|
29
|
+
includeContent?: boolean;
|
|
14
30
|
signal?: AbortSignal;
|
|
15
31
|
}
|
|
16
32
|
export interface CodeInsightExecution {
|
|
@@ -20,6 +36,7 @@ export interface CodeInsightExecution {
|
|
|
20
36
|
args: Record<string, unknown>;
|
|
21
37
|
text?: string;
|
|
22
38
|
structuredContent?: unknown;
|
|
39
|
+
status?: string;
|
|
23
40
|
error?: string;
|
|
24
41
|
}
|
|
25
42
|
export interface CodeInsightBridgeResult {
|
|
@@ -33,6 +50,8 @@ export interface CodeInsightBridgeResult {
|
|
|
33
50
|
executions: CodeInsightExecution[];
|
|
34
51
|
warnings: string[];
|
|
35
52
|
repo?: string;
|
|
53
|
+
launcherStrategy: GitNexusLaunchStrategy;
|
|
54
|
+
ambiguities: CodeInsightAmbiguity[];
|
|
36
55
|
workspaceMode: "direct" | "temp-repo";
|
|
37
56
|
sourceRoot: string;
|
|
38
57
|
analysisRoot: string;
|
|
@@ -48,11 +67,25 @@ export interface EmbeddedGraphContext {
|
|
|
48
67
|
mode: "query" | "context" | "impact";
|
|
49
68
|
highlights: string[];
|
|
50
69
|
}
|
|
51
|
-
export declare function
|
|
52
|
-
|
|
70
|
+
export declare function resolveGitNexusBridgeCommand(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): {
|
|
71
|
+
command: string;
|
|
72
|
+
args: string[];
|
|
73
|
+
strategy: GitNexusLaunchStrategy;
|
|
74
|
+
};
|
|
75
|
+
export declare function resolveExecutableCommand(command: string, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string;
|
|
76
|
+
export declare function resolveSpawnCommand(command: string, args: string[], platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): {
|
|
53
77
|
command: string;
|
|
54
78
|
args: string[];
|
|
55
79
|
};
|
|
80
|
+
export declare function rerankQueryStructuredContent(structuredContent: unknown, hints: {
|
|
81
|
+
query?: string;
|
|
82
|
+
goal?: string;
|
|
83
|
+
taskContext?: string;
|
|
84
|
+
}): {
|
|
85
|
+
structuredContent: unknown;
|
|
86
|
+
changed: boolean;
|
|
87
|
+
note?: string;
|
|
88
|
+
};
|
|
56
89
|
export interface BridgeWorkspace {
|
|
57
90
|
workspaceMode: "direct" | "temp-repo";
|
|
58
91
|
sourceRoot: string;
|