mcp-probe-kit 3.6.1 → 3.6.3
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 +49 -11
- package/build/index.js +71 -24
- package/build/lib/__tests__/custom-mcp-resources.unit.test.d.ts +1 -0
- package/build/lib/__tests__/custom-mcp-resources.unit.test.js +135 -0
- package/build/lib/__tests__/gitnexus-bridge.unit.test.js +1 -1
- package/build/lib/__tests__/project-mcp-resources.unit.test.d.ts +1 -0
- package/build/lib/__tests__/project-mcp-resources.unit.test.js +49 -0
- package/build/lib/__tests__/workspace-root.unit.test.js +49 -1
- package/build/lib/custom-mcp-resources.d.ts +39 -0
- package/build/lib/custom-mcp-resources.js +222 -0
- package/build/lib/output-schema-registry.d.ts +8 -0
- package/build/lib/output-schema-registry.js +14 -0
- package/build/lib/project-mcp-resources.d.ts +61 -0
- package/build/lib/project-mcp-resources.js +173 -0
- package/build/lib/workflow-skill-installer.js +3 -3
- package/build/lib/workflow-skill-template.js +1 -1
- package/build/lib/workspace-root.d.ts +18 -1
- package/build/lib/workspace-root.js +149 -27
- package/build/schemas/basic-tools.d.ts +1 -1
- package/build/schemas/basic-tools.js +2 -1
- package/build/schemas/index.d.ts +2 -2
- package/build/schemas/output/project-tools.d.ts +52 -0
- package/build/schemas/output/project-tools.js +16 -0
- package/build/schemas/project-tools.d.ts +1 -1
- package/build/schemas/project-tools.js +2 -1
- package/build/tools/init_project.js +38 -7
- package/build/tools/scan_and_extract_patterns.js +1 -1
- package/package.json +1 -1
|
@@ -2,15 +2,23 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { discoverProjectRootFromLayout } from "./project-context-layout.js";
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/** Schema / 文档:project_root 参数说明(自动探测,无需用户配置 MCP_PROJECT_ROOT) */
|
|
6
|
+
export const PROJECT_ROOT_SCHEMA_DESCRIPTION = "可选。项目根目录绝对路径;未传时自动从 MCP 客户端工作区解析(如 Cursor 注入 WORKSPACE_FOLDER_PATHS、OpenCode/客户端配置的 cwd 等)。仅边缘场景需手动传入。";
|
|
7
|
+
/** MCP 客户端注入的工作区路径(最高优先级,信任客户端,不向父级 layout 上爬) */
|
|
8
|
+
const RUNTIME_CWD_ENV_KEYS = ["INIT_CWD", "PWD", "CWD"];
|
|
9
|
+
/** 用户可选覆盖(不要求在 MCP 配置里逐个填写) */
|
|
10
|
+
const OPTIONAL_OVERRIDE_ENV_KEYS = [
|
|
7
11
|
"MCP_PROJECT_ROOT",
|
|
8
12
|
"MCP_WORKSPACE_ROOT",
|
|
9
13
|
"CURSOR_WORKSPACE_ROOT",
|
|
10
14
|
"WORKSPACE_ROOT",
|
|
11
15
|
"PROJECT_ROOT",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
16
|
+
"OPENCODE_WORKSPACE",
|
|
17
|
+
"OPENCODE_CWD",
|
|
18
|
+
"OPENCODE_PROJECT_ROOT",
|
|
19
|
+
"VSCODE_CWD",
|
|
20
|
+
"CLAUDE_PROJECT_DIR",
|
|
21
|
+
"CODEX_CWD",
|
|
14
22
|
];
|
|
15
23
|
const WORKSPACE_MARKERS = [
|
|
16
24
|
".git",
|
|
@@ -23,6 +31,10 @@ const WORKSPACE_MARKERS = [
|
|
|
23
31
|
"go.mod",
|
|
24
32
|
"pyproject.toml",
|
|
25
33
|
"requirements.txt",
|
|
34
|
+
"opencode.json",
|
|
35
|
+
".opencode",
|
|
36
|
+
"AGENTS.md",
|
|
37
|
+
".agents",
|
|
26
38
|
".cursor",
|
|
27
39
|
".vscode",
|
|
28
40
|
".kiro",
|
|
@@ -81,7 +93,7 @@ function getRuntimePackageRoot() {
|
|
|
81
93
|
export function getMcpPackageInstallRoot() {
|
|
82
94
|
return getRuntimePackageRoot();
|
|
83
95
|
}
|
|
84
|
-
/** 解析
|
|
96
|
+
/** 解析 MCP 客户端注入的 WORKSPACE_FOLDER_PATHS(如 Cursor) */
|
|
85
97
|
export function resolveFromWorkspaceFolderPathsEnv() {
|
|
86
98
|
const raw = process.env.WORKSPACE_FOLDER_PATHS?.trim();
|
|
87
99
|
if (!raw) {
|
|
@@ -114,7 +126,9 @@ function findWorkspaceAncestor(start, packageRoot) {
|
|
|
114
126
|
}
|
|
115
127
|
let current = start;
|
|
116
128
|
while (true) {
|
|
117
|
-
if (current !== packageRoot &&
|
|
129
|
+
if (current !== packageRoot &&
|
|
130
|
+
!isFilesystemRoot(current) &&
|
|
131
|
+
looksLikeWorkspaceRoot(current)) {
|
|
118
132
|
return current;
|
|
119
133
|
}
|
|
120
134
|
const parent = path.dirname(current);
|
|
@@ -124,6 +138,50 @@ function findWorkspaceAncestor(start, packageRoot) {
|
|
|
124
138
|
current = parent;
|
|
125
139
|
}
|
|
126
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* 信任 MCP 客户端注入的工作区路径:仅在客户端给定目录及其子树内找 marker,
|
|
143
|
+
* 不向父级 layout 上爬(避免 monorepo 父目录抢走子项目)。
|
|
144
|
+
*/
|
|
145
|
+
function resolveTrustedClientWorkspace(clientPath, packageRoot) {
|
|
146
|
+
if (looksLikeWorkspaceRoot(clientPath)) {
|
|
147
|
+
return clientPath;
|
|
148
|
+
}
|
|
149
|
+
return findWorkspaceAncestor(clientPath, packageRoot) ?? clientPath;
|
|
150
|
+
}
|
|
151
|
+
function isFilesystemRoot(target) {
|
|
152
|
+
const normalized = path.resolve(target);
|
|
153
|
+
return normalized === path.parse(normalized).root;
|
|
154
|
+
}
|
|
155
|
+
function isUsableWorkspaceCandidate(target, packageRoot) {
|
|
156
|
+
if (!isExistingDirectory(target)) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
if (target === packageRoot || isFilesystemRoot(target)) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
function resolveFromEnvKeys(keys, packageRoot) {
|
|
165
|
+
for (const key of keys) {
|
|
166
|
+
const candidate = safeResolve(process.env[key] || "");
|
|
167
|
+
const resolved = findWorkspaceAncestor(candidate, packageRoot);
|
|
168
|
+
if (resolved) {
|
|
169
|
+
return resolved;
|
|
170
|
+
}
|
|
171
|
+
if (isUsableWorkspaceCandidate(candidate, packageRoot)) {
|
|
172
|
+
return candidate;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
function buildPackageFallbackWarning(resolved) {
|
|
178
|
+
return [
|
|
179
|
+
"未能自动识别用户项目根目录,Skill/AGENTS.md 可能写入了 mcp-probe-kit 安装目录。",
|
|
180
|
+
"请从目标项目目录打开 MCP 客户端(Cursor / OpenCode 等会自动传入工作区),",
|
|
181
|
+
"或在工具参数中传 project_root 绝对路径。",
|
|
182
|
+
`当前回退路径: ${resolved}`,
|
|
183
|
+
].join(" ");
|
|
184
|
+
}
|
|
127
185
|
export function isLikelyProjectNamedRelativePath(inputPath) {
|
|
128
186
|
if (!inputPath || path.isAbsolute(inputPath)) {
|
|
129
187
|
return false;
|
|
@@ -158,33 +216,97 @@ export function buildProjectRootRetryHint(inputPath) {
|
|
|
158
216
|
},
|
|
159
217
|
};
|
|
160
218
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
219
|
+
function buildExplicitIgnoredWarning(requested, resolved) {
|
|
220
|
+
return [
|
|
221
|
+
`未能采用传入的 project_root: ${requested}`,
|
|
222
|
+
`实际使用: ${resolved}`,
|
|
223
|
+
"请传绝对路径(Windows 建议 E:/project 或 E:\\\\project),或从目标项目目录打开 MCP 客户端以自动识别工作区。",
|
|
224
|
+
].join(" ");
|
|
225
|
+
}
|
|
226
|
+
function resolveAutoWorkspaceRoot(packageRoot) {
|
|
227
|
+
const fromWorkspaceEnv = resolveFromWorkspaceFolderPathsEnv();
|
|
228
|
+
if (fromWorkspaceEnv) {
|
|
229
|
+
const root = resolveTrustedClientWorkspace(fromWorkspaceEnv, packageRoot);
|
|
230
|
+
return {
|
|
231
|
+
root,
|
|
232
|
+
source: "workspace-env",
|
|
233
|
+
explicitHonored: false,
|
|
234
|
+
};
|
|
165
235
|
}
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
168
|
-
|
|
236
|
+
const cwd = safeResolve(process.cwd());
|
|
237
|
+
if (isUsableWorkspaceCandidate(cwd, packageRoot)) {
|
|
238
|
+
if (looksLikeWorkspaceRoot(cwd)) {
|
|
239
|
+
return { root: cwd, source: "cwd", explicitHonored: false };
|
|
240
|
+
}
|
|
241
|
+
const fromCwdAncestor = findWorkspaceAncestor(cwd, packageRoot);
|
|
242
|
+
if (fromCwdAncestor) {
|
|
243
|
+
return { root: fromCwdAncestor, source: "cwd", explicitHonored: false };
|
|
244
|
+
}
|
|
169
245
|
}
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (fromLayout) {
|
|
174
|
-
return fromLayout;
|
|
246
|
+
const fromRuntimeCwd = resolveFromEnvKeys(RUNTIME_CWD_ENV_KEYS, packageRoot);
|
|
247
|
+
if (fromRuntimeCwd) {
|
|
248
|
+
return { root: fromRuntimeCwd, source: "env", explicitHonored: false };
|
|
175
249
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
250
|
+
const fromOverride = resolveFromEnvKeys(OPTIONAL_OVERRIDE_ENV_KEYS, packageRoot);
|
|
251
|
+
if (fromOverride) {
|
|
252
|
+
return { root: fromOverride, source: "env", explicitHonored: false };
|
|
253
|
+
}
|
|
254
|
+
if (isExistingDirectory(cwd)) {
|
|
255
|
+
const fromLayout = discoverProjectRootFromLayout(cwd);
|
|
256
|
+
if (fromLayout) {
|
|
257
|
+
return { root: fromLayout, source: "layout", explicitHonored: false };
|
|
181
258
|
}
|
|
182
259
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
260
|
+
return {
|
|
261
|
+
root: packageRoot,
|
|
262
|
+
source: "package-fallback",
|
|
263
|
+
explicitHonored: false,
|
|
264
|
+
warning: buildPackageFallbackWarning(packageRoot),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* 解析项目根目录。
|
|
269
|
+
* 若调用方显式传入 project_root(非空),优先信任该路径,不再向上游走 layout 到父目录。
|
|
270
|
+
*/
|
|
271
|
+
export function resolveWorkspaceRootWithMeta(explicitProjectRoot) {
|
|
272
|
+
const explicitRaw = (explicitProjectRoot || "").trim();
|
|
273
|
+
const explicit = safeResolve(explicitRaw);
|
|
274
|
+
const packageRoot = getRuntimePackageRoot();
|
|
275
|
+
if (explicitRaw) {
|
|
276
|
+
if (isExistingDirectory(explicit)) {
|
|
277
|
+
return {
|
|
278
|
+
root: explicit,
|
|
279
|
+
source: "explicit",
|
|
280
|
+
explicitRequested: explicitRaw,
|
|
281
|
+
explicitHonored: true,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
const userMeantAbsolute = path.isAbsolute(explicitRaw) ||
|
|
285
|
+
/^[a-zA-Z]:[\\/]/.test(explicitRaw) ||
|
|
286
|
+
explicitRaw.startsWith("/") ||
|
|
287
|
+
explicitRaw.startsWith("\\\\");
|
|
288
|
+
if (explicit && userMeantAbsolute) {
|
|
289
|
+
return {
|
|
290
|
+
root: explicit,
|
|
291
|
+
source: "explicit-not-yet-created",
|
|
292
|
+
explicitRequested: explicitRaw,
|
|
293
|
+
explicitHonored: true,
|
|
294
|
+
warning: `project_root 目录尚不存在,将按该路径创建 Skill/AGENTS.md: ${explicit}`,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
const fallback = resolveAutoWorkspaceRoot(packageRoot);
|
|
298
|
+
return {
|
|
299
|
+
root: fallback.root,
|
|
300
|
+
source: fallback.source,
|
|
301
|
+
explicitRequested: explicitRaw,
|
|
302
|
+
explicitHonored: false,
|
|
303
|
+
warning: buildExplicitIgnoredWarning(explicitRaw, fallback.root),
|
|
304
|
+
};
|
|
186
305
|
}
|
|
187
|
-
return packageRoot;
|
|
306
|
+
return resolveAutoWorkspaceRoot(packageRoot);
|
|
307
|
+
}
|
|
308
|
+
export function resolveWorkspaceRoot(explicitProjectRoot) {
|
|
309
|
+
return resolveWorkspaceRootWithMeta(explicitProjectRoot).root;
|
|
188
310
|
}
|
|
189
311
|
export function toWorkspacePath(explicitProjectRoot) {
|
|
190
312
|
return resolveWorkspaceRoot(explicitProjectRoot).replace(/\\/g, "/");
|
|
@@ -17,7 +17,7 @@ export declare const basicToolSchemas: readonly [{
|
|
|
17
17
|
};
|
|
18
18
|
readonly project_root: {
|
|
19
19
|
readonly type: "string";
|
|
20
|
-
readonly description: "
|
|
20
|
+
readonly description: "可选。项目根目录绝对路径;未传时自动从 MCP 客户端工作区解析(如 Cursor 注入 WORKSPACE_FOLDER_PATHS、OpenCode/客户端配置的 cwd 等)。仅边缘场景需手动传入。";
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
readonly required: readonly [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 基础工具的 Schema 定义
|
|
3
3
|
*/
|
|
4
|
+
import { PROJECT_ROOT_SCHEMA_DESCRIPTION } from "../lib/workspace-root.js";
|
|
4
5
|
export const basicToolSchemas = [
|
|
5
6
|
{
|
|
6
7
|
name: "init_project",
|
|
@@ -18,7 +19,7 @@ export const basicToolSchemas = [
|
|
|
18
19
|
},
|
|
19
20
|
project_root: {
|
|
20
21
|
type: "string",
|
|
21
|
-
description:
|
|
22
|
+
description: PROJECT_ROOT_SCHEMA_DESCRIPTION,
|
|
22
23
|
},
|
|
23
24
|
},
|
|
24
25
|
required: [],
|
package/build/schemas/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare const allToolSchemas: ({
|
|
|
17
17
|
};
|
|
18
18
|
readonly project_root: {
|
|
19
19
|
readonly type: "string";
|
|
20
|
-
readonly description: "
|
|
20
|
+
readonly description: "可选。项目根目录绝对路径;未传时自动从 MCP 客户端工作区解析(如 Cursor 注入 WORKSPACE_FOLDER_PATHS、OpenCode/客户端配置的 cwd 等)。仅边缘场景需手动传入。";
|
|
21
21
|
};
|
|
22
22
|
};
|
|
23
23
|
readonly required: readonly [];
|
|
@@ -320,7 +320,7 @@ export declare const allToolSchemas: ({
|
|
|
320
320
|
};
|
|
321
321
|
readonly project_root: {
|
|
322
322
|
readonly type: "string";
|
|
323
|
-
readonly description: "
|
|
323
|
+
readonly description: "可选。项目根目录绝对路径;未传时自动从 MCP 客户端工作区解析(如 Cursor 注入 WORKSPACE_FOLDER_PATHS、OpenCode/客户端配置的 cwd 等)。仅边缘场景需手动传入。";
|
|
324
324
|
};
|
|
325
325
|
};
|
|
326
326
|
readonly required: readonly [];
|
|
@@ -15,6 +15,46 @@ export declare const ProjectInitSchema: {
|
|
|
15
15
|
readonly projectName: {
|
|
16
16
|
readonly type: "string";
|
|
17
17
|
};
|
|
18
|
+
readonly projectRoot: {
|
|
19
|
+
readonly type: "string";
|
|
20
|
+
readonly description: "解析后的项目根目录(POSIX)";
|
|
21
|
+
};
|
|
22
|
+
readonly bootstrap: {
|
|
23
|
+
readonly type: "object";
|
|
24
|
+
readonly description: "MCP Skill / AGENTS.md 自动安装结果";
|
|
25
|
+
readonly properties: {
|
|
26
|
+
readonly skillPath: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
};
|
|
29
|
+
readonly agentsMdPath: {
|
|
30
|
+
readonly type: "string";
|
|
31
|
+
};
|
|
32
|
+
readonly skillCreated: {
|
|
33
|
+
readonly type: "boolean";
|
|
34
|
+
};
|
|
35
|
+
readonly skillUpdated: {
|
|
36
|
+
readonly type: "boolean";
|
|
37
|
+
};
|
|
38
|
+
readonly agentsCreated: {
|
|
39
|
+
readonly type: "boolean";
|
|
40
|
+
};
|
|
41
|
+
readonly agentsUpdated: {
|
|
42
|
+
readonly type: "boolean";
|
|
43
|
+
};
|
|
44
|
+
readonly workspaceWarnings: {
|
|
45
|
+
readonly type: "array";
|
|
46
|
+
readonly items: {
|
|
47
|
+
readonly type: "string";
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
readonly rootSource: {
|
|
51
|
+
readonly type: "string";
|
|
52
|
+
};
|
|
53
|
+
readonly explicitHonored: {
|
|
54
|
+
readonly type: "boolean";
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
};
|
|
18
58
|
readonly structure: {
|
|
19
59
|
readonly type: "object";
|
|
20
60
|
readonly description: "项目结构";
|
|
@@ -404,6 +444,18 @@ export declare const ConflictResolutionSchema: {
|
|
|
404
444
|
export interface ProjectInit {
|
|
405
445
|
summary: string;
|
|
406
446
|
projectName: string;
|
|
447
|
+
projectRoot?: string;
|
|
448
|
+
bootstrap?: {
|
|
449
|
+
skillPath: string;
|
|
450
|
+
agentsMdPath: string;
|
|
451
|
+
skillCreated: boolean;
|
|
452
|
+
skillUpdated: boolean;
|
|
453
|
+
agentsCreated: boolean;
|
|
454
|
+
agentsUpdated: boolean;
|
|
455
|
+
workspaceWarnings: string[];
|
|
456
|
+
rootSource: string;
|
|
457
|
+
explicitHonored: boolean;
|
|
458
|
+
};
|
|
407
459
|
structure: {
|
|
408
460
|
directories?: string[];
|
|
409
461
|
files?: string[];
|
|
@@ -11,6 +11,22 @@ export const ProjectInitSchema = {
|
|
|
11
11
|
properties: {
|
|
12
12
|
summary: { type: 'string' },
|
|
13
13
|
projectName: { type: 'string' },
|
|
14
|
+
projectRoot: { type: 'string', description: '解析后的项目根目录(POSIX)' },
|
|
15
|
+
bootstrap: {
|
|
16
|
+
type: 'object',
|
|
17
|
+
description: 'MCP Skill / AGENTS.md 自动安装结果',
|
|
18
|
+
properties: {
|
|
19
|
+
skillPath: { type: 'string' },
|
|
20
|
+
agentsMdPath: { type: 'string' },
|
|
21
|
+
skillCreated: { type: 'boolean' },
|
|
22
|
+
skillUpdated: { type: 'boolean' },
|
|
23
|
+
agentsCreated: { type: 'boolean' },
|
|
24
|
+
agentsUpdated: { type: 'boolean' },
|
|
25
|
+
workspaceWarnings: { type: 'array', items: { type: 'string' } },
|
|
26
|
+
rootSource: { type: 'string' },
|
|
27
|
+
explicitHonored: { type: 'boolean' },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
14
30
|
structure: {
|
|
15
31
|
type: 'object',
|
|
16
32
|
description: '项目结构',
|
|
@@ -124,7 +124,7 @@ export declare const projectToolSchemas: readonly [{
|
|
|
124
124
|
};
|
|
125
125
|
readonly project_root: {
|
|
126
126
|
readonly type: "string";
|
|
127
|
-
readonly description: "
|
|
127
|
+
readonly description: "可选。项目根目录绝对路径;未传时自动从 MCP 客户端工作区解析(如 Cursor 注入 WORKSPACE_FOLDER_PATHS、OpenCode/客户端配置的 cwd 等)。仅边缘场景需手动传入。";
|
|
128
128
|
};
|
|
129
129
|
};
|
|
130
130
|
readonly required: readonly [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 项目管理工具的 Schema 定义
|
|
3
3
|
*/
|
|
4
|
+
import { PROJECT_ROOT_SCHEMA_DESCRIPTION } from "../lib/workspace-root.js";
|
|
4
5
|
export const projectToolSchemas = [
|
|
5
6
|
{
|
|
6
7
|
name: "workflow",
|
|
@@ -129,7 +130,7 @@ export const projectToolSchemas = [
|
|
|
129
130
|
},
|
|
130
131
|
project_root: {
|
|
131
132
|
type: "string",
|
|
132
|
-
description:
|
|
133
|
+
description: PROJECT_ROOT_SCHEMA_DESCRIPTION,
|
|
133
134
|
},
|
|
134
135
|
},
|
|
135
136
|
required: [],
|
|
@@ -2,7 +2,8 @@ import { parseArgs, getString } from "../utils/parseArgs.js";
|
|
|
2
2
|
import { okStructured } from "../lib/response.js";
|
|
3
3
|
import { ensureMcpProbeKitBootstrap } from "../lib/workflow-skill-installer.js";
|
|
4
4
|
import { MCP_PROBE_SKILL_REL_PATH } from "../lib/workflow-skill-template.js";
|
|
5
|
-
import {
|
|
5
|
+
import { resolveWorkspaceRootWithMeta } from "../lib/workspace-root.js";
|
|
6
|
+
import { toPosixPath } from "../lib/project-context-layout.js";
|
|
6
7
|
/**
|
|
7
8
|
* init_project 工具
|
|
8
9
|
*
|
|
@@ -22,31 +23,45 @@ export async function initProject(args) {
|
|
|
22
23
|
fieldAliases: {
|
|
23
24
|
input: ["requirement", "description", "需求", "项目需求"],
|
|
24
25
|
project_name: ["name", "project", "项目名", "项目名称"],
|
|
25
|
-
project_root: ["root", "path", "项目路径"],
|
|
26
|
+
project_root: ["root", "path", "项目路径", "projectRoot", "projectPath", "workspace"],
|
|
26
27
|
},
|
|
27
28
|
});
|
|
28
29
|
const input = getString(parsedArgs.input);
|
|
29
30
|
const projectName = getString(parsedArgs.project_name) || "新项目";
|
|
30
|
-
const
|
|
31
|
+
const rootResolution = resolveWorkspaceRootWithMeta(getString(parsedArgs.project_root));
|
|
32
|
+
const projectRoot = rootResolution.root;
|
|
31
33
|
const bootstrap = ensureMcpProbeKitBootstrap(projectRoot);
|
|
34
|
+
const pathWarnings = [rootResolution.warning, bootstrap.workspaceWarning].filter((item) => Boolean(item));
|
|
35
|
+
const warningBlock = pathWarnings.length
|
|
36
|
+
? `\n⚠️ **路径 / 工作区**\n${pathWarnings.map((w) => `- ${w}`).join("\n")}\n`
|
|
37
|
+
: "";
|
|
32
38
|
const featureSlug = projectName.toLowerCase().replace(/\s+/g, '-');
|
|
39
|
+
const agentsRel = toPosixPath(bootstrap.agentsMd.path);
|
|
33
40
|
const message = `你需要按照 Spec-Driven Development(规范驱动开发)的方式初始化项目,参考 https://github.com/github/spec-kit 的工作流程。
|
|
34
41
|
|
|
35
42
|
📋 **项目需求**:
|
|
36
43
|
${input}
|
|
37
|
-
|
|
38
|
-
📌 **MCP
|
|
44
|
+
${warningBlock}
|
|
45
|
+
📌 **MCP 已自动同步(必须先落盘)**(项目根: \`${toPosixPath(projectRoot)}\`):
|
|
39
46
|
- \`${MCP_PROBE_SKILL_REL_PATH}\`${bootstrap.skill.created ? "(已创建)" : bootstrap.skill.updated ? "(已升级)" : "(已是最新)"}
|
|
40
|
-
- \`${
|
|
41
|
-
${bootstrap.workspaceWarning ? `\n⚠️ ${bootstrap.workspaceWarning}\n` : ""}
|
|
47
|
+
- \`${agentsRel}\`${bootstrap.agentsMd.created ? "(已创建)" : bootstrap.agentsMd.updated ? "(已更新)" : ""}
|
|
42
48
|
|
|
43
49
|
🎯 **初始化步骤**:
|
|
44
50
|
|
|
51
|
+
**第零步:确认 MCP 产物(已完成服务端写入,Agent 勿跳过)**
|
|
52
|
+
- Skill 与 AGENTS.md 已由 mcp-probe-kit 写入上述路径
|
|
53
|
+
- 若未看到文件,确认已从目标项目目录打开 MCP 客户端,或在工具参数中传 \`project_root\` 绝对路径
|
|
54
|
+
|
|
45
55
|
**第一步:创建项目基础结构**
|
|
46
56
|
在当前工作区创建以下目录和文件:
|
|
47
57
|
|
|
48
58
|
\`\`\`
|
|
49
59
|
.
|
|
60
|
+
├── .agents/
|
|
61
|
+
│ └── skills/
|
|
62
|
+
│ └── mcp-probe-kit/
|
|
63
|
+
│ └── SKILL.md # MCP 调用时机(已自动创建)
|
|
64
|
+
├── AGENTS.md # Agent 规则(已自动创建/更新)
|
|
50
65
|
├── docs/
|
|
51
66
|
│ ├── project-context.md # 项目上下文(技术栈、架构、规范)
|
|
52
67
|
│ ├── constitution.md # 项目宪法(核心原则和约束)
|
|
@@ -198,8 +213,21 @@ ${bootstrap.workspaceWarning ? `\n⚠️ ${bootstrap.workspaceWarning}\n` : ""}
|
|
|
198
213
|
const structuredData = {
|
|
199
214
|
summary: `初始化项目:${projectName}`,
|
|
200
215
|
projectName: projectName,
|
|
216
|
+
projectRoot: toPosixPath(projectRoot),
|
|
217
|
+
bootstrap: {
|
|
218
|
+
skillPath: MCP_PROBE_SKILL_REL_PATH,
|
|
219
|
+
agentsMdPath: agentsRel,
|
|
220
|
+
skillCreated: bootstrap.skill.created,
|
|
221
|
+
skillUpdated: bootstrap.skill.updated,
|
|
222
|
+
agentsCreated: bootstrap.agentsMd.created,
|
|
223
|
+
agentsUpdated: bootstrap.agentsMd.updated,
|
|
224
|
+
workspaceWarnings: pathWarnings,
|
|
225
|
+
rootSource: rootResolution.source,
|
|
226
|
+
explicitHonored: rootResolution.explicitHonored,
|
|
227
|
+
},
|
|
201
228
|
structure: {
|
|
202
229
|
directories: [
|
|
230
|
+
'.agents/skills/mcp-probe-kit/',
|
|
203
231
|
'docs/',
|
|
204
232
|
'docs/specs/',
|
|
205
233
|
`docs/specs/${featureSlug}/`,
|
|
@@ -207,6 +235,8 @@ ${bootstrap.workspaceWarning ? `\n⚠️ ${bootstrap.workspaceWarning}\n` : ""}
|
|
|
207
235
|
'src/'
|
|
208
236
|
],
|
|
209
237
|
files: [
|
|
238
|
+
MCP_PROBE_SKILL_REL_PATH,
|
|
239
|
+
agentsRel,
|
|
210
240
|
'docs/project-context.md',
|
|
211
241
|
'docs/constitution.md',
|
|
212
242
|
`docs/specs/${featureSlug}/requirements.md`,
|
|
@@ -218,6 +248,7 @@ ${bootstrap.workspaceWarning ? `\n⚠️ ${bootstrap.workspaceWarning}\n` : ""}
|
|
|
218
248
|
]
|
|
219
249
|
},
|
|
220
250
|
nextSteps: [
|
|
251
|
+
'确认 .agents/skills/mcp-probe-kit/SKILL.md 与 AGENTS.md 已落盘',
|
|
221
252
|
'创建项目目录结构',
|
|
222
253
|
'生成 project-context.md',
|
|
223
254
|
'生成 constitution.md',
|
|
@@ -306,7 +306,7 @@ export async function scanAndExtractPatterns(args) {
|
|
|
306
306
|
const { resolvedPath: targetDir, attemptedRoots } = resolveTargetDirectory(projectRoot, directoryPath);
|
|
307
307
|
if (!fs.existsSync(targetDir) || !fs.statSync(targetDir).isDirectory()) {
|
|
308
308
|
const attempted = attemptedRoots.map((root) => path.resolve(root, directoryPath).replace(/\\/g, '/'));
|
|
309
|
-
return okStructured(`目录不存在或不可访问: ${targetDir.replace(/\\/g, '/')}。相对路径解析依赖工作区根目录;请显式传入 project_root
|
|
309
|
+
return okStructured(`目录不存在或不可访问: ${targetDir.replace(/\\/g, '/')}。相对路径解析依赖工作区根目录;请显式传入 project_root,或从目标项目目录打开 MCP 客户端以自动识别工作区。`, {
|
|
310
310
|
mode: 'directory',
|
|
311
311
|
scannedFiles: 0,
|
|
312
312
|
patterns: [],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-probe-kit",
|
|
3
|
-
"version": "3.6.
|
|
3
|
+
"version": "3.6.3",
|
|
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",
|