mcp-probe-kit 3.0.9 → 3.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +14 -4
  2. package/build/lib/__tests__/gitnexus-bridge.unit.test.d.ts +1 -0
  3. package/build/lib/__tests__/gitnexus-bridge.unit.test.js +86 -0
  4. package/build/lib/gitnexus-bridge.d.ts +23 -0
  5. package/build/lib/gitnexus-bridge.js +517 -21
  6. package/build/schemas/code-analysis-tools.d.ts +9 -1
  7. package/build/schemas/code-analysis-tools.js +9 -1
  8. package/build/schemas/git-tools.d.ts +1 -1
  9. package/build/schemas/git-tools.js +1 -1
  10. package/build/schemas/index.d.ts +23 -3
  11. package/build/schemas/orchestration-tools.d.ts +13 -1
  12. package/build/schemas/orchestration-tools.js +13 -1
  13. package/build/schemas/output/core-tools.d.ts +130 -1
  14. package/build/schemas/output/core-tools.js +71 -1
  15. package/build/schemas/output/index.d.ts +2 -2
  16. package/build/schemas/output/index.js +2 -2
  17. package/build/schemas/output/project-tools.d.ts +13 -0
  18. package/build/schemas/output/project-tools.js +9 -0
  19. package/build/schemas/structured-output.d.ts +358 -5
  20. package/build/schemas/structured-output.js +169 -5
  21. package/build/tools/__tests__/code_insight.unit.test.js +81 -1
  22. package/build/tools/__tests__/fix_bug.unit.test.d.ts +1 -0
  23. package/build/tools/__tests__/fix_bug.unit.test.js +31 -0
  24. package/build/tools/__tests__/gencommit.unit.test.d.ts +1 -0
  25. package/build/tools/__tests__/gencommit.unit.test.js +41 -0
  26. package/build/tools/__tests__/init_project_context.unit.test.d.ts +1 -0
  27. package/build/tools/__tests__/init_project_context.unit.test.js +63 -0
  28. package/build/tools/__tests__/start_bugfix.unit.test.js +10 -0
  29. package/build/tools/__tests__/start_feature.unit.test.js +10 -0
  30. package/build/tools/code_insight.d.ts +10 -0
  31. package/build/tools/code_insight.js +156 -3
  32. package/build/tools/fix_bug.d.ts +3 -3
  33. package/build/tools/fix_bug.js +297 -312
  34. package/build/tools/gencommit.js +144 -123
  35. package/build/tools/init_project_context.js +211 -53
  36. package/build/tools/start_bugfix.js +170 -70
  37. package/build/tools/start_feature.js +79 -25
  38. package/docs/data/tools.js +33 -31
  39. package/docs/i18n/all-tools/en.json +9 -9
  40. package/docs/i18n/all-tools/ja.json +9 -9
  41. package/docs/i18n/all-tools/ko.json +9 -9
  42. package/docs/i18n/all-tools/zh-CN.json +9 -9
  43. package/docs/i18n/en.json +480 -481
  44. package/docs/i18n/ja.json +478 -479
  45. package/docs/i18n/ko.json +480 -481
  46. package/docs/i18n/zh-CN.json +480 -481
  47. package/docs/index.html +2 -2
  48. package/docs/pages/all-tools.html +2 -2
  49. package/docs/pages/examples.html +2 -2
  50. package/docs/pages/getting-started.html +2 -2
  51. package/docs/pages/migration.html +2 -2
  52. package/package.json +1 -2
@@ -1,3 +1,5 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
1
3
  import { parseArgs, getString, getNumber } from "../utils/parseArgs.js";
2
4
  import { okStructured } from "../lib/response.js";
3
5
  import { renderOrchestrationHeader } from "../lib/orchestration-guidance.js";
@@ -42,7 +44,7 @@ function resolveTemplateProfile(rawProfile, description) {
42
44
  warning: `模板档位 "${rawProfile}" 不支持,已回退为 ${fallback}`,
43
45
  };
44
46
  }
45
- const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南
47
+ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南(TBP 8 步真因分析)
46
48
 
47
49
  ## 🎯 目标
48
50
 
@@ -57,20 +59,21 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南
57
59
 
58
60
  ---
59
61
 
60
- ## 📋 步骤 0: 项目上下文(自动处理)
62
+ ## 📋 步骤 0: 项目上下文与取证基线(自动处理)
61
63
 
62
- **操作**:
63
- 1. 检查 \`docs/project-context.md\` 是否存在
64
- 2. **如果不存在**:
65
- - 调用 \`init_project_context\` 工具
66
- - 等待生成完成
67
- 3. **读取** \`docs/project-context.md\` 内容
68
- 4. 了解项目的技术栈、架构、测试框架
69
- 5. 后续步骤参考此上下文
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. 后续步骤参考此上下文
70
73
 
71
74
  ---
72
75
 
73
- ## 🔍 步骤 1: Bug 分析与修复
76
+ ## 🔍 步骤 1: 先做 TBP 1-7,再决定修复
74
77
 
75
78
  **调用工具**: \`fix_bug\`
76
79
 
@@ -82,11 +85,15 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南
82
85
  }
83
86
  \`\`\`
84
87
 
85
- **执行要点**:
86
- 1. 按指南完成问题定位
87
- 2. 使用 5 Whys 分析根本原因
88
- 3. 设计修复方案
89
- 4. 实施代码修复
88
+ **执行要点**:
89
+ 1. 先定义现象,不能泛化
90
+ 2. 复盘时间线,尽量带时间/步骤/状态
91
+ 3. 明确排除错误方向,并说明为什么不是
92
+ 4. 对比成功/失败样本,找分叉点
93
+ 5. 定位问题边界(模型 / 状态机 / 工具 / 文件 / 环境)
94
+ 6. 用因果句陈述真因:A + B 在条件 D 下导致 C
95
+ 7. 闭合证据链后,才进入修复设计
96
+ 8. 修复必须说明风险与验证方式
90
97
 
91
98
  **产出**: 修复后的代码
92
99
 
@@ -116,8 +123,8 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南
116
123
  ## ✅ 完成检查
117
124
 
118
125
  - [ ] 项目上下文已读取
119
- - [ ] Bug 已定位
120
- - [ ] 根本原因已分析
126
+ - [ ] TBP-1~TBP-7 已闭合
127
+ - [ ] 真因已写成因果句
121
128
  - [ ] 代码已修复
122
129
  - [ ] 测试已添加
123
130
  - [ ] 测试已通过
@@ -128,16 +135,20 @@ const PROMPT_TEMPLATE_GUIDED = `# 🐛 Bug 修复编排指南
128
135
 
129
136
  完成后,向用户汇总:
130
137
 
131
- 1. **Bug 原因**: [根本原因]
132
- 2. **修复方案**: [修复说明]
133
- 3. **修改文件**: [文件列表]
134
- 4. **测试覆盖**: [测试情况]
138
+ 1. **TBP 现象**: [精确定义的问题]
139
+ 2. **TBP 时间线**: [关键事件顺序]
140
+ 3. **已排除方向**: [不是哪些原因]
141
+ 4. **问题边界**: [失控发生在哪一层]
142
+ 5. **Bug 真因**: [根本原因]
143
+ 6. **修复方案**: [修复说明]
144
+ 7. **修改文件**: [文件列表]
145
+ 8. **测试覆盖**: [测试情况]
135
146
 
136
147
  ---
137
148
 
138
149
  *编排工具: MCP Probe Kit - start_bugfix*
139
150
  `;
140
- const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格)
151
+ const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格 | TBP 8 步)
141
152
 
142
153
  ## 🎯 目标
143
154
  修复 Bug:{error_message}
@@ -148,14 +159,15 @@ const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格)
148
159
 
149
160
  ## ✅ 执行计划(按顺序)
150
161
 
151
- 1) 检查 \`docs/project-context.md\`,缺失则调用 \`init_project_context\`
152
- 2) 调用 \`fix_bug\`
162
+ 1) 检查 \`docs/project-context.md\` \`docs/graph-insights/latest.*\`,任一缺失则调用 \`init_project_context\`
163
+ 2) 调用 \`fix_bug\`
153
164
  \`\`\`json
154
- {
155
- "error_message": "{error_message}",
156
- "stack_trace": "{stack_trace}"
157
- }
158
- \`\`\`
165
+ {
166
+ "error_message": "{error_message}",
167
+ "stack_trace": "{stack_trace}",
168
+ "analysis_mode": "{analysis_mode}"
169
+ }
170
+ \`\`\`
159
171
  3) 调用 \`gentest\`
160
172
  \`\`\`json
161
173
  {
@@ -167,18 +179,22 @@ const PROMPT_TEMPLATE_STRICT = `# 🐛 Bug 修复编排(严格)
167
179
  ---
168
180
 
169
181
  ## ✅ 输出汇总
170
- 1. Bug 原因
171
- 2. 修复方案
172
- 3. 修改文件
173
- 4. 测试覆盖
182
+ 1. TBP 现象
183
+ 2. TBP 时间线
184
+ 3. 已排除方向
185
+ 4. 问题边界
186
+ 5. Bug 真因
187
+ 6. 修复方案
188
+ 7. 修改文件
189
+ 8. 测试覆盖
174
190
 
175
191
  ---
176
192
 
177
193
  *编排工具: MCP Probe Kit - start_bugfix*
178
194
  `;
179
- const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(Requirements Loop)
195
+ const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(TBP RCA Loop)
180
196
 
181
- 本模式用于**生产级稳健补全**:在不改变用户意图的前提下补齐 Bug 修复所需关键信息。
197
+ 本模式用于**生产级稳健补全**:在不改变用户意图的前提下补齐 TBP 8 步真因分析所需证据。
182
198
 
183
199
  ## 🎯 目标
184
200
  修复 Bug:{error_message}
@@ -194,7 +210,7 @@ const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(Requirem
194
210
  ## 🔁 执行步骤(每轮)
195
211
 
196
212
  ### 1) 生成待确认问题
197
- 使用 \`ask_user\` 提问,问题来源于 Bug 修复补全清单(复现/环境/期望/影响/验证)。
213
+ 使用 \`ask_user\` 提问,问题来源于 TBP 清单(现象/时间线/对比样本/边界/验证)。
198
214
 
199
215
  **调用示例**:
200
216
  \`\`\`json
@@ -213,20 +229,20 @@ const LOOP_PROMPT_TEMPLATE_GUIDED = `# 🧭 Bug 需求澄清与补全(Requirem
213
229
  - Assumption:无法确认但补全(需确认)
214
230
 
215
231
  ### 3) 自检与结束
216
- 若 \`openQuestions\` 为空且无高风险假设,则结束 loop,进入修复流程。
232
+ 若 \`openQuestions\` 为空且无高风险假设,则结束 loop,进入 TBP-6/7/8 修复流程。
217
233
 
218
234
  ---
219
235
 
220
236
  ## ✅ 结束后继续
221
237
  当满足结束条件时,执行:
222
- 1. 调用 \`fix_bug\` 进行定位与修复
238
+ 1. 调用 \`fix_bug\` 完成 TBP 8 步分析与修复方案
223
239
  2. 调用 \`gentest\` 生成回归测试
224
240
 
225
241
  ---
226
242
 
227
243
  *编排工具: MCP Probe Kit - start_bugfix (requirements loop)*
228
244
  `;
229
- const LOOP_PROMPT_TEMPLATE_STRICT = `# 🧭 Bug 需求澄清与补全(Requirements Loop | 严格)
245
+ const LOOP_PROMPT_TEMPLATE_STRICT = `# 🧭 Bug 需求澄清与补全(TBP RCA Loop | 严格)
230
246
 
231
247
  本模式用于稳健补全关键信息,不改变用户意图。
232
248
 
@@ -257,12 +273,12 @@ const LOOP_PROMPT_TEMPLATE_STRICT = `# 🧭 Bug 需求澄清与补全(Requirem
257
273
  `;
258
274
  function buildBugfixQuestions(questionBudget) {
259
275
  const base = [
260
- { question: "复现步骤是什么?", context: "复现步骤", required: true },
261
- { question: "环境/版本信息是什么?", context: "环境信息", required: true },
262
- { question: "期望行为是什么?", context: "期望行为", required: true },
263
- { question: "实际表现是什么?", context: "实际表现", required: true },
264
- { question: "影响范围与严重级别如何?", context: "影响范围", required: true },
265
- { question: "是否有相关日志/错误栈?", context: "日志信息", required: false },
276
+ { question: "请精确定义现象:用户可见的问题是什么?", context: "现象", required: true },
277
+ { question: "问题发生的关键时间线是什么?开始、过程中、最后停在什么状态?", context: "时间线", required: true },
278
+ { question: "期望行为与实际行为分别是什么?", context: "期望与实际", required: true },
279
+ { question: "有没有成功样本或不出问题的对照场景?", context: "对比样本", required: false },
280
+ { question: "环境/版本/配置差异是什么?", context: "环境信息", required: true },
281
+ { question: "是否有日志、堆栈、run id、session id、trace 等证据?", context: "证据标识", required: false },
266
282
  ];
267
283
  return base.slice(0, Math.max(0, questionBudget));
268
284
  }
@@ -275,6 +291,8 @@ export async function startBugfix(args, context) {
275
291
  defaultValues: {
276
292
  error_message: "",
277
293
  stack_trace: "",
294
+ code_context: "",
295
+ analysis_mode: "tbp8",
278
296
  template_profile: "auto",
279
297
  requirements_mode: "steady",
280
298
  loop_max_rounds: 2,
@@ -285,6 +303,9 @@ export async function startBugfix(args, context) {
285
303
  fieldAliases: {
286
304
  error_message: ["error", "err", "message", "错误", "错误信息"],
287
305
  stack_trace: ["stack", "trace", "堆栈", "调用栈"],
306
+ code_context: ["code_context", "code", "context", "相关代码", "代码上下文"],
307
+ project_root: ["projectRoot", "project_path", "projectPath", "root", "project_root", "项目路径", "项目根目录"],
308
+ analysis_mode: ["analysis_mode", "methodology", "rca", "tbp", "分析方法"],
288
309
  template_profile: ["profile", "template_profile", "模板档位", "模板模式"],
289
310
  requirements_mode: ["mode", "requirements_mode", "loop", "需求模式"],
290
311
  loop_max_rounds: ["max_rounds", "rounds", "最大轮次"],
@@ -294,6 +315,11 @@ export async function startBugfix(args, context) {
294
315
  });
295
316
  const errorMessage = getString(parsedArgs.error_message);
296
317
  const stackTrace = getString(parsedArgs.stack_trace);
318
+ const codeContext = getString(parsedArgs.code_context);
319
+ const projectRoot = getString(parsedArgs.project_root);
320
+ const analysisMode = ((getString(parsedArgs.analysis_mode) || "tbp8").toLowerCase() === "tbp8"
321
+ ? "tbp8"
322
+ : "tbp8");
297
323
  const rawProfile = getString(parsedArgs.template_profile);
298
324
  const requirementsMode = getString(parsedArgs.requirements_mode) || "steady";
299
325
  const maxRounds = getNumber(parsedArgs.loop_max_rounds, 2);
@@ -309,6 +335,7 @@ export async function startBugfix(args, context) {
309
335
  const templateMeta = {
310
336
  profile: profileDecision.resolved,
311
337
  requested: profileDecision.requested,
338
+ analysisMode,
312
339
  };
313
340
  if (profileDecision.reason) {
314
341
  templateMeta.reason = profileDecision.reason;
@@ -318,6 +345,7 @@ export async function startBugfix(args, context) {
318
345
  }
319
346
  const headerNotes = [
320
347
  `模板档位: ${profileDecision.resolved}${profileDecision.requested === 'auto' ? '(自动)' : ''}`,
348
+ `分析方法: ${analysisMode}`,
321
349
  ];
322
350
  if (profileDecision.reason) {
323
351
  headerNotes.push(`选择理由: ${profileDecision.reason}`);
@@ -326,32 +354,52 @@ export async function startBugfix(args, context) {
326
354
  headerNotes.push(profileDecision.warning);
327
355
  }
328
356
  throwIfAborted(context?.signal, "start_bugfix 已取消");
329
- await reportToolProgress(context, 55, "start_bugfix: 获取代码图谱上下文");
357
+ await reportToolProgress(context, 55, "start_bugfix: 刷新图谱并收敛问题范围");
358
+ const graphDocs = {
359
+ latestMarkdownPath: "docs/graph-insights/latest.md",
360
+ latestJsonPath: "docs/graph-insights/latest.json",
361
+ };
362
+ const resolvedProjectRoot = path.resolve(projectRoot || process.cwd());
363
+ const bootstrapState = {
364
+ projectContextExists: fs.existsSync(path.join(resolvedProjectRoot, "docs", "project-context.md")),
365
+ latestMarkdownExists: fs.existsSync(path.join(resolvedProjectRoot, "docs", "graph-insights", "latest.md")),
366
+ latestJsonExists: fs.existsSync(path.join(resolvedProjectRoot, "docs", "graph-insights", "latest.json")),
367
+ };
368
+ const graphDocsMissing = !bootstrapState.latestMarkdownExists || !bootstrapState.latestJsonExists;
330
369
  const graphContext = await buildBugfixGraphContext({
331
370
  errorMessage,
332
371
  stackTrace,
372
+ projectRoot: projectRoot || undefined,
333
373
  signal: context?.signal,
334
374
  });
335
375
  const graphStatusNote = graphContext.available
336
- ? `图谱增强: 可用(${graphContext.mode})`
337
- : "图谱增强: 已降级(自动回退)";
376
+ ? `任务图谱收敛: 可用(${graphContext.mode})`
377
+ : "任务图谱收敛: 已降级(自动回退)";
338
378
  headerNotes.push(graphStatusNote);
339
- const graphCodeContext = graphContext.available
340
- ? [
341
- `图谱摘要: ${graphContext.summary}`,
342
- ...graphContext.highlights.slice(0, 3).map((item) => `图谱线索: ${item}`),
343
- ]
344
- .filter(Boolean)
345
- .join("\n")
346
- : "";
379
+ const graphCodeContext = [
380
+ codeContext,
381
+ `如存在 ${graphDocs.latestMarkdownPath},请一并参考其中的调用链、依赖关系和影响面摘要`,
382
+ ...(graphContext.available
383
+ ? [
384
+ graphContext.summary ? `任务图谱摘要: ${graphContext.summary}` : "",
385
+ ...graphContext.highlights.slice(0, 3).map((item) => `任务图谱线索: ${item}`),
386
+ ]
387
+ : []),
388
+ ]
389
+ .filter(Boolean)
390
+ .join("\n\n");
347
391
  const graphGuideSection = `
348
392
 
349
- ## 🧠 代码图谱上下文(可选增强)
350
- - 状态: ${graphContext.available ? "可用" : "降级"}
351
- - 摘要: ${graphContext.summary}
393
+ ## 🧠 代码图谱上下文
394
+ - 基线入口: ${graphDocs.latestMarkdownPath}
395
+ - 基线结构化副本: ${graphDocs.latestJsonPath}
396
+ - 基线状态: ${graphDocsMissing ? "缺失(需要补初始化)" : "可用"}
397
+ - 任务级收敛: ${graphContext.available ? "可用" : "降级"}
398
+ - 任务级摘要: ${graphContext.summary}
352
399
  ${graphContext.highlights.length > 0
353
- ? `- 线索:\n${graphContext.highlights.slice(0, 3).map((item) => ` - ${item}`).join("\n")}`
354
- : "- 线索: 无"}
400
+ ? `- 任务级线索:\n${graphContext.highlights.slice(0, 3).map((item) => ` - ${item}`).join("\n")}`
401
+ : "- 任务级线索: 无"}
402
+ - 使用方式: 先读取基线图谱,再用本次任务图谱做 TBP-4 / TBP-5 / TBP-6 的边界与真因收敛
355
403
  `;
356
404
  if (requirementsMode === "loop") {
357
405
  throwIfAborted(context?.signal, "start_bugfix(loop) 已取消");
@@ -381,9 +429,13 @@ ${graphContext.highlights.length > 0
381
429
  {
382
430
  id: 'context',
383
431
  tool: 'init_project_context',
384
- when: '缺少 docs/project-context.md',
385
- args: { docs_dir: 'docs' },
386
- outputs: ['docs/project-context.md'],
432
+ when: `缺少 docs/project-context.md 或 ${graphDocs.latestMarkdownPath} / ${graphDocs.latestJsonPath}`,
433
+ args: {
434
+ docs_dir: 'docs',
435
+ ...(projectRoot ? { project_root: projectRoot } : {}),
436
+ },
437
+ outputs: ['docs/project-context.md', graphDocs.latestMarkdownPath, graphDocs.latestJsonPath],
438
+ note: `兼容老项目:如果旧项目没有 graph-insights/latest.*,先补齐图谱初始化再进入 bug 收敛`,
387
439
  },
388
440
  {
389
441
  id: 'loop-1',
@@ -409,6 +461,7 @@ ${graphContext.highlights.length > 0
409
461
  args: {
410
462
  error_message: errorMessage,
411
463
  ...(stackTrace ? { stack_trace: stackTrace } : {}),
464
+ analysis_mode: analysisMode,
412
465
  ...(graphCodeContext ? { code_context: graphCodeContext } : {}),
413
466
  },
414
467
  outputs: [],
@@ -439,6 +492,7 @@ ${graphContext.highlights.length > 0
439
492
  : LOOP_PROMPT_TEMPLATE_GUIDED;
440
493
  const guide = (header + loopTemplate
441
494
  .replace(/{error_message}/g, errorMessage)
495
+ .replace(/{analysis_mode}/g, analysisMode)
442
496
  .replace(/{question_budget}/g, String(questionBudget))
443
497
  .replace(/{assumption_cap}/g, String(assumptionCap)))
444
498
  + graphGuideSection;
@@ -468,6 +522,11 @@ ${graphContext.highlights.length > 0
468
522
  metadata: {
469
523
  plan,
470
524
  template: templateMeta,
525
+ graphDocs,
526
+ bootstrapState: {
527
+ ...bootstrapState,
528
+ graphDocsMissing,
529
+ },
471
530
  graphContext,
472
531
  },
473
532
  };
@@ -495,6 +554,7 @@ ${graphContext.highlights.length > 0
495
554
  const guide = (header + promptTemplate
496
555
  .replace(/{error_message}/g, errorMessage)
497
556
  .replace(/{stack_trace}/g, stackTrace)
557
+ .replace(/{analysis_mode}/g, analysisMode)
498
558
  .replace(/{stack_trace_section}/g, stackTraceSection))
499
559
  + graphGuideSection;
500
560
  const plan = {
@@ -503,9 +563,13 @@ ${graphContext.highlights.length > 0
503
563
  {
504
564
  id: 'context',
505
565
  tool: 'init_project_context',
506
- when: '缺少 docs/project-context.md',
507
- args: { docs_dir: 'docs' },
508
- outputs: ['docs/project-context.md'],
566
+ when: `缺少 docs/project-context.md 或 ${graphDocs.latestMarkdownPath} / ${graphDocs.latestJsonPath}`,
567
+ args: {
568
+ docs_dir: 'docs',
569
+ ...(projectRoot ? { project_root: projectRoot } : {}),
570
+ },
571
+ outputs: ['docs/project-context.md', graphDocs.latestMarkdownPath, graphDocs.latestJsonPath],
572
+ note: `兼容老项目:如果旧项目没有 graph-insights/latest.*,先补齐图谱初始化再进入 bug 收敛`,
509
573
  },
510
574
  {
511
575
  id: 'fix',
@@ -513,6 +577,7 @@ ${graphContext.highlights.length > 0
513
577
  args: {
514
578
  error_message: errorMessage,
515
579
  ...(stackTrace ? { stack_trace: stackTrace } : {}),
580
+ analysis_mode: analysisMode,
516
581
  ...(graphCodeContext ? { code_context: graphCodeContext } : {}),
517
582
  },
518
583
  outputs: [],
@@ -532,11 +597,12 @@ ${graphContext.highlights.length > 0
532
597
  const bugfixReport = {
533
598
  summary: `Bug 修复工作流:${errorMessage.substring(0, 50)}${errorMessage.length > 50 ? '...' : ''}`,
534
599
  status: 'pending',
600
+ analysisMode,
535
601
  steps: [
536
602
  {
537
603
  name: '检查项目上下文',
538
604
  status: 'pending',
539
- description: '检查 docs/project-context.md 是否存在,如不存在则调用 init_project_context',
605
+ description: '检查 docs/project-context.md graph-insights/latest.* 是否存在,缺失则调用 init_project_context',
540
606
  },
541
607
  {
542
608
  name: 'Bug 分析与修复',
@@ -552,7 +618,11 @@ ${graphContext.highlights.length > 0
552
618
  artifacts: [],
553
619
  nextSteps: [
554
620
  '检查并读取项目上下文文档',
555
- '调用 fix_bug 工具分析和修复问题',
621
+ `如果缺少 ${graphDocs.latestMarkdownPath} / ${graphDocs.latestJsonPath},先调用 init_project_context 补齐图谱初始化`,
622
+ `优先读取 ${graphDocs.latestMarkdownPath} 获取调用链、依赖和影响面摘要`,
623
+ '结合本次任务图谱线索收敛问题边界,避免扩大改动面',
624
+ '按 TBP-1~TBP-7 完成真因分析',
625
+ '调用 fix_bug 工具分析问题并形成因果句真因',
556
626
  '调用 gentest 工具生成回归测试',
557
627
  '运行测试验证修复',
558
628
  ],
@@ -560,9 +630,39 @@ ${graphContext.highlights.length > 0
560
630
  fixPlan: '待制定(需要调用 fix_bug 工具)',
561
631
  testPlan: '待生成(需要调用 gentest 工具)',
562
632
  affectedFiles: [],
633
+ tbp: {
634
+ phenomenon: `待确认:${errorMessage}`,
635
+ timeline: [
636
+ { order: 1, event: '收到用户错误描述', evidence: errorMessage },
637
+ ...(stackTrace ? [{ order: 2, event: '收到堆栈信息', evidence: stackTrace }] : []),
638
+ ],
639
+ ruledOut: [],
640
+ commonPattern: '待通过成功/失败样本对比确认分叉点',
641
+ boundary: '待定位(优先检查状态机、工具执行层、文件系统、环境配置)',
642
+ rootCauseStatement: '待形成 “A + B 在条件 D 下导致 C” 的因果句',
643
+ evidence: [
644
+ { type: 'symptom', detail: errorMessage, source: 'error_message' },
645
+ ...(stackTrace ? [{ type: 'stack', detail: stackTrace, source: 'stack_trace' }] : []),
646
+ ...(graphCodeContext ? [{ type: 'graph', detail: graphCodeContext, source: 'graph_context' }] : []),
647
+ ],
648
+ repair: [
649
+ {
650
+ layer: 'analysis',
651
+ action: '先完成 TBP 1-7 取证与真因闭合,再进入修复',
652
+ risk: '若直接改代码,容易补症状而非修真因',
653
+ verification: '检查真因是否能解释全部关键现象并排除竞争假设',
654
+ },
655
+ ],
656
+ },
563
657
  metadata: {
564
658
  plan,
565
659
  template: templateMeta,
660
+ analysisMode,
661
+ graphDocs,
662
+ bootstrapState: {
663
+ ...bootstrapState,
664
+ graphDocsMissing,
665
+ },
566
666
  graphContext,
567
667
  },
568
668
  };