mcp-probe-kit 3.6.9 → 3.6.10
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/build/lib/__tests__/gitnexus-bridge.unit.test.js +28 -1
- package/build/lib/__tests__/task-defaults.unit.test.js +16 -2
- package/build/lib/gitnexus-bridge.d.ts +1 -0
- package/build/lib/gitnexus-bridge.js +15 -6
- package/build/lib/task-defaults.d.ts +2 -1
- package/build/lib/task-defaults.js +7 -4
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ import * as os from "node:os";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import spawn from "cross-spawn";
|
|
5
5
|
import { afterEach, describe, expect, test } from "vitest";
|
|
6
|
-
import { extractResolvedSymbolIdFromContext, prepareBridgeWorkspace, resolveExecutableCommand, resolveGitNexusBridgeCommand, resolveSpawnCommand, rerankQueryStructuredContent, } from "../gitnexus-bridge.js";
|
|
6
|
+
import { extractResolvedSymbolIdFromContext, prepareBridgeWorkspace, resolveExecutableCommand, resolveGitNexusBridgeCommand, resolveSpawnCommand, rerankQueryStructuredContent, tryRefreshWorkspaceIndex, } from "../gitnexus-bridge.js";
|
|
7
7
|
const tempRoots = [];
|
|
8
8
|
afterEach(() => {
|
|
9
9
|
while (tempRoots.length > 0) {
|
|
@@ -123,6 +123,33 @@ describe("gitnexus-bridge workspace preparation", () => {
|
|
|
123
123
|
expect(resolved.endsWith(".exe") || resolved === "git" || resolved === "git.cmd").toBe(true);
|
|
124
124
|
expect(spawned.command.toLowerCase()).toContain("git");
|
|
125
125
|
});
|
|
126
|
+
test("index refresh 失败时返回错误信息而不抛错", async () => {
|
|
127
|
+
const repoRoot = makeTempDir("gitnexus-index-fail-");
|
|
128
|
+
fs.mkdirSync(path.join(repoRoot, ".git"));
|
|
129
|
+
const prevCommand = process.env.MCP_GITNEXUS_COMMAND;
|
|
130
|
+
const prevPath = process.env.PATH;
|
|
131
|
+
process.env.MCP_GITNEXUS_COMMAND = path.join(repoRoot, "missing-gitnexus.cmd");
|
|
132
|
+
process.env.PATH = repoRoot;
|
|
133
|
+
try {
|
|
134
|
+
const workspace = await prepareBridgeWorkspace(repoRoot);
|
|
135
|
+
const error = await tryRefreshWorkspaceIndex(workspace);
|
|
136
|
+
expect(error).toBeTruthy();
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
if (prevCommand === undefined) {
|
|
140
|
+
delete process.env.MCP_GITNEXUS_COMMAND;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
process.env.MCP_GITNEXUS_COMMAND = prevCommand;
|
|
144
|
+
}
|
|
145
|
+
if (prevPath === undefined) {
|
|
146
|
+
delete process.env.PATH;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
process.env.PATH = prevPath;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
126
153
|
test("git 目录直接使用源仓库", async () => {
|
|
127
154
|
const repoRoot = makeTempDir("gitnexus-direct-");
|
|
128
155
|
fs.mkdirSync(path.join(repoRoot, ".git"));
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test, afterEach } from 'vitest';
|
|
2
2
|
import { isAutoTaskTool, shouldAutoEscalateToTask } from '../task-defaults.js';
|
|
3
3
|
const originalDisable = process.env.MCP_DISABLE_AUTO_TASK;
|
|
4
|
+
const originalEnable = process.env.MCP_ENABLE_AUTO_TASK;
|
|
4
5
|
afterEach(() => {
|
|
5
6
|
if (originalDisable === undefined) {
|
|
6
7
|
delete process.env.MCP_DISABLE_AUTO_TASK;
|
|
@@ -8,6 +9,12 @@ afterEach(() => {
|
|
|
8
9
|
else {
|
|
9
10
|
process.env.MCP_DISABLE_AUTO_TASK = originalDisable;
|
|
10
11
|
}
|
|
12
|
+
if (originalEnable === undefined) {
|
|
13
|
+
delete process.env.MCP_ENABLE_AUTO_TASK;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
process.env.MCP_ENABLE_AUTO_TASK = originalEnable;
|
|
17
|
+
}
|
|
11
18
|
});
|
|
12
19
|
describe('task-defaults', () => {
|
|
13
20
|
test('code_insight 与 scan 属于自动 Task 工具', () => {
|
|
@@ -15,12 +22,19 @@ describe('task-defaults', () => {
|
|
|
15
22
|
expect(isAutoTaskTool('scan_and_extract_patterns')).toBe(true);
|
|
16
23
|
expect(isAutoTaskTool('search_memory')).toBe(false);
|
|
17
24
|
});
|
|
18
|
-
test('
|
|
25
|
+
test('默认不自动升级为 Task,避免 Agent 客户端拿不到同步结果', () => {
|
|
19
26
|
delete process.env.MCP_DISABLE_AUTO_TASK;
|
|
27
|
+
delete process.env.MCP_ENABLE_AUTO_TASK;
|
|
28
|
+
expect(shouldAutoEscalateToTask('code_insight', false)).toBe(false);
|
|
29
|
+
expect(shouldAutoEscalateToTask('code_insight', true)).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
test('MCP_ENABLE_AUTO_TASK=1 时开启自动 Task', () => {
|
|
32
|
+
process.env.MCP_ENABLE_AUTO_TASK = '1';
|
|
20
33
|
expect(shouldAutoEscalateToTask('code_insight', false)).toBe(true);
|
|
21
34
|
expect(shouldAutoEscalateToTask('code_insight', true)).toBe(false);
|
|
22
35
|
});
|
|
23
|
-
test('MCP_DISABLE_AUTO_TASK=1
|
|
36
|
+
test('MCP_DISABLE_AUTO_TASK=1 时强制关闭自动 Task', () => {
|
|
37
|
+
process.env.MCP_ENABLE_AUTO_TASK = '1';
|
|
24
38
|
process.env.MCP_DISABLE_AUTO_TASK = '1';
|
|
25
39
|
expect(shouldAutoEscalateToTask('code_insight', false)).toBe(false);
|
|
26
40
|
});
|
|
@@ -98,6 +98,7 @@ export interface BridgeWorkspace {
|
|
|
98
98
|
export declare function prepareBridgeWorkspace(cwd?: string, signal?: AbortSignal, options?: {
|
|
99
99
|
bootstrap?: boolean;
|
|
100
100
|
}): Promise<BridgeWorkspace>;
|
|
101
|
+
export declare function tryRefreshWorkspaceIndex(workspace: BridgeWorkspace, signal?: AbortSignal): Promise<string | undefined>;
|
|
101
102
|
export declare function runCodeInsightBridge(request: CodeInsightRequest): Promise<CodeInsightBridgeResult>;
|
|
102
103
|
export declare function buildFeatureGraphContext(input: {
|
|
103
104
|
featureName: string;
|
|
@@ -786,12 +786,18 @@ export async function prepareBridgeWorkspace(cwd = process.cwd(), signal, option
|
|
|
786
786
|
}
|
|
787
787
|
return createTempAnalysisWorkspace(resolvedCwd, signal, options);
|
|
788
788
|
}
|
|
789
|
-
async function
|
|
789
|
+
export async function tryRefreshWorkspaceIndex(workspace, signal) {
|
|
790
790
|
if (workspace.workspaceMode !== "direct") {
|
|
791
|
-
return;
|
|
791
|
+
return undefined;
|
|
792
|
+
}
|
|
793
|
+
try {
|
|
794
|
+
const analyzeCli = resolveGitNexusCliCommand("analyze");
|
|
795
|
+
await runProcess(analyzeCli.command, analyzeCli.args, workspace.analysisRoot, signal);
|
|
796
|
+
return undefined;
|
|
797
|
+
}
|
|
798
|
+
catch (error) {
|
|
799
|
+
return normalizeError(error);
|
|
792
800
|
}
|
|
793
|
-
const analyzeCli = resolveGitNexusCliCommand("analyze");
|
|
794
|
-
await runProcess(analyzeCli.command, analyzeCli.args, workspace.analysisRoot, signal);
|
|
795
801
|
}
|
|
796
802
|
function isUnsafeHomeRoot(sourceRoot) {
|
|
797
803
|
return path.resolve(sourceRoot) === path.resolve(os.homedir());
|
|
@@ -967,12 +973,15 @@ export async function runCodeInsightBridge(request) {
|
|
|
967
973
|
};
|
|
968
974
|
}
|
|
969
975
|
const workspace = await prepareBridgeWorkspace(requestedProjectRoot, request.signal);
|
|
970
|
-
|
|
976
|
+
const warnings = [];
|
|
977
|
+
const indexRefreshError = await tryRefreshWorkspaceIndex(workspace, request.signal);
|
|
978
|
+
if (indexRefreshError) {
|
|
979
|
+
warnings.push("index_refresh_failed");
|
|
980
|
+
}
|
|
971
981
|
const effectiveRepo = workspace.workspaceMode === "temp-repo"
|
|
972
982
|
? workspace.repoName
|
|
973
983
|
: resolvePreferredRepoName(request.repo) || workspace.repoName;
|
|
974
984
|
const { command, args } = launcher;
|
|
975
|
-
const warnings = [];
|
|
976
985
|
if (workspace.workspaceMode === "temp-repo") {
|
|
977
986
|
warnings.push("temp_repo_workspace");
|
|
978
987
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 长耗时工具可选走 MCP Task,避免阻塞 stdio 宿主。
|
|
3
|
+
* 默认关闭:多数 Agent 客户端不会轮询 task 结果,自动升级会导致 code_insight 等“报错/无结果”。
|
|
3
4
|
*/
|
|
4
5
|
export declare function isAutoTaskTool(toolName: string): boolean;
|
|
5
6
|
export declare function isAutoTaskEnabled(): boolean;
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 长耗时工具可选走 MCP Task,避免阻塞 stdio 宿主。
|
|
3
|
+
* 默认关闭:多数 Agent 客户端不会轮询 task 结果,自动升级会导致 code_insight 等“报错/无结果”。
|
|
3
4
|
*/
|
|
4
5
|
const AUTO_TASK_TOOLS = new Set(['code_insight', 'scan_and_extract_patterns']);
|
|
5
6
|
export function isAutoTaskTool(toolName) {
|
|
6
7
|
return AUTO_TASK_TOOLS.has(toolName);
|
|
7
8
|
}
|
|
9
|
+
function isTruthyEnv(value) {
|
|
10
|
+
return Boolean(value && /^(1|true|yes|on)$/i.test(value.trim()));
|
|
11
|
+
}
|
|
8
12
|
export function isAutoTaskEnabled() {
|
|
9
|
-
|
|
10
|
-
if (raw && /^(1|true|yes|on)$/i.test(raw)) {
|
|
13
|
+
if (isTruthyEnv(process.env.MCP_DISABLE_AUTO_TASK)) {
|
|
11
14
|
return false;
|
|
12
15
|
}
|
|
13
|
-
return
|
|
16
|
+
return isTruthyEnv(process.env.MCP_ENABLE_AUTO_TASK);
|
|
14
17
|
}
|
|
15
18
|
export function shouldAutoEscalateToTask(toolName, hasExplicitTaskRequest) {
|
|
16
19
|
if (hasExplicitTaskRequest) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-probe-kit",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.10",
|
|
4
4
|
"description": "AI-Powered Development Toolkit - MCP Server with 30 tools covering code quality, development efficiency, project management, and UI/UX design. Features: Structured Output, Workflow Orchestration, MCP Skill auto-sync, UI/UX Pro Max, and Requirements Interview.",
|
|
5
5
|
"mcpName": "io.github.mybolide/mcp-probe-kit",
|
|
6
6
|
"type": "module",
|