mcp-probe-kit 3.6.5 → 3.6.8
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 +3 -1
- package/build/index.js +1 -0
- package/build/lib/__tests__/agents-md-template.unit.test.js +2 -0
- package/build/lib/__tests__/agents-skill-ref.unit.test.d.ts +1 -0
- package/build/lib/__tests__/agents-skill-ref.unit.test.js +32 -0
- package/build/lib/__tests__/harness-adapters.unit.test.d.ts +1 -0
- package/build/lib/__tests__/harness-adapters.unit.test.js +68 -0
- package/build/lib/__tests__/harness-skill-targets.unit.test.d.ts +1 -0
- package/build/lib/__tests__/harness-skill-targets.unit.test.js +59 -0
- package/build/lib/__tests__/project-mcp-resources.unit.test.js +1 -1
- package/build/lib/__tests__/workflow-skill-frontmatter.unit.test.d.ts +1 -0
- package/build/lib/__tests__/workflow-skill-frontmatter.unit.test.js +31 -0
- package/build/lib/__tests__/workflow-skill-installer.unit.test.js +21 -6
- package/build/lib/agents-md-template.d.ts +1 -0
- package/build/lib/agents-md-template.js +21 -6
- package/build/lib/agents-skill-ref.d.ts +6 -0
- package/build/lib/agents-skill-ref.js +45 -0
- package/build/lib/harness-adapters.d.ts +19 -0
- package/build/lib/harness-adapters.js +166 -0
- package/build/lib/harness-skill-targets.d.ts +38 -0
- package/build/lib/harness-skill-targets.js +95 -0
- package/build/lib/project-context-layout.d.ts +15 -2
- package/build/lib/project-context-layout.js +27 -3
- package/build/lib/workflow-skill-installer.d.ts +2 -0
- package/build/lib/workflow-skill-installer.js +19 -5
- package/build/lib/workflow-skill-template.d.ts +3 -0
- package/build/lib/workflow-skill-template.js +12 -5
- package/build/lib/workflow-skill-version.d.ts +7 -1
- package/build/lib/workflow-skill-version.js +45 -2
- package/build/tools/init_project_context.js +17 -2
- package/package.json +84 -84
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Canonical Skill path — never changes per harness */
|
|
2
|
+
export declare const CANONICAL_SKILL_REL_PATH = ".agents/skills/mcp-probe-kit/SKILL.md";
|
|
3
|
+
export type HarnessId = "agents" | "cursor" | "claude" | "codex" | "opencode" | "trae" | "traecli" | "codebuddy" | "lingma" | "comate";
|
|
4
|
+
export type HarnessAdapterKind = "skill-mirror" | "rules-pointer" | "claude-pointer";
|
|
5
|
+
export interface HarnessAdapterTarget {
|
|
6
|
+
id: string;
|
|
7
|
+
harnessId: HarnessId;
|
|
8
|
+
relPath: string;
|
|
9
|
+
kind: HarnessAdapterKind;
|
|
10
|
+
/** 项目内已有该目录时才写适配层(零配置) */
|
|
11
|
+
markerDir: string;
|
|
12
|
+
}
|
|
13
|
+
export interface HarnessDetectionResult {
|
|
14
|
+
markerHarnesses: HarnessId[];
|
|
15
|
+
detected: HarnessId[];
|
|
16
|
+
skillCanonical: string;
|
|
17
|
+
adaptersToWrite: HarnessAdapterTarget[];
|
|
18
|
+
}
|
|
19
|
+
export declare const HARNESS_ADAPTER_TARGETS: HarnessAdapterTarget[];
|
|
20
|
+
/**
|
|
21
|
+
* 零配置 harness 检测:项目里已有工具目录(如 `.trae/`)则写对应薄适配。
|
|
22
|
+
* AGENTS.md 与 canonical Skill 路径始终不变。
|
|
23
|
+
*/
|
|
24
|
+
export declare function detectHarnessContext(projectRoot: string): HarnessDetectionResult;
|
|
25
|
+
export interface LayoutHarnessManifest {
|
|
26
|
+
detected: HarnessId[];
|
|
27
|
+
skillCanonical: string;
|
|
28
|
+
adapters: Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
kind: HarnessAdapterKind;
|
|
31
|
+
path: string;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export declare function toLayoutHarnessManifest(detection: HarnessDetectionResult, writtenAdapters: Array<{
|
|
35
|
+
id: string;
|
|
36
|
+
kind: HarnessAdapterKind;
|
|
37
|
+
path: string;
|
|
38
|
+
}>): LayoutHarnessManifest;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { MCP_PROBE_SKILL_REL_PATH } from "./workflow-skill-template.js";
|
|
4
|
+
/** Canonical Skill path — never changes per harness */
|
|
5
|
+
export const CANONICAL_SKILL_REL_PATH = MCP_PROBE_SKILL_REL_PATH;
|
|
6
|
+
export const HARNESS_ADAPTER_TARGETS = [
|
|
7
|
+
{
|
|
8
|
+
id: "trae-skill",
|
|
9
|
+
harnessId: "trae",
|
|
10
|
+
relPath: ".trae/skills/mcp-probe-kit/SKILL.md",
|
|
11
|
+
kind: "skill-mirror",
|
|
12
|
+
markerDir: ".trae",
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: "traecli-skill",
|
|
16
|
+
harnessId: "traecli",
|
|
17
|
+
relPath: ".traecli/skills/mcp-probe-kit/SKILL.md",
|
|
18
|
+
kind: "skill-mirror",
|
|
19
|
+
markerDir: ".traecli",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: "codebuddy-skill",
|
|
23
|
+
harnessId: "codebuddy",
|
|
24
|
+
relPath: ".codebuddy/skills/mcp-probe-kit/SKILL.md",
|
|
25
|
+
kind: "skill-mirror",
|
|
26
|
+
markerDir: ".codebuddy",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "lingma-rules",
|
|
30
|
+
harnessId: "lingma",
|
|
31
|
+
relPath: ".lingma/rules/mcp-probe-kit-mcp.md",
|
|
32
|
+
kind: "rules-pointer",
|
|
33
|
+
markerDir: ".lingma",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "comate-rules",
|
|
37
|
+
harnessId: "comate",
|
|
38
|
+
relPath: ".comate/rules/mcp-probe-kit-mcp.mdr",
|
|
39
|
+
kind: "rules-pointer",
|
|
40
|
+
markerDir: ".comate",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "claude-pointer",
|
|
44
|
+
harnessId: "claude",
|
|
45
|
+
relPath: "CLAUDE.md",
|
|
46
|
+
kind: "claude-pointer",
|
|
47
|
+
markerDir: ".claude",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
const MARKER_DIR_TO_HARNESS = {
|
|
51
|
+
".trae": "trae",
|
|
52
|
+
".traecli": "traecli",
|
|
53
|
+
".codebuddy": "codebuddy",
|
|
54
|
+
".lingma": "lingma",
|
|
55
|
+
".comate": "comate",
|
|
56
|
+
".cursor": "cursor",
|
|
57
|
+
".claude": "claude",
|
|
58
|
+
".codex": "codex",
|
|
59
|
+
".opencode": "opencode",
|
|
60
|
+
};
|
|
61
|
+
function detectMarkerHarnesses(projectRoot) {
|
|
62
|
+
const found = [];
|
|
63
|
+
for (const [markerDir, harnessId] of Object.entries(MARKER_DIR_TO_HARNESS)) {
|
|
64
|
+
if (fs.existsSync(path.join(projectRoot, markerDir))) {
|
|
65
|
+
found.push(harnessId);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return found;
|
|
69
|
+
}
|
|
70
|
+
function shouldWriteAdapter(projectRoot, adapter) {
|
|
71
|
+
return fs.existsSync(path.join(projectRoot, adapter.markerDir));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 零配置 harness 检测:项目里已有工具目录(如 `.trae/`)则写对应薄适配。
|
|
75
|
+
* AGENTS.md 与 canonical Skill 路径始终不变。
|
|
76
|
+
*/
|
|
77
|
+
export function detectHarnessContext(projectRoot) {
|
|
78
|
+
const root = path.resolve(projectRoot);
|
|
79
|
+
const markerHarnesses = detectMarkerHarnesses(root);
|
|
80
|
+
const detected = markerHarnesses.length > 0 ? markerHarnesses : ["agents"];
|
|
81
|
+
const adaptersToWrite = HARNESS_ADAPTER_TARGETS.filter((adapter) => shouldWriteAdapter(root, adapter));
|
|
82
|
+
return {
|
|
83
|
+
markerHarnesses,
|
|
84
|
+
detected,
|
|
85
|
+
skillCanonical: CANONICAL_SKILL_REL_PATH,
|
|
86
|
+
adaptersToWrite,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function toLayoutHarnessManifest(detection, writtenAdapters) {
|
|
90
|
+
return {
|
|
91
|
+
detected: detection.detected,
|
|
92
|
+
skillCanonical: detection.skillCanonical,
|
|
93
|
+
adapters: writtenAdapters,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -32,6 +32,15 @@ export interface ProjectContextLayoutArgs {
|
|
|
32
32
|
}
|
|
33
33
|
/** Primary env key recorded in layout.json (optional local override via projectRoot) */
|
|
34
34
|
export declare const LAYOUT_PROJECT_ROOT_ENV = "MCP_PROJECT_ROOT";
|
|
35
|
+
export interface LayoutManifestHarnessV1 {
|
|
36
|
+
detected: string[];
|
|
37
|
+
skillCanonical: string;
|
|
38
|
+
adapters: Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
kind: string;
|
|
41
|
+
path: string;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
35
44
|
export interface LayoutManifestV1 {
|
|
36
45
|
version: 1;
|
|
37
46
|
/** Ignored if present in old files — project root is always inferred from manifest path */
|
|
@@ -45,6 +54,8 @@ export interface LayoutManifestV1 {
|
|
|
45
54
|
indexStyle: "agents" | "legacy";
|
|
46
55
|
generatedBy: string;
|
|
47
56
|
generatedAt: string;
|
|
57
|
+
/** Harness detection snapshot (AGENTS.md + canonical Skill stay harness-agnostic) */
|
|
58
|
+
harness?: LayoutManifestHarnessV1;
|
|
48
59
|
}
|
|
49
60
|
export declare function toPosixPath(value: string): string;
|
|
50
61
|
export declare function relativeLink(fromRel: string, toRel: string): string;
|
|
@@ -66,8 +77,10 @@ export declare function manifestPathRelativeToProject(projectRoot: string, absol
|
|
|
66
77
|
export declare function layoutAbsPath(layout: ProjectContextLayout, relativePath: string): string;
|
|
67
78
|
type ProjectContextLayoutCore = Omit<ProjectContextLayout, "projectRoot" | "projectRootPosix">;
|
|
68
79
|
export declare function attachProjectRoot(layout: ProjectContextLayoutCore, projectRoot: string): ProjectContextLayout;
|
|
69
|
-
export declare function buildLayoutManifest(layout: ProjectContextLayout): LayoutManifestV1;
|
|
70
|
-
export declare function writeLayoutManifest(projectRoot: string, layout: ProjectContextLayout): string;
|
|
80
|
+
export declare function buildLayoutManifest(layout: ProjectContextLayout, harness?: LayoutManifestHarnessV1): LayoutManifestV1;
|
|
81
|
+
export declare function writeLayoutManifest(projectRoot: string, layout: ProjectContextLayout, harness?: LayoutManifestHarnessV1): string;
|
|
82
|
+
/** Patch harness section on an existing layout.json (e.g. after bootstrap adapters). */
|
|
83
|
+
export declare function patchLayoutManifestHarness(projectRoot: string, harness: LayoutManifestHarnessV1): string | null;
|
|
71
84
|
export declare function layoutFromManifest(manifest: LayoutManifestV1, fallbackProjectRoot: string, manifestFilePath?: string): ProjectContextLayout;
|
|
72
85
|
export declare function resolveProjectContextLayout(projectRoot: string, args?: ProjectContextLayoutArgs): ProjectContextLayout;
|
|
73
86
|
export declare function countCjkChars(text: string): number;
|
|
@@ -196,7 +196,7 @@ export function attachProjectRoot(layout, projectRoot) {
|
|
|
196
196
|
projectRootPosix: projectRootToManifestValue(resolved),
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
|
-
export function buildLayoutManifest(layout) {
|
|
199
|
+
export function buildLayoutManifest(layout, harness) {
|
|
200
200
|
return {
|
|
201
201
|
version: 1,
|
|
202
202
|
projectRootEnv: LAYOUT_PROJECT_ROOT_ENV,
|
|
@@ -207,17 +207,41 @@ export function buildLayoutManifest(layout) {
|
|
|
207
207
|
indexStyle: layout.indexStyle,
|
|
208
208
|
generatedBy: "init_project_context",
|
|
209
209
|
generatedAt: new Date().toISOString(),
|
|
210
|
+
...(harness ? { harness } : {}),
|
|
210
211
|
};
|
|
211
212
|
}
|
|
212
|
-
export function writeLayoutManifest(projectRoot, layout) {
|
|
213
|
+
export function writeLayoutManifest(projectRoot, layout, harness) {
|
|
213
214
|
const resolvedRoot = path.resolve(projectRoot);
|
|
214
215
|
const manifestRel = layoutManifestRel(layout.contextRoot);
|
|
215
|
-
const manifest = buildLayoutManifest(attachProjectRoot(layout, resolvedRoot));
|
|
216
|
+
const manifest = buildLayoutManifest(attachProjectRoot(layout, resolvedRoot), harness);
|
|
216
217
|
const absoluteManifest = path.join(resolvedRoot, ...manifestRel.split("/"));
|
|
217
218
|
fs.mkdirSync(path.dirname(absoluteManifest), { recursive: true });
|
|
218
219
|
fs.writeFileSync(absoluteManifest, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
219
220
|
return manifestRel;
|
|
220
221
|
}
|
|
222
|
+
function layoutHarnessEquals(left, right) {
|
|
223
|
+
return JSON.stringify(left ?? null) === JSON.stringify(right);
|
|
224
|
+
}
|
|
225
|
+
/** Patch harness section on an existing layout.json (e.g. after bootstrap adapters). */
|
|
226
|
+
export function patchLayoutManifestHarness(projectRoot, harness) {
|
|
227
|
+
const resolvedRoot = path.resolve(projectRoot);
|
|
228
|
+
const existing = readLayoutManifest(resolvedRoot);
|
|
229
|
+
if (!existing) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
if (layoutHarnessEquals(existing.harness, harness)) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
const layout = layoutFromManifest(existing, resolvedRoot);
|
|
236
|
+
const manifestRel = layout.manifestPath;
|
|
237
|
+
const absoluteManifest = path.join(resolvedRoot, ...manifestRel.split("/"));
|
|
238
|
+
const updated = {
|
|
239
|
+
...existing,
|
|
240
|
+
harness,
|
|
241
|
+
};
|
|
242
|
+
fs.writeFileSync(absoluteManifest, `${JSON.stringify(updated, null, 2)}\n`, "utf8");
|
|
243
|
+
return manifestRel;
|
|
244
|
+
}
|
|
221
245
|
export function layoutFromManifest(manifest, fallbackProjectRoot, manifestFilePath) {
|
|
222
246
|
const contextRoot = normalizeRelativePath(manifest.contextRoot);
|
|
223
247
|
const projectRoot = resolveManifestProjectRoot(manifest, fallbackProjectRoot, manifestFilePath);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type HarnessAdapterEnsureResult } from "./harness-adapters.js";
|
|
1
2
|
export interface SkillEnsureResult {
|
|
2
3
|
skillPath: string;
|
|
3
4
|
skillRelPath: string;
|
|
@@ -17,6 +18,7 @@ export interface McpProbeKitBootstrapResult {
|
|
|
17
18
|
projectRoot: string;
|
|
18
19
|
skill: SkillEnsureResult;
|
|
19
20
|
agentsMd: AgentsMdEnsureResult;
|
|
21
|
+
harness?: HarnessAdapterEnsureResult;
|
|
20
22
|
/** 工作区可能解析失败(写到了 mcp-probe-kit 安装目录) */
|
|
21
23
|
workspaceWarning?: string;
|
|
22
24
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
import { agentsSkillReferenceSatisfied, resolveAgentsSkillRefMode, } from "./agents-skill-ref.js";
|
|
3
4
|
import { generateAgentsMdInner } from "./agents-md-template.js";
|
|
4
5
|
import { mergeAgentsMdBlock } from "./merge-agents-md.js";
|
|
5
|
-
import { detectDocumentLocale, resolveProjectContextLayout, toPosixPath, } from "./project-context-layout.js";
|
|
6
6
|
import { generateWorkflowSkillContent, LEGACY_WORKFLOW_SKILL_REL_PATH, MCP_PROBE_SKILL_REL_PATH, } from "./workflow-skill-template.js";
|
|
7
|
-
import { agentsContextNeedsUpgrade, getMcpProbeSkillVersion,
|
|
7
|
+
import { agentsContextNeedsUpgrade, getMcpProbeSkillVersion, parseSkillInstalledVersion, skillContentNeedsUpgrade, } from "./workflow-skill-version.js";
|
|
8
|
+
import { ensureHarnessAdapters } from "./harness-adapters.js";
|
|
9
|
+
import { detectDocumentLocale, patchLayoutManifestHarness, resolveProjectContextLayout, toPosixPath, } from "./project-context-layout.js";
|
|
8
10
|
import { isLikelyProjectNamedRelativePath, getMcpPackageInstallRoot, resolveWorkspaceRoot, } from "./workspace-root.js";
|
|
9
11
|
function buildWorkspaceWarning(projectRoot) {
|
|
10
12
|
const normalizedRoot = path.resolve(projectRoot);
|
|
@@ -42,6 +44,7 @@ function buildAgentsMdInner(projectRoot, existingAgentsContent) {
|
|
|
42
44
|
const layout = resolveProjectContextLayout(projectRoot);
|
|
43
45
|
const locale = detectDocumentLocale(projectRoot, existingAgentsContent);
|
|
44
46
|
const graphReady = fs.existsSync(path.join(projectRoot, layout.latestMarkdownPath));
|
|
47
|
+
const contextReady = fs.existsSync(path.join(projectRoot, layout.legacyIndexPath));
|
|
45
48
|
return generateAgentsMdInner({
|
|
46
49
|
layout,
|
|
47
50
|
locale,
|
|
@@ -53,6 +56,7 @@ function buildAgentsMdInner(projectRoot, existingAgentsContent) {
|
|
|
53
56
|
docs: [],
|
|
54
57
|
projectRootPosix: toPosixPath(projectRoot),
|
|
55
58
|
graphReady,
|
|
59
|
+
contextReady,
|
|
56
60
|
});
|
|
57
61
|
}
|
|
58
62
|
function agentsMdNeedsUpdate(content, skillRelPath, targetVersion) {
|
|
@@ -68,6 +72,9 @@ function agentsMdNeedsUpdate(content, skillRelPath, targetVersion) {
|
|
|
68
72
|
if (!content.includes(skillRelPath)) {
|
|
69
73
|
return true;
|
|
70
74
|
}
|
|
75
|
+
if (!agentsSkillReferenceSatisfied(content, resolveAgentsSkillRefMode())) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
71
78
|
if (agentsContextNeedsUpgrade(content, targetVersion)) {
|
|
72
79
|
return true;
|
|
73
80
|
}
|
|
@@ -85,7 +92,7 @@ export function ensureMcpProbeSkill(projectRoot) {
|
|
|
85
92
|
const skillPath = path.join(root, MCP_PROBE_SKILL_REL_PATH);
|
|
86
93
|
const targetVersion = getMcpProbeSkillVersion();
|
|
87
94
|
const existing = fs.existsSync(skillPath) ? fs.readFileSync(skillPath, "utf8") : null;
|
|
88
|
-
const previousVersion = existing ?
|
|
95
|
+
const previousVersion = existing ? parseSkillInstalledVersion(existing) : null;
|
|
89
96
|
if (!skillContentNeedsUpgrade(existing, targetVersion)) {
|
|
90
97
|
return {
|
|
91
98
|
skillPath,
|
|
@@ -144,10 +151,17 @@ export function ensureAgentsMdSkillReference(projectRoot) {
|
|
|
144
151
|
export function ensureMcpProbeKitBootstrap(projectRoot) {
|
|
145
152
|
const root = path.resolve(projectRoot);
|
|
146
153
|
const workspaceWarning = buildWorkspaceWarning(root);
|
|
154
|
+
const skill = ensureMcpProbeSkill(root);
|
|
155
|
+
const agentsMd = ensureAgentsMdSkillReference(root);
|
|
156
|
+
const skillContent = fs.readFileSync(skill.skillPath, "utf8");
|
|
157
|
+
const layout = resolveProjectContextLayout(root);
|
|
158
|
+
const harness = ensureHarnessAdapters(root, skillContent, layout.indexPath);
|
|
159
|
+
patchLayoutManifestHarness(root, harness.layoutHarness);
|
|
147
160
|
return {
|
|
148
161
|
projectRoot: root,
|
|
149
|
-
skill
|
|
150
|
-
agentsMd
|
|
162
|
+
skill,
|
|
163
|
+
agentsMd,
|
|
164
|
+
harness,
|
|
151
165
|
workspaceWarning,
|
|
152
166
|
};
|
|
153
167
|
}
|
|
@@ -6,4 +6,7 @@ export declare const MCP_PROBE_SKILL_REL_PATH = ".agents/skills/mcp-probe-kit/SK
|
|
|
6
6
|
/** @deprecated 旧路径,仅用于检测并升级 AGENTS.md 引用 */
|
|
7
7
|
export declare const LEGACY_WORKFLOW_SKILL_REL_PATH = ".agents/skills/workflow/SKILL.md";
|
|
8
8
|
export declare function generateWorkflowSkillBody(skillVersion?: string): string;
|
|
9
|
+
export declare const MCP_PROBE_SKILL_NAME = "mcp-probe-kit";
|
|
10
|
+
export declare const MCP_PROBE_SKILL_DESCRIPTION = "\u5C06\u7528\u6237\u610F\u56FE\u8DEF\u7531\u5230 mcp-probe-kit MCP \u5DE5\u5177\uFF08start_feature\u3001start_bugfix\u3001code_insight\u3001workflow\u3001gencommit \u7B49\uFF09\u3002\u5728\u5DF2\u914D\u7F6E MCP \u4E14\u51C6\u5907\u5199\u4EE3\u7801\u524D\u8BFB\u53D6\uFF1B\u4EC5\u8BF4\u660E\u8C03\u54EA\u4E2A MCP\uFF0C\u4E0D\u662F\u9879\u76EE\u7814\u53D1\u6D41\u7A0B\u672C\u8EAB\u3002Routes intent to mcp-probe-kit MCP tools; read before coding when MCP is configured.";
|
|
11
|
+
export declare function formatSkillFrontmatter(skillVersion?: string): string;
|
|
9
12
|
export declare function generateWorkflowSkillContent(skillVersion?: string): string;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { VERSION } from "../version.js";
|
|
6
6
|
import { MCP_INTENT_QUICK_LOOKUP, MCP_SKILL_AVOID_RULES, MCP_SKILL_COMMON_FLOWS, MCP_TOOL_SKILL_GROUPS, } from "./mcp-tool-skill-registry.js";
|
|
7
|
-
import {
|
|
7
|
+
import { SKILL_VERSION_FRONTMATTER_KEY } from "./workflow-skill-version.js";
|
|
8
8
|
export const MCP_PROBE_SKILL_REL_PATH = ".agents/skills/mcp-probe-kit/SKILL.md";
|
|
9
9
|
/** @deprecated 旧路径,仅用于检测并升级 AGENTS.md 引用 */
|
|
10
10
|
export const LEGACY_WORKFLOW_SKILL_REL_PATH = ".agents/skills/workflow/SKILL.md";
|
|
@@ -74,12 +74,19 @@ ${renderAvoidRules()}
|
|
|
74
74
|
*mcp-probe-kit 按版本自动同步(当前 \`${skillVersion}\`)。路径:\`${MCP_PROBE_SKILL_REL_PATH}\`*
|
|
75
75
|
`;
|
|
76
76
|
}
|
|
77
|
+
export const MCP_PROBE_SKILL_NAME = "mcp-probe-kit";
|
|
78
|
+
export const MCP_PROBE_SKILL_DESCRIPTION = `将用户意图路由到 mcp-probe-kit MCP 工具(start_feature、start_bugfix、code_insight、workflow、gencommit 等)。在已配置 MCP 且准备写代码前读取;仅说明调哪个 MCP,不是项目研发流程本身。Routes intent to mcp-probe-kit MCP tools; read before coding when MCP is configured.`;
|
|
79
|
+
export function formatSkillFrontmatter(skillVersion = VERSION) {
|
|
80
|
+
return `---
|
|
81
|
+
name: ${MCP_PROBE_SKILL_NAME}
|
|
82
|
+
description: >-
|
|
83
|
+
${MCP_PROBE_SKILL_DESCRIPTION}
|
|
84
|
+
${SKILL_VERSION_FRONTMATTER_KEY}: "${skillVersion}"
|
|
85
|
+
---`;
|
|
86
|
+
}
|
|
77
87
|
export function generateWorkflowSkillContent(skillVersion = VERSION) {
|
|
78
|
-
|
|
79
|
-
return `${versionMarker}
|
|
88
|
+
return `${formatSkillFrontmatter(skillVersion)}
|
|
80
89
|
|
|
81
90
|
${generateWorkflowSkillBody(skillVersion)}
|
|
82
|
-
|
|
83
|
-
${versionMarker}
|
|
84
91
|
`;
|
|
85
92
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
/** Skill
|
|
1
|
+
/** Skill frontmatter 版本字段 */
|
|
2
|
+
export declare const SKILL_VERSION_FRONTMATTER_KEY = "mcp-probe-kit-version";
|
|
3
|
+
/** @deprecated 旧版 HTML 版本标记,仍用于解析历史文件 */
|
|
2
4
|
export declare const SKILL_VERSION_MARKER = "mcp-probe-kit-skill-version";
|
|
3
5
|
/** AGENTS.md mcp-probe 块内版本标记 */
|
|
4
6
|
export declare const AGENTS_CONTEXT_VERSION_MARKER = "mcp-probe:context-version";
|
|
@@ -6,6 +8,10 @@ export declare function getMcpProbeSkillVersion(): string;
|
|
|
6
8
|
export declare function formatSkillVersionMarker(version?: string): string;
|
|
7
9
|
export declare function formatAgentsContextVersionMarker(version?: string): string;
|
|
8
10
|
export declare function parseSkillVersionMarker(content: string): string | null;
|
|
11
|
+
/** 从 Skill 正文解析已安装版本(frontmatter 优先,HTML 注释兜底) */
|
|
12
|
+
export declare function parseSkillInstalledVersion(content: string): string | null;
|
|
13
|
+
/** 是否缺少 Agent Skill 发现所需的 YAML frontmatter */
|
|
14
|
+
export declare function skillFrontmatterNeedsUpgrade(content: string): boolean;
|
|
9
15
|
export declare function parseAgentsContextVersion(content: string): string | null;
|
|
10
16
|
/** 比较 semver(仅主版本号段,忽略 prerelease 后缀) */
|
|
11
17
|
export declare function compareSemver(a: string, b: string): number;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { VERSION } from "../version.js";
|
|
2
|
-
/** Skill
|
|
2
|
+
/** Skill frontmatter 版本字段 */
|
|
3
|
+
export const SKILL_VERSION_FRONTMATTER_KEY = "mcp-probe-kit-version";
|
|
4
|
+
/** @deprecated 旧版 HTML 版本标记,仍用于解析历史文件 */
|
|
3
5
|
export const SKILL_VERSION_MARKER = "mcp-probe-kit-skill-version";
|
|
4
6
|
/** AGENTS.md mcp-probe 块内版本标记 */
|
|
5
7
|
export const AGENTS_CONTEXT_VERSION_MARKER = "mcp-probe:context-version";
|
|
@@ -17,6 +19,44 @@ export function parseSkillVersionMarker(content) {
|
|
|
17
19
|
const match = content.match(pattern);
|
|
18
20
|
return match?.[1]?.trim() ?? null;
|
|
19
21
|
}
|
|
22
|
+
function parseSkillVersionFromFrontmatter(content) {
|
|
23
|
+
if (!content.trimStart().startsWith("---")) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const end = content.indexOf("\n---", 3);
|
|
27
|
+
if (end === -1) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const header = content.slice(0, end + 4);
|
|
31
|
+
const pattern = new RegExp(`^${SKILL_VERSION_FRONTMATTER_KEY}:\\s*["']?([^"'\\n]+)["']?\\s*$`, "m");
|
|
32
|
+
const match = header.match(pattern);
|
|
33
|
+
return match?.[1]?.trim().replace(/^["']|["']$/g, "") ?? null;
|
|
34
|
+
}
|
|
35
|
+
/** 从 Skill 正文解析已安装版本(frontmatter 优先,HTML 注释兜底) */
|
|
36
|
+
export function parseSkillInstalledVersion(content) {
|
|
37
|
+
return parseSkillVersionFromFrontmatter(content) ?? parseSkillVersionMarker(content);
|
|
38
|
+
}
|
|
39
|
+
/** 是否缺少 Agent Skill 发现所需的 YAML frontmatter */
|
|
40
|
+
export function skillFrontmatterNeedsUpgrade(content) {
|
|
41
|
+
if (!content.trimStart().startsWith("---")) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const end = content.indexOf("\n---", 3);
|
|
45
|
+
if (end === -1) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
const header = content.slice(0, end + 4);
|
|
49
|
+
if (!/^name:\s*mcp-probe-kit\s*$/m.test(header)) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (!/^description:\s*>?-?\s*\S/m.test(header)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (!new RegExp(`^${SKILL_VERSION_FRONTMATTER_KEY}:\\s*`, "m").test(header)) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
20
60
|
export function parseAgentsContextVersion(content) {
|
|
21
61
|
const pattern = new RegExp(`<!--\\s*${AGENTS_CONTEXT_VERSION_MARKER}:\\s*([^\\s>]+)\\s*-->`, "i");
|
|
22
62
|
const match = content.match(pattern);
|
|
@@ -49,7 +89,10 @@ export function skillContentNeedsUpgrade(existing, targetVersion = VERSION) {
|
|
|
49
89
|
if (!existing?.trim()) {
|
|
50
90
|
return true;
|
|
51
91
|
}
|
|
52
|
-
|
|
92
|
+
if (skillFrontmatterNeedsUpgrade(existing)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
const installed = parseSkillInstalledVersion(existing);
|
|
53
96
|
if (!installed) {
|
|
54
97
|
return true;
|
|
55
98
|
}
|
|
@@ -6,6 +6,9 @@ import { resolveWorkspaceRoot, isLikelyProjectNamedRelativePath, buildProjectRoo
|
|
|
6
6
|
import { detectDocumentLocale, layoutAbsPath, legacyProjectContextExists, parseLayoutArgsFromRecord, resolveProjectContextLayout, toPosixPath, writeLayoutManifest, } from "../lib/project-context-layout.js";
|
|
7
7
|
import { mergeAgentsMdBlock } from "../lib/merge-agents-md.js";
|
|
8
8
|
import { generateAgentsMdInner } from "../lib/agents-md-template.js";
|
|
9
|
+
import { ensureHarnessAdapters } from "../lib/harness-adapters.js";
|
|
10
|
+
import { generateWorkflowSkillContent, MCP_PROBE_SKILL_REL_PATH } from "../lib/workflow-skill-template.js";
|
|
11
|
+
import { getMcpProbeSkillVersion } from "../lib/workflow-skill-version.js";
|
|
9
12
|
import { formatFileDeliverySection, writeProjectFile, } from "../lib/file-delivery.js";
|
|
10
13
|
import * as fs from "fs";
|
|
11
14
|
import * as path from "path";
|
|
@@ -177,14 +180,26 @@ async function generateProjectContext(layout, projectRoot) {
|
|
|
177
180
|
category: detection.category,
|
|
178
181
|
docs,
|
|
179
182
|
projectRootPosix: layout.projectRootPosix,
|
|
180
|
-
graphReady:
|
|
183
|
+
graphReady: fs.existsSync(layoutAbsPath(layout, layout.latestMarkdownPath)),
|
|
184
|
+
contextReady: modularExists,
|
|
181
185
|
});
|
|
182
186
|
const mergedAgents = mergeAgentsMdBlock(existingAgentsRaw, agentsInner);
|
|
183
|
-
const
|
|
187
|
+
const skillPath = layoutAbsPath(layout, MCP_PROBE_SKILL_REL_PATH);
|
|
188
|
+
const skillContent = fs.existsSync(skillPath)
|
|
189
|
+
? fs.readFileSync(skillPath, "utf8")
|
|
190
|
+
: generateWorkflowSkillContent(getMcpProbeSkillVersion());
|
|
191
|
+
const harnessResult = ensureHarnessAdapters(projectRootAbs, skillContent, layout.indexPath);
|
|
192
|
+
const manifestWritten = writeLayoutManifest(projectRootAbs, layout, harnessResult.layoutHarness);
|
|
184
193
|
const agentsMdWritten = writeProjectFile(projectRootAbs, layout.indexPath, mergedAgents.content, "always");
|
|
185
194
|
const writtenFiles = [
|
|
186
195
|
agentsMdWritten,
|
|
187
196
|
{ path: manifestWritten, action: "updated" },
|
|
197
|
+
...harnessResult.adapters
|
|
198
|
+
.filter((a) => a.created || a.updated)
|
|
199
|
+
.map((a) => ({
|
|
200
|
+
path: a.path,
|
|
201
|
+
action: (a.created ? "created" : "updated"),
|
|
202
|
+
})),
|
|
188
203
|
];
|
|
189
204
|
const pendingFiles = [
|
|
190
205
|
...(modularExists
|
package/package.json
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-probe-kit",
|
|
3
|
-
"version": "3.6.
|
|
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
|
-
"mcpName": "io.github.mybolide/mcp-probe-kit",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "build/index.js",
|
|
8
|
-
"bin": {
|
|
9
|
-
"mcp-probe-kit": "build/index.js"
|
|
10
|
-
},
|
|
11
|
-
"scripts": {
|
|
12
|
-
"build": "tsc",
|
|
13
|
-
"postbuild": "node scripts/copy-ui-embedded-data.mjs",
|
|
14
|
-
"watch": "tsc --watch",
|
|
15
|
-
"dev": "tsc && node build/index.js",
|
|
16
|
-
"test": "vitest --run",
|
|
17
|
-
"test:watch": "vitest",
|
|
18
|
-
"test:ui": "vitest --ui",
|
|
19
|
-
"inspector": "npx @modelcontextprotocol/inspector node build/index.js",
|
|
20
|
-
"prepare": "npm run build",
|
|
21
|
-
"prepublishOnly": "npm run build",
|
|
22
|
-
"sync-ui-data": "tsx scripts/sync-ui-data.ts",
|
|
23
|
-
"sync-version": "node scripts/sync-version.mjs",
|
|
24
|
-
"verify-workflow-skill": "tsx scripts/verify-workflow-skill.ts",
|
|
25
|
-
"sync-workflow-skill": "tsx scripts/sync-workflow-skill.ts",
|
|
26
|
-
"prebuild": "npm run sync-version && npm run sync-ui-data && npm run verify-workflow-skill && npm run sync-workflow-skill",
|
|
27
|
-
"docs:serve": "npx http-server docs -p 8080 -o"
|
|
28
|
-
},
|
|
29
|
-
"keywords": [
|
|
30
|
-
"mcp",
|
|
31
|
-
"model-context-protocol",
|
|
32
|
-
"cursor",
|
|
33
|
-
"ai-tools",
|
|
34
|
-
"development-tools",
|
|
35
|
-
"code-quality",
|
|
36
|
-
"code-review",
|
|
37
|
-
"refactor",
|
|
38
|
-
"debugging",
|
|
39
|
-
"sql-generator",
|
|
40
|
-
"ui-generator",
|
|
41
|
-
"react",
|
|
42
|
-
"vue",
|
|
43
|
-
"typescript",
|
|
44
|
-
"git-tools",
|
|
45
|
-
"ai-assistant"
|
|
46
|
-
],
|
|
47
|
-
"author": {
|
|
48
|
-
"name": "小墨 (Kyle)",
|
|
49
|
-
"url": "https://www.bytezonex.com/"
|
|
50
|
-
},
|
|
51
|
-
"license": "MIT",
|
|
52
|
-
"repository": {
|
|
53
|
-
"type": "git",
|
|
54
|
-
"url": "git+https://github.com/mybolide/mcp-probe-kit.git"
|
|
55
|
-
},
|
|
56
|
-
"bugs": {
|
|
57
|
-
"url": "https://github.com/mybolide/mcp-probe-kit/issues"
|
|
58
|
-
},
|
|
59
|
-
"homepage": "https://mcp-probe-kit.bytezonex.com",
|
|
60
|
-
"engines": {
|
|
61
|
-
"node": ">=18.0.0"
|
|
62
|
-
},
|
|
63
|
-
"files": [
|
|
64
|
-
"build",
|
|
65
|
-
"README.md",
|
|
66
|
-
"LICENSE"
|
|
67
|
-
],
|
|
68
|
-
"dependencies": {
|
|
69
|
-
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
70
|
-
"cross-spawn": "^7.0.6",
|
|
71
|
-
"csv-parse": "^6.1.0",
|
|
72
|
-
"tar": "^7.5.6"
|
|
73
|
-
},
|
|
74
|
-
"devDependencies": {
|
|
75
|
-
"@types/cross-spawn": "^6.0.6",
|
|
76
|
-
"@types/node": "^20.0.0",
|
|
77
|
-
"@types/tar": "^6.1.13",
|
|
78
|
-
"@vitest/ui": "^4.0.18",
|
|
79
|
-
"fast-check": "^4.5.3",
|
|
80
|
-
"tsx": "^4.21.0",
|
|
81
|
-
"typescript": "^5.3.0",
|
|
82
|
-
"vitest": "^4.0.18"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-probe-kit",
|
|
3
|
+
"version": "3.6.8",
|
|
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
|
+
"mcpName": "io.github.mybolide/mcp-probe-kit",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "build/index.js",
|
|
8
|
+
"bin": {
|
|
9
|
+
"mcp-probe-kit": "build/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"postbuild": "node scripts/copy-ui-embedded-data.mjs",
|
|
14
|
+
"watch": "tsc --watch",
|
|
15
|
+
"dev": "tsc && node build/index.js",
|
|
16
|
+
"test": "vitest --run",
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"test:ui": "vitest --ui",
|
|
19
|
+
"inspector": "npx @modelcontextprotocol/inspector node build/index.js",
|
|
20
|
+
"prepare": "npm run build",
|
|
21
|
+
"prepublishOnly": "npm run build",
|
|
22
|
+
"sync-ui-data": "tsx scripts/sync-ui-data.ts",
|
|
23
|
+
"sync-version": "node scripts/sync-version.mjs",
|
|
24
|
+
"verify-workflow-skill": "tsx scripts/verify-workflow-skill.ts",
|
|
25
|
+
"sync-workflow-skill": "tsx scripts/sync-workflow-skill.ts",
|
|
26
|
+
"prebuild": "npm run sync-version && npm run sync-ui-data && npm run verify-workflow-skill && npm run sync-workflow-skill",
|
|
27
|
+
"docs:serve": "npx http-server docs -p 8080 -o"
|
|
28
|
+
},
|
|
29
|
+
"keywords": [
|
|
30
|
+
"mcp",
|
|
31
|
+
"model-context-protocol",
|
|
32
|
+
"cursor",
|
|
33
|
+
"ai-tools",
|
|
34
|
+
"development-tools",
|
|
35
|
+
"code-quality",
|
|
36
|
+
"code-review",
|
|
37
|
+
"refactor",
|
|
38
|
+
"debugging",
|
|
39
|
+
"sql-generator",
|
|
40
|
+
"ui-generator",
|
|
41
|
+
"react",
|
|
42
|
+
"vue",
|
|
43
|
+
"typescript",
|
|
44
|
+
"git-tools",
|
|
45
|
+
"ai-assistant"
|
|
46
|
+
],
|
|
47
|
+
"author": {
|
|
48
|
+
"name": "小墨 (Kyle)",
|
|
49
|
+
"url": "https://www.bytezonex.com/"
|
|
50
|
+
},
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"repository": {
|
|
53
|
+
"type": "git",
|
|
54
|
+
"url": "git+https://github.com/mybolide/mcp-probe-kit.git"
|
|
55
|
+
},
|
|
56
|
+
"bugs": {
|
|
57
|
+
"url": "https://github.com/mybolide/mcp-probe-kit/issues"
|
|
58
|
+
},
|
|
59
|
+
"homepage": "https://mcp-probe-kit.bytezonex.com",
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=18.0.0"
|
|
62
|
+
},
|
|
63
|
+
"files": [
|
|
64
|
+
"build",
|
|
65
|
+
"README.md",
|
|
66
|
+
"LICENSE"
|
|
67
|
+
],
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
70
|
+
"cross-spawn": "^7.0.6",
|
|
71
|
+
"csv-parse": "^6.1.0",
|
|
72
|
+
"tar": "^7.5.6"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@types/cross-spawn": "^6.0.6",
|
|
76
|
+
"@types/node": "^20.0.0",
|
|
77
|
+
"@types/tar": "^6.1.13",
|
|
78
|
+
"@vitest/ui": "^4.0.18",
|
|
79
|
+
"fast-check": "^4.5.3",
|
|
80
|
+
"tsx": "^4.21.0",
|
|
81
|
+
"typescript": "^5.3.0",
|
|
82
|
+
"vitest": "^4.0.18"
|
|
83
|
+
}
|
|
84
|
+
}
|