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.
Files changed (31) hide show
  1. package/README.md +3 -1
  2. package/build/index.js +1 -0
  3. package/build/lib/__tests__/agents-md-template.unit.test.js +2 -0
  4. package/build/lib/__tests__/agents-skill-ref.unit.test.d.ts +1 -0
  5. package/build/lib/__tests__/agents-skill-ref.unit.test.js +32 -0
  6. package/build/lib/__tests__/harness-adapters.unit.test.d.ts +1 -0
  7. package/build/lib/__tests__/harness-adapters.unit.test.js +68 -0
  8. package/build/lib/__tests__/harness-skill-targets.unit.test.d.ts +1 -0
  9. package/build/lib/__tests__/harness-skill-targets.unit.test.js +59 -0
  10. package/build/lib/__tests__/project-mcp-resources.unit.test.js +1 -1
  11. package/build/lib/__tests__/workflow-skill-frontmatter.unit.test.d.ts +1 -0
  12. package/build/lib/__tests__/workflow-skill-frontmatter.unit.test.js +31 -0
  13. package/build/lib/__tests__/workflow-skill-installer.unit.test.js +21 -6
  14. package/build/lib/agents-md-template.d.ts +1 -0
  15. package/build/lib/agents-md-template.js +21 -6
  16. package/build/lib/agents-skill-ref.d.ts +6 -0
  17. package/build/lib/agents-skill-ref.js +45 -0
  18. package/build/lib/harness-adapters.d.ts +19 -0
  19. package/build/lib/harness-adapters.js +166 -0
  20. package/build/lib/harness-skill-targets.d.ts +38 -0
  21. package/build/lib/harness-skill-targets.js +95 -0
  22. package/build/lib/project-context-layout.d.ts +15 -2
  23. package/build/lib/project-context-layout.js +27 -3
  24. package/build/lib/workflow-skill-installer.d.ts +2 -0
  25. package/build/lib/workflow-skill-installer.js +19 -5
  26. package/build/lib/workflow-skill-template.d.ts +3 -0
  27. package/build/lib/workflow-skill-template.js +12 -5
  28. package/build/lib/workflow-skill-version.d.ts +7 -1
  29. package/build/lib/workflow-skill-version.js +45 -2
  30. package/build/tools/init_project_context.js +17 -2
  31. 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, parseSkillVersionMarker, skillContentNeedsUpgrade, } from "./workflow-skill-version.js";
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 ? parseSkillVersionMarker(existing) : null;
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: ensureMcpProbeSkill(root),
150
- agentsMd: ensureAgentsMdSkillReference(root),
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 { formatSkillVersionMarker } from "./workflow-skill-version.js";
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
- const versionMarker = formatSkillVersionMarker(skillVersion);
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 文件首行版本标记:`<!-- mcp-probe-kit-skill-version: 3.5.0 -->` */
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 文件首行版本标记:`<!-- mcp-probe-kit-skill-version: 3.5.0 -->` */
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
- const installed = parseSkillVersionMarker(existing);
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: false,
183
+ graphReady: fs.existsSync(layoutAbsPath(layout, layout.latestMarkdownPath)),
184
+ contextReady: modularExists,
181
185
  });
182
186
  const mergedAgents = mergeAgentsMdBlock(existingAgentsRaw, agentsInner);
183
- const manifestWritten = writeLayoutManifest(projectRootAbs, layout);
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.5",
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
+ }