mcp-probe-kit 3.0.16 → 3.0.18

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 (74) hide show
  1. package/README.md +603 -399
  2. package/build/index.js +13 -1
  3. package/build/lib/__tests__/memory-client.unit.test.d.ts +1 -0
  4. package/build/lib/__tests__/memory-client.unit.test.js +83 -0
  5. package/build/lib/__tests__/memory-config.unit.test.d.ts +1 -0
  6. package/build/lib/__tests__/memory-config.unit.test.js +33 -0
  7. package/build/lib/cursor-history-client.d.ts +54 -0
  8. package/build/lib/cursor-history-client.js +240 -0
  9. package/build/lib/gitnexus-bridge.js +6 -8
  10. package/build/lib/memory-client.d.ts +61 -0
  11. package/build/lib/memory-client.js +293 -0
  12. package/build/lib/memory-config.d.ts +14 -0
  13. package/build/lib/memory-config.js +31 -0
  14. package/build/lib/memory-orchestration.d.ts +26 -0
  15. package/build/lib/memory-orchestration.js +65 -0
  16. package/build/lib/project-detector.js +6 -4
  17. package/build/lib/workspace-root.d.ts +12 -0
  18. package/build/lib/workspace-root.js +153 -0
  19. package/build/resources/ui-ux-data/metadata.json +1 -1
  20. package/build/schemas/code-analysis-tools.d.ts +1 -1
  21. package/build/schemas/code-analysis-tools.js +1 -1
  22. package/build/schemas/index.d.ts +198 -4
  23. package/build/schemas/index.js +2 -0
  24. package/build/schemas/memory-tools.d.ts +191 -0
  25. package/build/schemas/memory-tools.js +106 -0
  26. package/build/schemas/orchestration-tools.d.ts +3 -3
  27. package/build/schemas/orchestration-tools.js +3 -3
  28. package/build/schemas/ui-ux-schemas.d.ts +8 -0
  29. package/build/schemas/ui-ux-schemas.js +4 -0
  30. package/build/tools/__tests__/cursor-history.unit.test.d.ts +1 -0
  31. package/build/tools/__tests__/cursor-history.unit.test.js +87 -0
  32. package/build/tools/__tests__/memorize_asset.unit.test.d.ts +1 -0
  33. package/build/tools/__tests__/memorize_asset.unit.test.js +68 -0
  34. package/build/tools/code_insight.d.ts +20 -0
  35. package/build/tools/code_insight.js +15 -0
  36. package/build/tools/cursor_list_conversations.d.ts +7 -0
  37. package/build/tools/cursor_list_conversations.js +35 -0
  38. package/build/tools/cursor_read_conversation.d.ts +7 -0
  39. package/build/tools/cursor_read_conversation.js +36 -0
  40. package/build/tools/cursor_search_conversations.d.ts +7 -0
  41. package/build/tools/cursor_search_conversations.js +36 -0
  42. package/build/tools/index.d.ts +6 -0
  43. package/build/tools/index.js +7 -0
  44. package/build/tools/init_project_context.d.ts +20 -1
  45. package/build/tools/init_project_context.js +114 -99
  46. package/build/tools/memorize_asset.d.ts +7 -0
  47. package/build/tools/memorize_asset.js +66 -0
  48. package/build/tools/read_memory_asset.d.ts +7 -0
  49. package/build/tools/read_memory_asset.js +26 -0
  50. package/build/tools/scan_and_extract_patterns.d.ts +27 -0
  51. package/build/tools/scan_and_extract_patterns.js +346 -0
  52. package/build/tools/start_bugfix.d.ts +20 -0
  53. package/build/tools/start_bugfix.js +97 -69
  54. package/build/tools/start_feature.d.ts +20 -0
  55. package/build/tools/start_feature.js +61 -31
  56. package/build/tools/start_onboard.d.ts +20 -0
  57. package/build/tools/start_onboard.js +15 -0
  58. package/build/tools/start_ui.d.ts +20 -0
  59. package/build/tools/start_ui.js +66 -32
  60. package/docs/data/tools.js +472 -373
  61. package/docs/i18n/all-tools/en.json +38 -5
  62. package/docs/i18n/all-tools/ja.json +14 -4
  63. package/docs/i18n/all-tools/ko.json +13 -3
  64. package/docs/i18n/all-tools/zh-CN.json +38 -5
  65. package/docs/i18n/en.json +48 -10
  66. package/docs/i18n/ja.json +47 -9
  67. package/docs/i18n/ko.json +47 -9
  68. package/docs/i18n/zh-CN.json +48 -10
  69. package/docs/pages/all-tools.html +515 -515
  70. package/docs/pages/examples.html +661 -661
  71. package/docs/pages/getting-started.html +673 -582
  72. package/docs/pages/migration.html +291 -291
  73. package/package.json +83 -82
  74. package/docs/debug-i18n.html +0 -163
@@ -6,6 +6,8 @@ import { renderOrchestrationHeader } from "../lib/orchestration-guidance.js";
6
6
  import { BugFixReportSchema, RequirementsLoopSchema } from "../schemas/structured-output.js";
7
7
  import { reportToolProgress, throwIfAborted, } from "../lib/tool-execution-context.js";
8
8
  import { buildBugfixGraphContext } from "../lib/gitnexus-bridge.js";
9
+ import { buildMemoryPlanStep, loadMemoryInjectionContext, renderMemoryGuideSection, } from "../lib/memory-orchestration.js";
10
+ import { resolveWorkspaceRoot, isLikelyProjectNamedRelativePath, buildProjectRootRetryHint } from "../lib/workspace-root.js";
9
11
  function decideTemplateProfile(description) {
10
12
  const text = description || '';
11
13
  const lengthScore = text.length >= 200 ? 2 : text.length >= 120 ? 1 : 0;
@@ -44,7 +46,7 @@ function resolveTemplateProfile(rawProfile, description) {
44
46
  warning: `模板档位 "${rawProfile}" 不支持,已回退为 ${fallback}`,
45
47
  };
46
48
  }
47
- const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因分析)
49
+ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因分析)
48
50
 
49
51
  ## 🎯 目标
50
52
 
@@ -59,21 +61,21 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因
59
61
 
60
62
  ---
61
63
 
62
- ## 📋 步骤 0: 项目上下文与取证基线(自动处理)
64
+ ## 📋 步骤 0: 项目上下文与取证基线(自动处理)
63
65
 
64
- **操作**:
65
- 1. 检查 \`docs/project-context.md\` 是否存在
66
- 2. 检查 \`docs/graph-insights/latest.md\` 和 \`docs/graph-insights/latest.json\` 是否存在
67
- 3. **如果任一缺失**:
68
- - 调用 \`init_project_context\` 工具
69
- - 等待生成完成
70
- 4. **读取** \`docs/project-context.md\` 与图谱文档
71
- 5. 了解项目的技术栈、架构、测试框架和调用链
72
- 6. 后续步骤参考此上下文
66
+ **操作**:
67
+ 1. 检查 \`docs/project-context.md\` 是否存在
68
+ 2. 检查 \`docs/graph-insights/latest.md\` 和 \`docs/graph-insights/latest.json\` 是否存在
69
+ 3. **如果任一缺失**:
70
+ - 调用 \`init_project_context\` 工具
71
+ - 等待生成完成
72
+ 4. **读取** \`docs/project-context.md\` 与图谱文档
73
+ 5. 了解项目的技术栈、架构、测试框架和调用链
74
+ 6. 后续步骤参考此上下文
73
75
 
74
76
  ---
75
77
 
76
- ## 🔍 步骤 1: 先做 TBP 1-7,再决定修复
78
+ ## 🔍 步骤 1: 先做 TBP 1-7,再决定修复
77
79
 
78
80
  **调用工具**: \`fix_bug\`
79
81
 
@@ -85,15 +87,15 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因
85
87
  }
86
88
  \`\`\`
87
89
 
88
- **执行要点**:
89
- 1. 先定义现象,不能泛化
90
- 2. 复盘时间线,尽量带时间/步骤/状态
91
- 3. 明确排除错误方向,并说明为什么不是
92
- 4. 对比成功/失败样本,找分叉点
93
- 5. 定位问题边界(模型 / 状态机 / 工具 / 文件 / 环境)
94
- 6. 用因果句陈述真因:A + B 在条件 D 下导致 C
95
- 7. 闭合证据链后,才进入修复设计
96
- 8. 修复必须说明风险与验证方式
90
+ **执行要点**:
91
+ 1. 先定义现象,不能泛化
92
+ 2. 复盘时间线,尽量带时间/步骤/状态
93
+ 3. 明确排除错误方向,并说明为什么不是
94
+ 4. 对比成功/失败样本,找分叉点
95
+ 5. 定位问题边界(模型 / 状态机 / 工具 / 文件 / 环境)
96
+ 6. 用因果句陈述真因:A + B 在条件 D 下导致 C
97
+ 7. 闭合证据链后,才进入修复设计
98
+ 8. 修复必须说明风险与验证方式
97
99
 
98
100
  **产出**: 修复后的代码
99
101
 
@@ -123,8 +125,8 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因
123
125
  ## ✅ 完成检查
124
126
 
125
127
  - [ ] 项目上下文已读取
126
- - [ ] TBP-1~TBP-7 已闭合
127
- - [ ] 真因已写成因果句
128
+ - [ ] TBP-1~TBP-7 已闭合
129
+ - [ ] 真因已写成因果句
128
130
  - [ ] 代码已修复
129
131
  - [ ] 测试已添加
130
132
  - [ ] 测试已通过
@@ -135,20 +137,20 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因
135
137
 
136
138
  完成后,向用户汇总:
137
139
 
138
- 1. **TBP 现象**: [精确定义的问题]
139
- 2. **TBP 时间线**: [关键事件顺序]
140
- 3. **已排除方向**: [不是哪些原因]
141
- 4. **问题边界**: [失控发生在哪一层]
142
- 5. **Bug 真因**: [根本原因]
143
- 6. **修复方案**: [修复说明]
144
- 7. **修改文件**: [文件列表]
145
- 8. **测试覆盖**: [测试情况]
140
+ 1. **TBP 现象**: [精确定义的问题]
141
+ 2. **TBP 时间线**: [关键事件顺序]
142
+ 3. **已排除方向**: [不是哪些原因]
143
+ 4. **问题边界**: [失控发生在哪一层]
144
+ 5. **Bug 真因**: [根本原因]
145
+ 6. **修复方案**: [修复说明]
146
+ 7. **修改文件**: [文件列表]
147
+ 8. **测试覆盖**: [测试情况]
146
148
 
147
149
  ---
148
150
 
149
151
  *编排工具: MCP Probe Kit - start_bugfix*
150
152
  `;
151
- const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格 | TBP 8 步)
153
+ const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格 | TBP 8 步)
152
154
 
153
155
  ## 🎯 目标
154
156
  修复 Bug:{error_message}
@@ -159,15 +161,15 @@ const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格 | TBP 8 步)
159
161
 
160
162
  ## ✅ 执行计划(按顺序)
161
163
 
162
- 1) 检查 \`docs/project-context.md\` 与 \`docs/graph-insights/latest.*\`,任一缺失则调用 \`init_project_context\`
163
- 2) 调用 \`fix_bug\`
164
+ 1) 检查 \`docs/project-context.md\` 与 \`docs/graph-insights/latest.*\`,任一缺失则调用 \`init_project_context\`
165
+ 2) 调用 \`fix_bug\`
164
166
  \`\`\`json
165
- {
166
- "error_message": "{error_message}",
167
- "stack_trace": "{stack_trace}",
168
- "analysis_mode": "{analysis_mode}"
169
- }
170
- \`\`\`
167
+ {
168
+ "error_message": "{error_message}",
169
+ "stack_trace": "{stack_trace}",
170
+ "analysis_mode": "{analysis_mode}"
171
+ }
172
+ \`\`\`
171
173
  3) 调用 \`gentest\`
172
174
  \`\`\`json
173
175
  {
@@ -179,22 +181,22 @@ const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格 | TBP 8 步)
179
181
  ---
180
182
 
181
183
  ## ✅ 输出汇总
182
- 1. TBP 现象
183
- 2. TBP 时间线
184
- 3. 已排除方向
185
- 4. 问题边界
186
- 5. Bug 真因
187
- 6. 修复方案
188
- 7. 修改文件
189
- 8. 测试覆盖
184
+ 1. TBP 现象
185
+ 2. TBP 时间线
186
+ 3. 已排除方向
187
+ 4. 问题边界
188
+ 5. Bug 真因
189
+ 6. 修复方案
190
+ 7. 修改文件
191
+ 8. 测试覆盖
190
192
 
191
193
  ---
192
194
 
193
195
  *编排工具: MCP Probe Kit - start_bugfix*
194
196
  `;
195
- const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(TBP RCA Loop)
197
+ const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(TBP RCA Loop)
196
198
 
197
- 本模式用于**生产级稳健补全**:在不改变用户意图的前提下补齐 TBP 8 步真因分析所需证据。
199
+ 本模式用于**生产级稳健补全**:在不改变用户意图的前提下补齐 TBP 8 步真因分析所需证据。
198
200
 
199
201
  ## 🎯 目标
200
202
  修复 Bug:{error_message}
@@ -210,7 +212,7 @@ const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(TBP RCA
210
212
  ## 🔁 执行步骤(每轮)
211
213
 
212
214
  ### 1) 生成待确认问题
213
- 使用 \`ask_user\` 提问,问题来源于 TBP 清单(现象/时间线/对比样本/边界/验证)。
215
+ 使用 \`ask_user\` 提问,问题来源于 TBP 清单(现象/时间线/对比样本/边界/验证)。
214
216
 
215
217
  **调用示例**:
216
218
  \`\`\`json
@@ -229,20 +231,20 @@ const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(TBP RCA
229
231
  - Assumption:无法确认但补全(需确认)
230
232
 
231
233
  ### 3) 自检与结束
232
- 若 \`openQuestions\` 为空且无高风险假设,则结束 loop,进入 TBP-6/7/8 修复流程。
234
+ 若 \`openQuestions\` 为空且无高风险假设,则结束 loop,进入 TBP-6/7/8 修复流程。
233
235
 
234
236
  ---
235
237
 
236
238
  ## ✅ 结束后继续
237
239
  当满足结束条件时,执行:
238
- 1. 调用 \`fix_bug\` 完成 TBP 8 步分析与修复方案
240
+ 1. 调用 \`fix_bug\` 完成 TBP 8 步分析与修复方案
239
241
  2. 调用 \`gentest\` 生成回归测试
240
242
 
241
243
  ---
242
244
 
243
245
  *编排工具: MCP Probe Kit - start_bugfix (requirements loop)*
244
246
  `;
245
- const LOOP_PROMPT_TEMPLATE_STRICT = `# 🧭 Bug 需求澄清与补全(TBP RCA Loop | 严格)
247
+ const LOOP_PROMPT_TEMPLATE_STRICT = `# 🧭 Bug 需求澄清与补全(TBP RCA Loop | 严格)
246
248
 
247
249
  本模式用于稳健补全关键信息,不改变用户意图。
248
250
 
@@ -317,6 +319,20 @@ export async function startBugfix(args, context) {
317
319
  const stackTrace = getString(parsedArgs.stack_trace);
318
320
  const codeContext = getString(parsedArgs.code_context);
319
321
  const projectRoot = getString(parsedArgs.project_root);
322
+ if (isLikelyProjectNamedRelativePath(projectRoot)) {
323
+ return {
324
+ content: [{
325
+ type: "text",
326
+ text: `拒绝执行 bugfix 编排:project_root 不能传带项目名的半相对路径,例如 ${projectRoot}。请改为传项目根目录绝对路径。`,
327
+ }],
328
+ isError: true,
329
+ structuredContent: {
330
+ error_code: "INVALID_PROJECT_ROOT",
331
+ rejected_project_root: projectRoot,
332
+ retry_hint: buildProjectRootRetryHint(projectRoot),
333
+ },
334
+ };
335
+ }
320
336
  const analysisMode = ((getString(parsedArgs.analysis_mode) || "tbp8").toLowerCase() === "tbp8"
321
337
  ? "tbp8"
322
338
  : "tbp8");
@@ -359,7 +375,7 @@ export async function startBugfix(args, context) {
359
375
  latestMarkdownPath: "docs/graph-insights/latest.md",
360
376
  latestJsonPath: "docs/graph-insights/latest.json",
361
377
  };
362
- const resolvedProjectRoot = path.resolve(projectRoot || process.cwd());
378
+ const resolvedProjectRoot = resolveWorkspaceRoot(projectRoot);
363
379
  const bootstrapState = {
364
380
  projectContextExists: fs.existsSync(path.join(resolvedProjectRoot, "docs", "project-context.md")),
365
381
  latestMarkdownExists: fs.existsSync(path.join(resolvedProjectRoot, "docs", "graph-insights", "latest.md")),
@@ -388,19 +404,21 @@ export async function startBugfix(args, context) {
388
404
  ]
389
405
  .filter(Boolean)
390
406
  .join("\n\n");
391
- const graphGuideSection = `
392
-
393
- ## 🧠 代码图谱上下文
394
- - 基线入口: ${graphDocs.latestMarkdownPath}
395
- - 基线结构化副本: ${graphDocs.latestJsonPath}
396
- - 基线状态: ${graphDocsMissing ? "缺失(需要补初始化)" : "可用"}
397
- - 任务级收敛: ${graphContext.available ? "可用" : "降级"}
398
- - 任务级摘要: ${graphContext.summary}
407
+ const graphGuideSection = `
408
+
409
+ ## 🧠 代码图谱上下文
410
+ - 基线入口: ${graphDocs.latestMarkdownPath}
411
+ - 基线结构化副本: ${graphDocs.latestJsonPath}
412
+ - 基线状态: ${graphDocsMissing ? "缺失(需要补初始化)" : "可用"}
413
+ - 任务级收敛: ${graphContext.available ? "可用" : "降级"}
414
+ - 任务级摘要: ${graphContext.summary}
399
415
  ${graphContext.highlights.length > 0
400
416
  ? `- 任务级线索:\n${graphContext.highlights.slice(0, 3).map((item) => ` - ${item}`).join("\n")}`
401
- : "- 任务级线索: 无"}
402
- - 使用方式: 先读取基线图谱,再用本次任务图谱做 TBP-4 / TBP-5 / TBP-6 的边界与真因收敛
417
+ : "- 任务级线索: 无"}
418
+ - 使用方式: 先读取基线图谱,再用本次任务图谱做 TBP-4 / TBP-5 / TBP-6 的边界与真因收敛
403
419
  `;
420
+ const memoryContext = await loadMemoryInjectionContext([errorMessage, stackTrace, codeContext].filter(Boolean).join("\n"));
421
+ const memoryGuideSection = renderMemoryGuideSection(memoryContext);
404
422
  if (requirementsMode === "loop") {
405
423
  throwIfAborted(context?.signal, "start_bugfix(loop) 已取消");
406
424
  await reportToolProgress(context, 70, "start_bugfix: 生成 loop 计划");
@@ -476,6 +494,7 @@ ${graphContext.highlights.length > 0
476
494
  },
477
495
  outputs: [],
478
496
  },
497
+ ...(memoryContext.enabled ? [buildMemoryPlanStep()] : []),
479
498
  ],
480
499
  };
481
500
  const header = renderOrchestrationHeader({
@@ -485,7 +504,10 @@ ${graphContext.highlights.length > 0
485
504
  '按 Requirements Loop 规则提问并更新结构化输出',
486
505
  '满足结束条件后按 delegated plan 执行修复与测试',
487
506
  ],
488
- notes: headerNotes,
507
+ notes: [
508
+ ...headerNotes,
509
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,优先复用历史修复经验并在结束后评估沉淀'] : []),
510
+ ],
489
511
  });
490
512
  const loopTemplate = profileDecision.resolved === 'strict'
491
513
  ? LOOP_PROMPT_TEMPLATE_STRICT
@@ -495,7 +517,8 @@ ${graphContext.highlights.length > 0
495
517
  .replace(/{analysis_mode}/g, analysisMode)
496
518
  .replace(/{question_budget}/g, String(questionBudget))
497
519
  .replace(/{assumption_cap}/g, String(assumptionCap)))
498
- + graphGuideSection;
520
+ + graphGuideSection
521
+ + memoryGuideSection;
499
522
  const loopReport = {
500
523
  mode: 'loop',
501
524
  round: 1,
@@ -546,7 +569,10 @@ ${graphContext.highlights.length > 0
546
569
  '按 delegated plan 顺序调用工具',
547
570
  '完成修复并生成回归测试',
548
571
  ],
549
- notes: headerNotes,
572
+ notes: [
573
+ ...headerNotes,
574
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,必要时先读取相似历史资产'] : []),
575
+ ],
550
576
  });
551
577
  const promptTemplate = profileDecision.resolved === 'strict'
552
578
  ? PROMPT_TEMPLATE_STRICT
@@ -556,7 +582,8 @@ ${graphContext.highlights.length > 0
556
582
  .replace(/{stack_trace}/g, stackTrace)
557
583
  .replace(/{analysis_mode}/g, analysisMode)
558
584
  .replace(/{stack_trace_section}/g, stackTraceSection))
559
- + graphGuideSection;
585
+ + graphGuideSection
586
+ + memoryGuideSection;
560
587
  const plan = {
561
588
  mode: 'delegated',
562
589
  steps: [
@@ -591,6 +618,7 @@ ${graphContext.highlights.length > 0
591
618
  },
592
619
  outputs: [],
593
620
  },
621
+ ...(memoryContext.enabled ? [buildMemoryPlanStep()] : []),
594
622
  ],
595
623
  };
596
624
  // 创建结构化的 Bug 修复报告
@@ -5,4 +5,24 @@ export declare function startFeature(args: any, context?: ToolExecutionContext):
5
5
  text: string;
6
6
  }[];
7
7
  isError: boolean;
8
+ structuredContent: {
9
+ error_code: string;
10
+ rejected_project_root: string;
11
+ retry_hint: {
12
+ preferred: {
13
+ project_root: string;
14
+ path: string;
15
+ };
16
+ fallback: {
17
+ project_root: string;
18
+ };
19
+ };
20
+ };
21
+ } | {
22
+ content: {
23
+ type: string;
24
+ text: string;
25
+ }[];
26
+ isError: boolean;
27
+ structuredContent?: undefined;
8
28
  }>;
@@ -6,6 +6,8 @@ import { renderOrchestrationHeader } from "../lib/orchestration-guidance.js";
6
6
  import { FeatureReportSchema, RequirementsLoopSchema } from "../schemas/structured-output.js";
7
7
  import { reportToolProgress, throwIfAborted, } from "../lib/tool-execution-context.js";
8
8
  import { buildFeatureGraphContext } from "../lib/gitnexus-bridge.js";
9
+ import { buildMemoryPlanStep, loadMemoryInjectionContext, renderMemoryGuideSection, } from "../lib/memory-orchestration.js";
10
+ import { resolveWorkspaceRoot, toWorkspacePath, isLikelyProjectNamedRelativePath, buildProjectRootRetryHint } from "../lib/workspace-root.js";
9
11
  /**
10
12
  * start_feature 智能编排工具
11
13
  *
@@ -64,15 +66,15 @@ const PROMPT_TEMPLATE = `# 🚀 新功能开发编排(委托式)
64
66
 
65
67
  ## ✅ 执行计划(按顺序)
66
68
 
67
- ### 0) 项目上下文(如缺失)
68
- **检查**:
69
- - \`{docs_dir}/project-context.md\`
70
- - \`{docs_dir}/graph-insights/latest.md\`
71
- - \`{docs_dir}/graph-insights/latest.json\`
72
- **缺失则调用**: \`init_project_context\`
73
- \`\`\`json
74
- { "docs_dir": "{docs_dir}", "project_root": "{project_root}" }
75
- \`\`\`
69
+ ### 0) 项目上下文(如缺失)
70
+ **检查**:
71
+ - \`{docs_dir}/project-context.md\`
72
+ - \`{docs_dir}/graph-insights/latest.md\`
73
+ - \`{docs_dir}/graph-insights/latest.json\`
74
+ **缺失则调用**: \`init_project_context\`
75
+ \`\`\`json
76
+ { "docs_dir": "{docs_dir}", "project_root": "{project_root}" }
77
+ \`\`\`
76
78
 
77
79
  ### 1) 生成功能规格
78
80
  **调用**: \`add_feature\`
@@ -100,12 +102,12 @@ const PROMPT_TEMPLATE = `# 🚀 新功能开发编排(委托式)
100
102
 
101
103
  ---
102
104
 
103
- ## ✅ 输出汇总(执行完成后)
104
- 1. 规格文档位置: \`{docs_dir}/specs/{feature_name}/\`
105
- 2. 图谱入口: \`{docs_dir}/graph-insights/latest.md\`
106
- 3. 估算结果: 故事点 + 时间区间
107
- 4. 主要风险(如有)
108
- 5. 下一步: 按 tasks.md 开始开发
105
+ ## ✅ 输出汇总(执行完成后)
106
+ 1. 规格文档位置: \`{docs_dir}/specs/{feature_name}/\`
107
+ 2. 图谱入口: \`{docs_dir}/graph-insights/latest.md\`
108
+ 3. 估算结果: 故事点 + 时间区间
109
+ 4. 主要风险(如有)
110
+ 5. 下一步: 按 tasks.md 开始开发
109
111
 
110
112
  ---
111
113
 
@@ -204,6 +206,20 @@ export async function startFeature(args, context) {
204
206
  let description = getString(parsedArgs.description);
205
207
  const docsDir = getString(parsedArgs.docs_dir) || "docs";
206
208
  const projectRoot = getString(parsedArgs.project_root);
209
+ if (isLikelyProjectNamedRelativePath(projectRoot)) {
210
+ return {
211
+ content: [{
212
+ type: "text",
213
+ text: `拒绝执行 feature 编排:project_root 不能传带项目名的半相对路径,例如 ${projectRoot}。请改为传项目根目录绝对路径。`,
214
+ }],
215
+ isError: true,
216
+ structuredContent: {
217
+ error_code: "INVALID_PROJECT_ROOT",
218
+ rejected_project_root: projectRoot,
219
+ retry_hint: buildProjectRootRetryHint(projectRoot),
220
+ },
221
+ };
222
+ }
207
223
  const templateProfile = getString(parsedArgs.template_profile) || "auto";
208
224
  const requirementsMode = getString(parsedArgs.requirements_mode) || "steady";
209
225
  const maxRounds = getNumber(parsedArgs.loop_max_rounds, 2);
@@ -240,7 +256,7 @@ export async function startFeature(args, context) {
240
256
  latestMarkdownPath: `${docsDir}/graph-insights/latest.md`,
241
257
  latestJsonPath: `${docsDir}/graph-insights/latest.json`,
242
258
  };
243
- const resolvedProjectRoot = path.resolve(projectRoot || process.cwd());
259
+ const resolvedProjectRoot = resolveWorkspaceRoot(projectRoot);
244
260
  const bootstrapState = {
245
261
  projectContextExists: fs.existsSync(path.join(resolvedProjectRoot, docsDir, "project-context.md")),
246
262
  latestMarkdownExists: fs.existsSync(path.join(resolvedProjectRoot, docsDir, "graph-insights", "latest.md")),
@@ -256,18 +272,18 @@ export async function startFeature(args, context) {
256
272
  const graphStatusNote = graphContext.available
257
273
  ? `任务图谱收敛: 可用(${graphContext.mode})`
258
274
  : "任务图谱收敛: 已降级(自动回退)";
259
- const graphGuideSection = `
260
-
261
- ## 🧠 代码图谱上下文
262
- - 基线入口: ${graphDocs.latestMarkdownPath}
263
- - 基线结构化副本: ${graphDocs.latestJsonPath}
264
- - 基线状态: ${graphDocsMissing ? "缺失(需要补初始化)" : "可用"}
265
- - 任务级收敛: ${graphContext.available ? "可用" : "降级"}
266
- - 任务级摘要: ${graphContext.summary}
275
+ const graphGuideSection = `
276
+
277
+ ## 🧠 代码图谱上下文
278
+ - 基线入口: ${graphDocs.latestMarkdownPath}
279
+ - 基线结构化副本: ${graphDocs.latestJsonPath}
280
+ - 基线状态: ${graphDocsMissing ? "缺失(需要补初始化)" : "可用"}
281
+ - 任务级收敛: ${graphContext.available ? "可用" : "降级"}
282
+ - 任务级摘要: ${graphContext.summary}
267
283
  ${graphContext.highlights.length > 0
268
284
  ? `- 任务级线索:\n${graphContext.highlights.slice(0, 3).map((item) => ` - ${item}`).join("\n")}`
269
- : "- 任务级线索: 无"}
270
- - 使用方式: 先参考基线图谱,再使用本次任务图谱线索约束模块边界和改动范围
285
+ : "- 任务级线索: 无"}
286
+ - 使用方式: 先参考基线图谱,再使用本次任务图谱线索约束模块边界和改动范围
271
287
  `;
272
288
  const estimateCodeContext = [
273
289
  `参考生成的 ${docsDir}/specs/${featureName}/tasks.md`,
@@ -281,6 +297,8 @@ ${graphContext.highlights.length > 0
281
297
  ]
282
298
  .filter(Boolean)
283
299
  .join("\n");
300
+ const memoryContext = await loadMemoryInjectionContext(`${featureName}\n${description}`);
301
+ const memoryGuideSection = renderMemoryGuideSection(memoryContext);
284
302
  if (requirementsMode === "loop") {
285
303
  throwIfAborted(context?.signal, "start_feature(loop) 已取消");
286
304
  await reportToolProgress(context, 70, "start_feature: 生成 loop 计划");
@@ -355,6 +373,7 @@ ${graphContext.highlights.length > 0
355
373
  },
356
374
  outputs: [],
357
375
  },
376
+ ...(memoryContext.enabled ? [buildMemoryPlanStep()] : []),
358
377
  ],
359
378
  };
360
379
  const header = renderOrchestrationHeader({
@@ -364,15 +383,20 @@ ${graphContext.highlights.length > 0
364
383
  '按 Requirements Loop 规则提问并更新结构化输出',
365
384
  '满足结束条件后生成规格并完成估算',
366
385
  ],
367
- notes: [`模板档位: ${templateProfile}`, graphStatusNote],
386
+ notes: [
387
+ `模板档位: ${templateProfile}`,
388
+ graphStatusNote,
389
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,按需读取历史资产并在结束后评估是否沉淀'] : []),
390
+ ],
368
391
  });
369
392
  const guide = (header + LOOP_PROMPT_TEMPLATE
370
393
  .replace(/{feature_name}/g, featureName)
371
394
  .replace(/{description}/g, description)
372
- .replace(/{project_root}/g, (projectRoot || process.cwd()).replace(/\\/g, "/"))
395
+ .replace(/{project_root}/g, toWorkspacePath(projectRoot))
373
396
  .replace(/{question_budget}/g, String(questionBudget))
374
397
  .replace(/{assumption_cap}/g, String(assumptionCap)))
375
- + graphGuideSection;
398
+ + graphGuideSection
399
+ + memoryGuideSection;
376
400
  const loopReport = {
377
401
  mode: 'loop',
378
402
  round: 1,
@@ -419,7 +443,11 @@ ${graphContext.highlights.length > 0
419
443
  '按 delegated plan 顺序调用工具',
420
444
  '生成规格文档并完成工作量估算',
421
445
  ],
422
- notes: [`模板档位: ${templateProfile}`, graphStatusNote],
446
+ notes: [
447
+ `模板档位: ${templateProfile}`,
448
+ graphStatusNote,
449
+ ...(memoryContext.enabled ? ['记忆系统: 已启用,先复用摘要资产,必要时读取详情'] : []),
450
+ ],
423
451
  });
424
452
  const guide = (header + PROMPT_TEMPLATE
425
453
  .replace(/{feature_name}/g, featureName)
@@ -427,7 +455,8 @@ ${graphContext.highlights.length > 0
427
455
  .replace(/{docs_dir}/g, docsDir)
428
456
  .replace(/{project_root}/g, (projectRoot || process.cwd()).replace(/\\/g, "/"))
429
457
  .replace(/{template_profile}/g, templateProfile))
430
- + graphGuideSection;
458
+ + graphGuideSection
459
+ + memoryGuideSection;
431
460
  const plan = {
432
461
  mode: 'delegated',
433
462
  steps: [
@@ -461,6 +490,7 @@ ${graphContext.highlights.length > 0
461
490
  },
462
491
  outputs: [],
463
492
  },
493
+ ...(memoryContext.enabled ? [buildMemoryPlanStep()] : []),
464
494
  ],
465
495
  };
466
496
  // 创建结构化的功能开发报告
@@ -5,4 +5,24 @@ export declare function startOnboard(args: any, context?: ToolExecutionContext):
5
5
  text: string;
6
6
  }[];
7
7
  isError: boolean;
8
+ structuredContent: {
9
+ error_code: string;
10
+ rejected_project_root: string;
11
+ retry_hint: {
12
+ preferred: {
13
+ project_root: string;
14
+ path: string;
15
+ };
16
+ fallback: {
17
+ project_root: string;
18
+ };
19
+ };
20
+ };
21
+ } | {
22
+ content: {
23
+ type: string;
24
+ text: string;
25
+ }[];
26
+ isError: boolean;
27
+ structuredContent?: undefined;
8
28
  }>;
@@ -3,6 +3,7 @@ import { okStructured } from "../lib/response.js";
3
3
  import { renderOrchestrationHeader } from "../lib/orchestration-guidance.js";
4
4
  import { OnboardingReportSchema } from "../schemas/structured-output.js";
5
5
  import { reportToolProgress, throwIfAborted, } from "../lib/tool-execution-context.js";
6
+ import { isLikelyProjectNamedRelativePath, buildProjectRootRetryHint } from "../lib/workspace-root.js";
6
7
  /**
7
8
  * start_onboard 智能编排工具
8
9
  *
@@ -111,6 +112,20 @@ export async function startOnboard(args, context) {
111
112
  });
112
113
  const projectPath = getString(parsedArgs.project_path) || ".";
113
114
  const docsDir = getString(parsedArgs.docs_dir) || "docs";
115
+ if (isLikelyProjectNamedRelativePath(projectPath)) {
116
+ return {
117
+ content: [{
118
+ type: "text",
119
+ text: `拒绝执行项目上手编排:project_path 不能传带项目名的半相对路径,例如 ${projectPath}。请改为传项目根目录绝对路径。`,
120
+ }],
121
+ isError: true,
122
+ structuredContent: {
123
+ error_code: "INVALID_PROJECT_ROOT",
124
+ rejected_project_root: projectPath,
125
+ retry_hint: buildProjectRootRetryHint(projectPath),
126
+ },
127
+ };
128
+ }
114
129
  throwIfAborted(context?.signal, "start_onboard 已取消");
115
130
  await reportToolProgress(context, 85, "start_onboard: 生成执行计划");
116
131
  const header = renderOrchestrationHeader({
@@ -17,4 +17,24 @@ export declare function startUi(args: any, context?: ToolExecutionContext): Prom
17
17
  text: string;
18
18
  }[];
19
19
  isError: boolean;
20
+ structuredContent: {
21
+ error_code: string;
22
+ rejected_project_root: string;
23
+ retry_hint: {
24
+ preferred: {
25
+ project_root: string;
26
+ path: string;
27
+ };
28
+ fallback: {
29
+ project_root: string;
30
+ };
31
+ };
32
+ };
33
+ } | {
34
+ content: {
35
+ type: string;
36
+ text: string;
37
+ }[];
38
+ isError: boolean;
39
+ structuredContent?: undefined;
20
40
  }>;