cgraphx 1.1.0 → 1.3.0

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 (201) hide show
  1. package/README.md +0 -1
  2. package/dist/.claude-template/hooks/precommit-check/precommit-check.cjs +90 -0
  3. package/dist/.claude-template/skills/cgraphx/SKILL.md +3 -3
  4. package/dist/.claude-template/skills/cgraphx/agent-prompt.md +1 -1
  5. package/dist/.claude-template/skills/cgraphx-guide/SKILL.md +94 -0
  6. package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +424 -0
  7. package/dist/.claude-template/skills/clarify-requirements/SKILL.md +19 -8
  8. package/dist/.claude-template/skills/code-impact-docgen/SKILL.md +186 -176
  9. package/dist/.claude-template/skills/code-impact-docgen/template-design-html.md +357 -0
  10. package/dist/.claude-template/skills/code-impact-docgen/template-design-md.md +164 -0
  11. package/dist/.claude-template/skills/code-impact-init/SKILL.md +47 -47
  12. package/dist/.claude-template/skills/developer-timeline/SKILL.md +9 -0
  13. package/dist/.claude-template/skills/precommit-review/SKILL.md +50 -0
  14. package/dist/.claude-template/skills/run-api-test/SKILL.md +187 -0
  15. package/dist/.claude-template/skills/run-api-test/assets/template-test-report.md +103 -0
  16. package/dist/.claude-template/skills/run-api-test/assets/template-test-verify.jsonl +5 -0
  17. package/dist/.claude-template/skills/run-api-test/references/bru-run.md +60 -0
  18. package/dist/.claude-template/skills/run-api-test/references/db-verification.md +81 -0
  19. package/dist/.claude-template/skills/run-api-test/references/report-format.md +104 -0
  20. package/dist/.claude-template/skills/run-api-test/references/service-readiness.md +61 -0
  21. package/dist/.claude-template/skills/run-api-test/references/test-scope.md +64 -0
  22. package/dist/.claude-template/skills/write-api/SKILL.md +150 -0
  23. package/dist/.claude-template/skills/write-api/assets/template-api-spec.md +112 -0
  24. package/dist/.claude-template/skills/write-api/assets/template-request.bru +75 -0
  25. package/dist/.claude-template/skills/write-api/references/ai-prompts.md +133 -0
  26. package/dist/.claude-template/skills/write-api/references/api-spec-format.md +108 -0
  27. package/dist/.claude-template/skills/write-api/references/bru-format.md +144 -0
  28. package/dist/.claude-template/skills/write-api/references/collection-layout.md +81 -0
  29. package/dist/.claude-template/skills/write-api/references/environment-setup.md +105 -0
  30. package/dist/.claude-template/skills/write-api/references/interface-scope.md +74 -0
  31. package/dist/.claude-template/skills/write-api-doc/SKILL.md +317 -0
  32. package/dist/.claude-template/skills/write-api-doc/template-api-html.md +422 -0
  33. package/dist/.claude-template/skills/write-plan/SKILL.md +38 -16
  34. package/dist/.claude-template/skills/write-prd/SKILL.md +32 -8
  35. package/dist/.claude-template/skills/write-spec/SKILL.md +34 -9
  36. package/dist/api-test/ai-fields.d.ts +37 -0
  37. package/dist/api-test/ai-fields.d.ts.map +1 -0
  38. package/dist/api-test/ai-fields.js +114 -0
  39. package/dist/api-test/ai-fields.js.map +1 -0
  40. package/dist/api-test/assemble.d.ts +76 -0
  41. package/dist/api-test/assemble.d.ts.map +1 -0
  42. package/dist/api-test/assemble.js +185 -0
  43. package/dist/api-test/assemble.js.map +1 -0
  44. package/dist/api-test/bru-cli-invoker.d.ts +72 -0
  45. package/dist/api-test/bru-cli-invoker.d.ts.map +1 -0
  46. package/dist/api-test/bru-cli-invoker.js +169 -0
  47. package/dist/api-test/bru-cli-invoker.js.map +1 -0
  48. package/dist/api-test/bru-report-parser.d.ts +24 -0
  49. package/dist/api-test/bru-report-parser.d.ts.map +1 -0
  50. package/dist/api-test/bru-report-parser.js +110 -0
  51. package/dist/api-test/bru-report-parser.js.map +1 -0
  52. package/dist/api-test/bru-runner.d.ts +101 -0
  53. package/dist/api-test/bru-runner.d.ts.map +1 -0
  54. package/dist/api-test/bru-runner.js +316 -0
  55. package/dist/api-test/bru-runner.js.map +1 -0
  56. package/dist/api-test/bru-writer.d.ts +52 -0
  57. package/dist/api-test/bru-writer.d.ts.map +1 -0
  58. package/dist/api-test/bru-writer.js +159 -0
  59. package/dist/api-test/bru-writer.js.map +1 -0
  60. package/dist/api-test/call-chain-extractor.d.ts +80 -0
  61. package/dist/api-test/call-chain-extractor.d.ts.map +1 -0
  62. package/dist/api-test/call-chain-extractor.js +179 -0
  63. package/dist/api-test/call-chain-extractor.js.map +1 -0
  64. package/dist/api-test/cli.d.ts +133 -0
  65. package/dist/api-test/cli.d.ts.map +1 -0
  66. package/dist/api-test/cli.js +1009 -0
  67. package/dist/api-test/cli.js.map +1 -0
  68. package/dist/api-test/config.d.ts +75 -0
  69. package/dist/api-test/config.d.ts.map +1 -0
  70. package/dist/api-test/config.js +406 -0
  71. package/dist/api-test/config.js.map +1 -0
  72. package/dist/api-test/db-query-cli.d.ts +51 -0
  73. package/dist/api-test/db-query-cli.d.ts.map +1 -0
  74. package/dist/api-test/db-query-cli.js +119 -0
  75. package/dist/api-test/db-query-cli.js.map +1 -0
  76. package/dist/api-test/enhance-prepare.d.ts +111 -0
  77. package/dist/api-test/enhance-prepare.d.ts.map +1 -0
  78. package/dist/api-test/enhance-prepare.js +425 -0
  79. package/dist/api-test/enhance-prepare.js.map +1 -0
  80. package/dist/api-test/enhance-write.d.ts +28 -0
  81. package/dist/api-test/enhance-write.d.ts.map +1 -0
  82. package/dist/api-test/enhance-write.js +145 -0
  83. package/dist/api-test/enhance-write.js.map +1 -0
  84. package/dist/api-test/errors.d.ts +48 -0
  85. package/dist/api-test/errors.d.ts.map +1 -0
  86. package/dist/api-test/errors.js +76 -0
  87. package/dist/api-test/errors.js.map +1 -0
  88. package/dist/api-test/field-extractor.d.ts +98 -0
  89. package/dist/api-test/field-extractor.d.ts.map +1 -0
  90. package/dist/api-test/field-extractor.js +327 -0
  91. package/dist/api-test/field-extractor.js.map +1 -0
  92. package/dist/api-test/impl-finder.d.ts +37 -0
  93. package/dist/api-test/impl-finder.d.ts.map +1 -0
  94. package/dist/api-test/impl-finder.js +54 -0
  95. package/dist/api-test/impl-finder.js.map +1 -0
  96. package/dist/api-test/index.d.ts +41 -0
  97. package/dist/api-test/index.d.ts.map +1 -0
  98. package/dist/api-test/index.js +124 -0
  99. package/dist/api-test/index.js.map +1 -0
  100. package/dist/api-test/java-parser.d.ts +89 -0
  101. package/dist/api-test/java-parser.d.ts.map +1 -0
  102. package/dist/api-test/java-parser.js +508 -0
  103. package/dist/api-test/java-parser.js.map +1 -0
  104. package/dist/api-test/md-writer.d.ts +49 -0
  105. package/dist/api-test/md-writer.d.ts.map +1 -0
  106. package/dist/api-test/md-writer.js +202 -0
  107. package/dist/api-test/md-writer.js.map +1 -0
  108. package/dist/api-test/parser-httpservice.d.ts +91 -0
  109. package/dist/api-test/parser-httpservice.d.ts.map +1 -0
  110. package/dist/api-test/parser-httpservice.js +271 -0
  111. package/dist/api-test/parser-httpservice.js.map +1 -0
  112. package/dist/api-test/report.d.ts +188 -0
  113. package/dist/api-test/report.d.ts.map +1 -0
  114. package/dist/api-test/report.js +522 -0
  115. package/dist/api-test/report.js.map +1 -0
  116. package/dist/api-test/snapshot.d.ts +26 -0
  117. package/dist/api-test/snapshot.d.ts.map +1 -0
  118. package/dist/api-test/snapshot.js +150 -0
  119. package/dist/api-test/snapshot.js.map +1 -0
  120. package/dist/api-test/test-history.d.ts +48 -0
  121. package/dist/api-test/test-history.d.ts.map +1 -0
  122. package/dist/api-test/test-history.js +122 -0
  123. package/dist/api-test/test-history.js.map +1 -0
  124. package/dist/api-test/types.d.ts +174 -0
  125. package/dist/api-test/types.d.ts.map +1 -0
  126. package/dist/api-test/types.js +13 -0
  127. package/dist/api-test/types.js.map +1 -0
  128. package/dist/api-test/verify-prepare.d.ts +30 -0
  129. package/dist/api-test/verify-prepare.d.ts.map +1 -0
  130. package/dist/api-test/verify-prepare.js +150 -0
  131. package/dist/api-test/verify-prepare.js.map +1 -0
  132. package/dist/api-test/verify-write.d.ts +31 -0
  133. package/dist/api-test/verify-write.d.ts.map +1 -0
  134. package/dist/api-test/verify-write.js +159 -0
  135. package/dist/api-test/verify-write.js.map +1 -0
  136. package/dist/bin/codegraph.js +0 -100
  137. package/dist/bin/codegraph.js.map +1 -1
  138. package/dist/dbquery/dump-schema.d.ts +46 -0
  139. package/dist/dbquery/dump-schema.d.ts.map +1 -0
  140. package/dist/dbquery/dump-schema.js +379 -0
  141. package/dist/dbquery/dump-schema.js.map +1 -0
  142. package/dist/installer/targets/claude.d.ts +15 -0
  143. package/dist/installer/targets/claude.d.ts.map +1 -1
  144. package/dist/installer/targets/claude.js +53 -0
  145. package/dist/installer/targets/claude.js.map +1 -1
  146. package/dist/resolution/index.d.ts.map +1 -1
  147. package/dist/resolution/index.js +13 -0
  148. package/dist/resolution/index.js.map +1 -1
  149. package/dist/resolution/scope-index.d.ts +86 -0
  150. package/dist/resolution/scope-index.d.ts.map +1 -0
  151. package/dist/resolution/scope-index.js +143 -0
  152. package/dist/resolution/scope-index.js.map +1 -0
  153. package/dist/resolution/stdlib-blocklist.d.ts +53 -0
  154. package/dist/resolution/stdlib-blocklist.d.ts.map +1 -0
  155. package/dist/resolution/stdlib-blocklist.js +143 -0
  156. package/dist/resolution/stdlib-blocklist.js.map +1 -0
  157. package/dist/search/ast-helpers.d.ts +42 -0
  158. package/dist/search/ast-helpers.d.ts.map +1 -0
  159. package/dist/search/ast-helpers.js +106 -0
  160. package/dist/search/ast-helpers.js.map +1 -0
  161. package/dist/search/call-sites.d.ts +398 -0
  162. package/dist/search/call-sites.d.ts.map +1 -0
  163. package/dist/search/call-sites.js +1433 -0
  164. package/dist/search/call-sites.js.map +1 -0
  165. package/dist/search/context.d.ts +134 -0
  166. package/dist/search/context.d.ts.map +1 -0
  167. package/dist/search/context.js +575 -0
  168. package/dist/search/context.js.map +1 -0
  169. package/dist/search/impact.d.ts +139 -0
  170. package/dist/search/impact.d.ts.map +1 -0
  171. package/dist/search/impact.js +646 -0
  172. package/dist/search/impact.js.map +1 -0
  173. package/dist/search/related.d.ts +178 -0
  174. package/dist/search/related.d.ts.map +1 -0
  175. package/dist/search/related.js +667 -0
  176. package/dist/search/related.js.map +1 -0
  177. package/dist/search/slice.d.ts +148 -0
  178. package/dist/search/slice.d.ts.map +1 -0
  179. package/dist/search/slice.js +460 -0
  180. package/dist/search/slice.js.map +1 -0
  181. package/dist/search/snr-constants.d.ts +41 -0
  182. package/dist/search/snr-constants.d.ts.map +1 -0
  183. package/dist/search/snr-constants.js +44 -0
  184. package/dist/search/snr-constants.js.map +1 -0
  185. package/dist/search/types.d.ts +28 -0
  186. package/dist/search/types.d.ts.map +1 -0
  187. package/dist/search/types.js +12 -0
  188. package/dist/search/types.js.map +1 -0
  189. package/dist/timeline/cli.d.ts.map +1 -1
  190. package/dist/timeline/cli.js +22 -3
  191. package/dist/timeline/cli.js.map +1 -1
  192. package/dist/timeline/store.d.ts +5 -0
  193. package/dist/timeline/store.d.ts.map +1 -1
  194. package/dist/timeline/store.js +23 -3
  195. package/dist/timeline/store.js.map +1 -1
  196. package/package.json +1 -1
  197. package/scripts/agent-eval/subagent-token-cost.py +188 -0
  198. package/dist/.claude-template/skills/code-impact-docgen/template-business-html.md +0 -242
  199. package/dist/.claude-template/skills/code-impact-docgen/template-business-md.md +0 -107
  200. package/dist/.claude-template/skills/code-impact-docgen/template-technical-html.md +0 -205
  201. package/dist/.claude-template/skills/code-impact-docgen/template-technical-md.md +0 -155
@@ -9,7 +9,7 @@ Automated project exploration skill. Discovers entry points, explores each in de
9
9
 
10
10
  **Dependencies:**
11
11
  - `code-impact-markdown` skill must be installed in the same project(沉淀业务理解到 `docs/knowledge/*.md`)
12
- - cgraphx 已 `init` 的项目索引(提供代码结构事实:symbols / 调用链 / impact)。优先通过 `codegraph_explore` MCP 工具,不可用时走 Bash CLI(`cgraphx query` / `cgraphx callers` / `cgraphx callees` / `cgraphx impact` / `cgraphx affected`)。两者都不可用时降级为 grep 模式(精度损失,详见各 Phase 的 fallback 说明)
12
+ - cgraphx 已 `init` 的项目索引(提供代码结构事实:symbols / 调用链 / impact)。优先通过 `codegraph_explore` / `codegraph_impact` / `codegraph_node` 等 MCP 工具,不可用时走 Bash CLI(`cgraphx query` / `cgraphx callers` / `cgraphx callees` / `cgraphx affected`)。两者都不可用时降级为 grep 模式(精度损失,详见各 Phase 的 fallback 说明)
13
13
 
14
14
  ## Trigger
15
15
 
@@ -98,9 +98,9 @@ code-impact-init 协调 cgraphx 的**两个互补子系统**:
98
98
 
99
99
  ```
100
100
  Phase 1 Step 1.5: cgraphx init(一次性,几分钟,建代码图谱)
101
- Phase 1-2: 查询用 cgraphx query / callers / callees / impact / affected(毫秒级,子 agent 主用)
101
+ Phase 1-2: 查询用 cgraphx query / callers / callees / affected CLI,或 codegraph_explore / codegraph_impact / codegraph_node MCP(毫秒级,子 agent 主用)
102
102
  Phase 2 末尾: cgraphx docs index(同步子 agent 写的 .md 到知识图谱)
103
- Phase 3 Step 1: cgraphx impact 找高中心性 symbols
103
+ Phase 3 Step 1: 【已 deprecated — 原 cgraphx impact CLI 已去除】用 codegraph_impact MCP 主观评估影响面,或等阶段 2 gitnexus impact 工具
104
104
  Phase 3 Step 2: cgraphx docs concepts --sort=doc-count 找高中心性 concepts
105
105
  Phase 3 Step 3: 交叉验证 → cross-cutting pending
106
106
  Phase 3 末尾: cgraphx docs index(同步 Phase 3 文档)
@@ -466,49 +466,50 @@ Time →
466
466
  - 每批次跑 = 累计 N 批次 × 单次耗时,几天到几周
467
467
  - 根本解是 markdown 知识库做增量 index endpoint(P0 #1,留作下一轮)
468
468
 
469
- ### Phase 3: Cross-cutting Deep-dive(基于 cgraphx impact + cgraphx docs concepts 交叉)
469
+ ### Phase 3: Cross-cutting Deep-dive(基于 codegraph_impact MCP + cgraphx docs concepts 交叉)
470
470
 
471
- **核心思路**:cross-cutting concern = **代码层面被多个 entry 依赖的高中心性 symbol**(`cgraphx impact` `nodeCount` 测量)+ **业务层面已被多文档提及但无专属文档的 concept**(`cgraphx docs concepts --sort=doc-count` 测量)。两者交叉验证,比单纯靠 markdown concept 频率更准——concept markdown 里出现可能是子 agent 主观判断,cgraphx impact 是代码事实。
471
+ > **【2026-07-05 deprecated notice】** 原Phase 3 依赖 `cgraphx impact <symbol> --json` CLI 返回 `{nodeCount, edgeCount, affected[]}` 用于脚本循环 + 数值排序。该 CLI 在阶段 1 已去除(实测无法替代 MCP)。当前替代:
472
+ > - **代码层面找高中心性 symbol** — 用 `codegraph_impact(symbol)` MCP 工具,从返回的格式化报告里**主观评估**影响面广度(返回文本包含 affected symbols 列表 + 树状结构,agent 看大小估计中心性)
473
+ > - **完整 nodeCount 排序机制** — 等阶段 2 gitnexus 内核迁入后,用 gitnexus 的 `impact` 工具(基于 KuzuDB + Cypher,支持结构化返回)
474
+ > - Phase 3 的"交叉验证"思路仍然有效,只是代码层面从"机器排序"降级为"agent 主观判断"
472
475
 
473
- **Step 1 代码层面:找高中心性 symbols(cgraphx impact nodeCount)**
476
+ **核心思路**:cross-cutting concern = **代码层面被多个 entry 依赖的高中心性 symbol**(`codegraph_impact` MCP 评估)+ **业务层面已被多文档提及但无专属文档的 concept**(`cgraphx docs concepts --sort=doc-count` 测量)。两者交叉验证,比单纯靠 markdown concept 频率更准——concept 在 markdown 里出现可能是子 agent 主观判断,codegraph_impact 是代码事实。
474
477
 
475
- `cgraphx impact <symbol> --json` 返回 `{ symbol, depth, nodeCount, edgeCount, affected[] }`。**`nodeCount` 是中心性指标**——影响半径内的节点数,数字越大中心性越高。
478
+ **Step 1 代码层面:找高中心性 symbols(codegraph_impact MCP 主观评估)**
476
479
 
477
- ```bash
478
- CODEGRAPH="cgraphx"
479
-
480
- # 1. 从 docs/knowledge/*.md frontmatter related_code 提取 symbol 列表
481
- # related_code 可能是文件路径或 symbol 名,两种都收
482
- SYMBOLS=$(for f in docs/knowledge/*.md; do
483
- awk '/^---$/{c++; next} c==1 && /^related_code:/{flag=1; next} flag && /^ - /{gsub(/^ - /,""); print}' "$f"
484
- done | sort -u)
480
+ `codegraph_impact(symbol, depth)` MCP 返回该 symbol 的影响半径报告(affected symbols list + 树状结构 + 统计)。agent 看返回报告的**规模**(涉及的文件数 / 模块数 / 跨服务 hop 数)主观判断中心性。
485
481
 
486
- # 2. 对每个 symbol 跑 impact,按 nodeCount(中心性指标)排序
487
- TMP=$(mktemp)
488
- while IFS= read -r sym; do
489
- [ -z "$sym" ] && continue
490
- $CODEGRAPH impact "$sym" --json 2>/dev/null \
491
- | jq -r --arg sym "$sym" '[.nodeCount // 0, $sym] | @tsv' >> "$TMP"
492
- done <<< "$SYMBOLS"
493
-
494
- # 3. 取 top 30
495
- sort -t$'\t' -k1 -rn "$TMP" | head -30 > high-centrality-symbols.txt
496
- rm -f "$TMP"
482
+ **MCP 调用路径**(取代原 shell 循环):
483
+ ```
484
+ 对每个 Phase 2 探索到的 entry symbol:
485
+ 调用 codegraph_impact(symbol, depth=2) MCP
486
+ 看返回报告里 affected symbols 的数量 + 跨文件 / 跨模块分布
487
+ 主观标记"高中心性 / 中中心性 / 低中心性"
488
+ 取高中心性 top 30 作为 Phase 3 deep-dive 候选
489
+ ```
497
490
 
498
- cat high-centrality-symbols.txt
491
+ **原 shell 脚本路径(已废弃,留作历史参考)**:
492
+ ```bash
493
+ # 原 cgraphx impact CLI 已去除,以下脚本不工作,仅作历史参考
494
+ # CODEGRAPH="cgraphx"
495
+ # while IFS= read -r sym; do
496
+ # $CODEGRAPH impact "$sym" --json 2>/dev/null \
497
+ # | jq -r --arg sym "$sym" '[.nodeCount // 0, $sym] | @tsv' >> "$TMP"
498
+ # done <<< "$SYMBOLS"
499
+ # sort -t$'\t' -k1 -rn "$TMP" | head -30 > high-centrality-symbols.txt
499
500
  ```
500
501
 
501
502
  **注释说明**:
502
- - `cgraphx impact <symbol> --json` 输出 `{symbol, depth, nodeCount, edgeCount, affected[]}`
503
- - **`nodeCount` 是中心性指标**(影响半径内的节点数,数字越大中心性越高)
504
- - 如果 `related_code` 字段是文件路径而不是 symbol,需要先 `cgraphx query --kind=function --kind=method` 在该文件下找 symbol,再跑 impact
503
+ - ~~`cgraphx impact <symbol> --json` 输出 `{symbol, depth, nodeCount, edgeCount, affected[]}`~~(CLI 已去除)
504
+ - **替代**:`codegraph_impact(symbol)` MCP 返回格式化影响半径报告,agent 主观评估规模
505
+ - 如果 `related_code` 字段是文件路径而不是 symbol,需要先 `cgraphx query --kind=function --kind=method` 在该文件下找 symbol,再调 codegraph_impact MCP
505
506
 
506
- **MCP 优先路径**(可选):
507
- > 把 Phase 2 探索到的 entry symbols 喂给 `codegraph_explore` MCP 工具,一次性返回各符号的 impact 信息。比 shell 循环 + 文件拼接快得多,而且 agent 能直接看结构化结果做判断。
507
+ **MCP 调用优势**:
508
+ > 把 Phase 2 探索到的 entry symbols 喂给 `codegraph_impact` MCP 工具,agent 直接看结构化结果做判断,比 shell 循环 + 文件拼接更直接。
508
509
 
509
- **为什么这么设计**:cgraphx `impact nodeCount` 排序找中心性,不需要 cypher 接口。
510
+ **为什么这么设计**:用 `codegraph_impact` MCP 评估中心性,不需要 cypher 接口;等阶段 2 gitnexus 内核迁入后可升级到结构化 nodeCount 排序。
510
511
 
511
- 被多个 entry 依赖的 symbol 就是代码层面的 cross-cutting concern(如业务项目的 OrderService、PaymentGateway、AuthMiddleware——它们的 `nodeCount` 远高于工具类)。
512
+ 被多个 entry 依赖的 symbol 就是代码层面的 cross-cutting concern(如业务项目的 OrderService、PaymentGateway、AuthMiddleware——它们的影响半径远大于工具类)。
512
513
 
513
514
  **Step 2 — 业务层面:找高中心性 concepts(cgraphx docs concepts)**
514
515
 
@@ -537,10 +538,10 @@ jq '[.[] | {name, doc_count: .documentCount}] | sort_by(-.doc_count) | .[:30]' \
537
538
  对每个 cross-cutting concern 创建 pending item:
538
539
  - `type: "cross_cutting_concept"`
539
540
  - `entry_symbol`: 高中心性 symbol
540
- - `entry_files`: `cgraphx impact <symbol> --json` 输出的 `affected[].filePath`
541
+ - `entry_files`: `codegraph_impact(<symbol>)` MCP 报告里 affected symbols 的 `filePath`
541
542
  - `related_documents`: markdown 知识库里连接到该 concept 的已有文档路径
542
543
 
543
- 跑 Phase 2 探索循环,但用下方的 **Cross-cutting Sub-Agent Template**(强调基于 `cgraphx impact` + 已有文档整合,不重读代码)。
544
+ 跑 Phase 2 探索循环,但用下方的 **Cross-cutting Sub-Agent Template**(强调基于 `codegraph_impact` MCP + 已有文档整合,不重读代码)。
544
545
 
545
546
  **Step 5 — Finalize**
546
547
 
@@ -686,7 +687,7 @@ $CODEGRAPH docs find --q="{name}" --limit=5 --json
686
687
  1. 从起始符号开始,用 cgraphx 拿完整调用链:
687
688
  - 跟踪函数调用链(至少 4-5 层深度,用 `cgraphx callers` / `cgraphx callees`)
688
689
  - 识别数据模型、状态转换、错误处理路径(cgraphx 给位置,Read 看实现)
689
- - 关注跨模块/跨文件的依赖关系(用 `cgraphx impact {entry_symbol} --json` affected[])
690
+ - 关注跨模块/跨文件的依赖关系(用 `codegraph_impact({entry_symbol})` MCP 看影响半径 + affected symbols)
690
691
  - 记录外部服务调用(数据库、消息队列、HTTP 调用——通常在 callees 里)
691
692
 
692
693
  2. 识别业务概念和非显而易见的约束:
@@ -737,16 +738,15 @@ For Phase 3 deep-dive items with `type: "cross_cutting_concept"`:
737
738
  中心性 symbol:{entry_symbol}(被 N 个 entry 依赖的高中心性代码符号)
738
739
  关联已有文档(Read 这些):{document_paths}
739
740
 
740
- 【工具优先级:cgraphx impact > Read 已有文档 > Read 代码】
741
+ 【工具优先级:codegraph_impact MCP > Read 已有文档 > Read 代码】
741
742
 
742
- 1. **先看代码影响面**(cgraphx impact)—— 知道这个 symbol 在多少模块/调用链里出现:
743
+ 1. **先看代码影响面**(codegraph_impact MCP)—— 知道这个 symbol 在多少模块/调用链里出现:
743
744
 
744
- ```bash
745
- CODEGRAPH="cgraphx"
746
- # 拿完整 impact 看覆盖广度
747
- # 输出 {symbol, depth, nodeCount, edgeCount, affected[]}
748
- # nodeCount 作中心性,affected[] 看影响面涉及的文件/模块
749
- $CODEGRAPH impact {entry_symbol} --json
745
+ ```
746
+ # MCP 调用(取代原 cgraphx impact CLI)
747
+ # 返回格式化影响半径报告:affected symbols + 树状结构 + 跨文件 / 跨模块分布
748
+ # 用报告规模作中心性,涉及的文件/模块分布看影响面
749
+ 调用 codegraph_impact({entry_symbol}, depth=2) MCP
750
750
  ```
751
751
 
752
752
  2. **Read 关联已有文档**({document_paths})—— 知道业务层面已经记录了什么。
@@ -758,7 +758,7 @@ $CODEGRAPH impact {entry_symbol} --json
758
758
  项目名称:{project_name}
759
759
 
760
760
  【任务】
761
- 1. 用 cgraphx impact 输出构建"代码影响面":哪些模块/调用链依赖这个 symbol(看 `affected[]` 的 `filePath` 分布),跨多少文件/包,`nodeCount` 多大
761
+ 1. 用 codegraph_impact MCP 返回构建"代码影响面":哪些模块/调用链依赖这个 symbol(看报告中 affected symbols 的 `filePath` 分布),跨多少文件/包,规模多大
762
762
  2. 用已有文档({document_paths})构建"业务已知":业务侧如何描述这个 concept
763
763
  3. 找 gap:
764
764
  - 代码影响面 ≠ 业务已知 → 缺失视角(例:代码层面 OrderService 被 5 个模块调用,但业务文档只覆盖了 2 个)
@@ -775,7 +775,7 @@ document_type 建议:
775
775
 
776
776
  frontmatter:
777
777
  - related_documents 填引用的已有文档
778
- - related_code 填 cgraphx impact 输出 affected[] 里的高中心性文件
778
+ - related_code 填 codegraph_impact MCP 报告里 affected symbols 涉及的高中心性文件
779
779
  - concepts 填此核心 concept + 关联 concept
780
780
 
781
781
  完成后返回 JSON:
@@ -266,6 +266,15 @@ cgraphx timeline show <id>
266
266
  - ISO 8601:`2026-06-01` / `2026-06-01T00:00:00Z`
267
267
  - 相对:`7d` / `12h` / `30m` / `now`
268
268
 
269
+ **时区语义(重要)**:
270
+
271
+ - 所有 `ts` 字段存储为 UTC ISO。
272
+ - 日期字符串 `2026-06-01` 按**本地时区**解释(本地零点,不是 UTC 零点)。`--since=2026-06-01` 覆盖的是本地 6/1 全天,而非 UTC 6/1(后者在 UTC+N 时区会漏掉本地凌晨的工作)。
273
+ - `--format=table` 的 `ts(local)` 列、stats 的 `Window (local)` 行、`byDay` 按日分组 —— **全部按本地时区呈现**,直接是用户墙上时钟的时间,无需再做转换。
274
+ - `--format=json` 的 `ts` / `windowStart` / `windowEnd` **保留 UTC ISO**(带 `Z` 后缀)作为机器可读契约,程序消费时再自行转本地;只有 `byDay[].day` 是本地日期 `YYYY-MM-DD`(分组键,人看的)。
275
+
276
+ 生成 HTML 报告时,从 `--format=table` 拿到的时间已经是本地时间字符串,直接贴进 HTML 即可,不要把 UTC ISO 原样展示给用户。
277
+
269
278
  ### 输出选择
270
279
 
271
280
  - `table`:推荐给 agent 读,密度高。
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: precommit-review
3
+ description: 提交前审查 staged diff 的可疑修改。Use when 被 precommit-check hook 拦截后 / git commit 前审查 / 提交前自检 / 检查可疑修改 / 被注释的开关 / 未闭合逻辑 / 魔法字符串 / 临时标记。agent 自己跑 git diff --cached 逐项判断,不做脚本正则。
4
+ ---
5
+
6
+ ## 何时用
7
+
8
+ - precommit-check hook 拦截了你的 `git commit`,要求审查 → 立刻用本 skill
9
+ - 主动想在提交前自检可疑修改
10
+ - 任何"提交前再过一遍"的兜底场景
11
+
12
+ ## 你要做什么
13
+
14
+ 本 skill 不做脚本正则匹配 —— 你(agent)自己跑 git 命令拿 diff,逐项判断。
15
+
16
+ ### 步骤
17
+
18
+ 1. **列暂存文件**:`git diff --cached --name-status` —— 看哪些文件是 M/D/R(非纯新增)
19
+ 2. **拿实际改动**:`git diff --cached` —— 取 staged-vs-HEAD 的完整 diff
20
+ 3. **逐项审查**(下面清单),每命中一项就记下来
21
+ 4. **把发现讲给用户**,问是否放行
22
+ 5. 若干净或用户确认 → 用 `CGRAPHX_PRECOMMIT_REVIEWED=1 git commit ...` 重试提交(带这个 env 前缀,precommit-check hook 会放行)
23
+
24
+ ### 审查清单(逐项判断,不是正则)
25
+
26
+ - **被注释的开关**:新增的 `// @Component` / `// @Service` / `// @JmsListener` / `// @Scheduled` / `// @ConditionalOnProperty` / `// @Bean` / `// @EventListener` / `// @PostConstruct` 等。Spring 注解被注释 = bean 不加载 / 监听不触发 / 定时不跑 —— 高危,直击历史事故
27
+ - **被注释的业务调用**:新增的 `// executorService.submit(...)` / `// consumer.connect()` / `// consumer.listenTopic(...)` / `// consumeMessage(...)` / `// .start()` / `// .run()` 等。关键链路被注释 = 功能静默失效
28
+ - **未闭合的逻辑**:新增代码块括号失衡、`if`/`try`/`for` 没有配对的 `}`/`catch`/`)`、`return` 在不该断的地方 —— 编译器能抓多数,但看一眼补齐
29
+ - **写死的魔法字符串/数字**:可疑硬编码(密码、URL、ID、阈值)写死在代码里 —— 应抽常量
30
+ - **TODO/FIXME/临时/暂时**:新增行里带这些标记,确认是否应提交还是该当下处理掉
31
+
32
+ ### 判断原则
33
+
34
+ - 只看**本次新增的**改动(diff 里 `+` 开头的行),不看历史代码
35
+ - 命中任何一项都该 surface 给用户,让用户决定
36
+ - 不替用户改代码 —— 你只审查、报告、等指示
37
+
38
+ ## 输出格式
39
+
40
+ 把发现的每一项按 `文件:行号 + 类别 + 原文` 列给用户,例如:
41
+
42
+ ```
43
+ [关闭的开关] zqassis-service/.../CTGMQConsumerRunner.java:30
44
+ +//@Component ← bean 不再装载,确认是否有意
45
+
46
+ [被注释的业务调用] zqassis-service/.../CTGMQConsumerRunnerPull.java:49
47
+ +// executorService.submit(this::consumeMessage); ← 关键链路被关,确认是否有意
48
+ ```
49
+
50
+ 若一项都没命中,明说"未发现可疑修改",提示可用 `CGRAPHX_PRECOMMIT_REVIEWED=1 git commit ...` 提交。
@@ -0,0 +1,187 @@
1
+ ---
2
+ name: run-api-test
3
+ description: 在 write-api 生成 .bru 后,跑接口测试 + 核实写接口 DB 副作用 + 出报告。触发时由用户指定需求或接口:指定需求→跑该需求所有接口所有场景,报告归该需求目录;只指定接口→主动问测哪个需求(AI 反查 .bru docs 段关联需求列表让用户选);都没指定→主动问。服务未就绪暂停等待;写接口必须查 DB 验数据(HTTP 200 ≠ 通过);失败只报告不修代码不重跑,交用户决定。不调 write-api / write-api-doc,不改 .bru。Use when 用户要求跑接口测试 / 验证接口 / 测一下需求 X 的接口 / 跑下这个接口;write-api 跑完后用户要求执行测试;代码改完后用户想验证修复。
4
+ ---
5
+
6
+ # Run API Test
7
+
8
+ ## 定位
9
+
10
+ 打靶 skill:在 `write-api` 生成 `.bru` 之后,跑接口测试 + 核实写接口 DB 副作用 + 出报告。不改 .bru、不修代码、不重跑,失败交用户决定。
11
+
12
+ `write-api` 负责"造弹药",`run-api-test` 负责"打靶"。两者独立,同一份 .bru 可被多次复用(调整代码或断言后重跑)。
13
+
14
+ ## HARD-GATE
15
+
16
+ - **服务未就绪不盲跑** — 本地服务未起时暂停等待,不把 connection refused 当失败记入报告
17
+ - **写接口必须核实 DB 副作用** — HTTP 200 ≠ 测试通过,POST/PUT/DELETE/PATCH 必须由 AI 用 `db-query skill` 查 DB 验数据
18
+ - **env 文件不自动生成** — `docs/bruno/environments/local.bru` 缺失时报错退出,提示用户先跑 `/write-api`,不自己生成
19
+ - **报告永远归一个 feature 目录** — 即使测试涉及的接口关联多个 feature,报告归用户触发时指定的需求目录,不混
20
+
21
+ ## Trigger
22
+
23
+ **使用此 skill 当**:
24
+ - 用户完成 `/write-api` 后,要求"跑接口测试""跑一下测试""验证接口"
25
+ - 用户说"run-api-test""测一下需求 X 的接口""跑下这个接口"
26
+ - 代码改完后,用户想重跑接口测试验证修复
27
+
28
+ **不要使用此 skill 当**:
29
+ - 生成测试接口 → 用 `/write-api`(本 skill 假设 .bru 已存在)
30
+ - 写 HTML 接口文档 → 用 `/write-api-doc`
31
+ - 修代码 / 改 .bru → 用户手动或走 `/implementation`(本 skill 只测不修)
32
+ - 探索陌生项目 → 用 `/code-impact-init`
33
+ - 查代码调用关系 → 用 `/cgraphx` 或 `codegraph_explore` MCP
34
+
35
+ ## 与既有 skill 边界
36
+
37
+ | skill | 关系 | 说明 |
38
+ |---|---|---|
39
+ | `write-api` | 上游 | 产 .bru + 测试规格 + environments;本 skill 消费这些产物跑测试,不调它也不改 .bru |
40
+ | `write-api-doc` | 独立并列 | 不互相调用;本 skill 产测试报告 + JSONL,write-api-doc 产 HTML 接口文档 |
41
+ | `cgraphx` / `codegraph_explore` | 可选复用 | R1 确定测试范围时,若需定位接口 handler 可用(但通常用户已给接口名,直接用即可) |
42
+ | `db-query` | 复用 | R4 核实写接口 DB 副作用;受 db-query 既有只读约束 |
43
+ | `implementation` / `subagent-implement` | 下游 | 测试失败后由用户决定是否调起修 bug |
44
+ | `code-impact-docgen` | 独立 | 自测后产设计文档 |
45
+
46
+ ## 依赖
47
+
48
+ - `.bru` 文件已存在(由 `/write-api` 生成,在 `docs/bruno/<服务>/<接口名>/<场景>.bru` 或 `docs/bruno/common/<接口名>/<场景>.bru`)
49
+ - `docs/bruno/environments/local.bru` 存在(不存在时报错退出,提示先跑 `/write-api`)
50
+ - 本地服务可启动(若需手动启动,R2 暂停等待)
51
+ - 项目已配置 db-query profile(R4 核实写接口副作用用)—— 未配置则 R4 降级,见 `references/db-verification.md`
52
+
53
+ ## feature-id 与文件前缀规则
54
+
55
+ 复用既有规则(同 `/write-prd` / `/write-spec` / `/write-plan` / `/write-api-doc` / `/write-api` 的算法):
56
+
57
+ - feature-id 格式:`YYYY-MM-DD-[业务ID-]<标题>`
58
+ - 文件前缀:有业务ID = `<业务ID>-<标题>`,无业务ID = `<标题>`
59
+ - 文件名不得包含 `/`、`:`、`*`、`?`、`"`、`<`、`>`、`|`
60
+
61
+ 产物文件名(归用户指定的 feature 目录):
62
+ - Markdown 报告:`docs/features/<feature-id>/<文件前缀>-测试报告.md`
63
+ - JSONL 验证记录:`docs/features/<feature-id>/<文件前缀>-测试验证.jsonl`
64
+
65
+ 格式见 `references/report-format.md`。
66
+
67
+ ## 触发逻辑(用户给的是什么?)
68
+
69
+ 这是本 skill 的核心,直接写在 SKILL.md(不抽 reference),因为这是流程编排不是规范细节。
70
+
71
+ ```
72
+ 用户触发 /run-api-test
73
+
74
+ 用户给的是什么?
75
+ ├─ 指定了需求(feature-id / spec / 需求名)
76
+ │ → AI 查该需求的 <文件前缀>-api-spec.md,拿到接口清单 + 场景
77
+ │ → 提示用户确认"本次测试需求 X,涉及 N 接口 M 场景,确认?"
78
+ │ → 用户确认后进入 R1
79
+
80
+ ├─ 只指定了接口(接口名/路径)
81
+ │ → skill 主动问"测哪个需求?"
82
+ │ → AI 反查该接口 .bru docs 段的"关联需求"列表(可能多个)
83
+ │ → 列出来让用户选(若 0 个需求,提示用户先跑 /write-api)
84
+ │ → 选定后,AI 查该需求 api-spec.md 拿该接口的场景
85
+ │ → 提示用户确认后进入 R1
86
+
87
+ └─ 都没指定
88
+ → skill 主动问"请指定需求(feature-id/spec)或接口名"
89
+ → 拿到回答后回到上面两条分支
90
+ ```
91
+
92
+ **关键约束**:
93
+ - 不管走哪条分支,最终都要锁定一个 feature-id,**报告归该 feature 目录**
94
+ - AI 反查 .bru docs 段关联需求时,读 `docs/bruno/<服务>/<接口名>/*.bru` 里 docs 段的"关联需求"段
95
+ - 用户确认环节不能省 —— AI 理解的范围必须显示给用户,避免跑错需求或接口
96
+
97
+ ## 工作流
98
+
99
+ 按 R1-R5 顺序执行,每步规范细节在对应 reference 文件。
100
+
101
+ ### R1. 确定测试范围
102
+
103
+ - **前置**:触发逻辑锁定一个 feature-id
104
+ - **行为**:按 `references/test-scope.md` 拿到本次测试的 .bru 清单
105
+ - 查 `<文件前缀>-api-spec.md` 拿接口清单 + 场景 + .bru 路径
106
+ - 交叉校验 .bru 文件实际存在
107
+ - 显示测试范围给用户确认
108
+ - **校验失败**(api-spec 不存在 / .bru 缺失)→ 报错并退出
109
+ - **用户取消** → 退出
110
+ - **结果**:得到本次跑的 .bru 清单
111
+
112
+ ### R2. 本地服务就绪处理
113
+
114
+ - **前置**:R1 测试范围已确认
115
+ - **行为**:按 `references/service-readiness.md` 做服务就绪检测(两种 TCP 策略,任一通过即就绪)
116
+ - **env 文件缺失** → 报错退出,提示先跑 `/write-api`(本 skill 不生成 env)
117
+ - **服务未就绪** → 暂停提示用户启动,等待回车;不盲跑、不重试
118
+ - **就绪** → 继续 R3
119
+
120
+ ### R3. 跑测试
121
+
122
+ - **前置**:服务就绪 + env 就绪
123
+ - **行为**:按 `references/bru-run.md` 调用 `bru run` 跑 R1 清单涉及的接口目录
124
+ - **bru run 整体崩溃** → 报"测试执行器异常" + 输出 stderr,**不继续 R4**
125
+ - **结果**:得到每接口每场景的 HTTP 状态、响应体、断言通过情况
126
+
127
+ ### R4. 数据库副作用核实
128
+
129
+ - **前置**:R3 完成
130
+ - **跳过条件**:R1 清单无写接口(全 GET)→ 跳过本步直接 R5
131
+ - **行为**:按 `references/db-verification.md`,AI 用 `db-query skill` 逐写接口核实副作用
132
+ - **db-query skill 失败** → 该接口记"无法核实" + 状态 `失败-DB副作用`,**不阻塞其他接口**
133
+ - **结果**:逐接口 DB 核实记录写入 JSONL
134
+
135
+ ### R5. 产出测试报告
136
+
137
+ - **前置**:R3 + R4 完成
138
+ - **行为**:按 `references/report-format.md` 汇总产出
139
+ - Markdown 报告 `<文件前缀>-测试报告.md`(汇总 + 逐接口结果 + 失败分类 + DB 核实小结 + 下一步建议)
140
+ - JSONL `<文件前缀>-测试验证.jsonl`(R4 写接口记录 + R5 补齐查询接口记录)
141
+ - JSON 中间结果丢弃
142
+ - **报告归属**:归用户指定的 feature 目录,即使接口关联多 feature 也不混
143
+ - **结果**:报告落盘;skill 结束
144
+
145
+ ## 异常速查
146
+
147
+ | 场景 | 行为 |
148
+ |---|---|
149
+ | 用户指定需求但 api-spec 不存在 | 报"需求 X 无测试规格,请先跑 /write-api"并退出 |
150
+ | 用户指定接口但 .bru 不存在 | 报"接口 Y 无 .bru,请先跑 /write-api"并退出 |
151
+ | 用户指定接口但 docs 段无关联需求 | 提示"接口 Y 未声明关联需求,请确认 .bru 由 /write-api 生成" |
152
+ | api-spec §5 列出的 .bru 实际不存在 | 报"需求 X 接口 Y 场景 Z 的 .bru 缺失,请先跑 /write-api"并退出 |
153
+ | 本地服务未启动 | 暂停 + 提示用户启动,等待回车继续 |
154
+ | env 文件缺失 | 报"环境缺失,请先跑 /write-api"并退出,不自动生成 |
155
+ | 服务起了但接口 404 | 记 `失败-HTTP`,标注可能路由未注册或路径不对 |
156
+ | 写接口 HTTP 通但 DB 没改 | 记 `失败-DB副作用`,AI 标注预期 vs 实际差异 |
157
+ | bru run 整体崩溃 | 报"测试执行器异常" + 输出 stderr,不继续 R4 |
158
+ | 同 feature 重复触发 | 覆盖该 feature 报告 + JSONL,不增量合并 |
159
+ | db-query 在 R4 失败 | 该接口记"无法核实" + 状态 `失败-DB副作用`,不阻塞其他接口 |
160
+ | 用户改代码后重跑 | 直接重跑 `/run-api-test` 覆盖报告;只有需重新生成 .bru 入参时才走 `/write-api` |
161
+
162
+ ## 质量检查
163
+
164
+ 跑完后自检:
165
+ - 报告归指定的 feature 目录(`<文件前缀>-测试报告.md` + `<文件前缀>-测试验证.jsonl`)
166
+ - 写接口 DB 核实到位,不存在"只看 HTTP 200 就算过"的写接口
167
+ - 服务未就绪时没盲跑,没产 connection refused 失败报告
168
+ - 失败接口有原因分类(数据问题 / 代码 bug / 服务问题 / 断言过严)
169
+ - 不改 .bru(跑前后 .bru 内容一致)
170
+ - 不自动修代码、不自动重跑
171
+ - env 文件缺失时报错退出,没自己生成
172
+ - JSON 中间结果已丢弃,不归档
173
+ - 用户确认环节有执行(测试范围显示给用户)
174
+
175
+ ## 收尾
176
+
177
+ 提示用户:
178
+ 1. 测试报告位置(`<文件前缀>-测试报告.md`)
179
+ 2. 通过 / 失败 / 跳过汇总
180
+ 3. 失败接口清单 + 原因分类
181
+ 4. 下一步建议:
182
+ - 失败-DB副作用 → 走 `/implementation` 修,修完重跑 `/run-api-test`
183
+ - 失败-断言 → 确认是代码 bug 还是断言写错
184
+ - 失败-HTTP → 确认路由注册
185
+ - 需重新生成 .bru 入参 → 走 `/write-api` 再跑 `/run-api-test`
186
+
187
+ 不主动调用 `/implementation` 或其他下游 skill。不写 knowledge 文件。不修改 spec / plan / 代码 / .bru。
@@ -0,0 +1,103 @@
1
+ # 接口测试报告模板
2
+
3
+ 适用于 `write-api` skill 在 S7 生成。默认输出到 `docs/features/<feature-id>/<文件前缀>-测试报告.md`。
4
+
5
+ 本模板由 skill 在 S7 填充:汇总 + 逐接口结果 + 失败原因分类 + 下一步建议。
6
+
7
+ ## 完整结构
8
+
9
+ ```markdown
10
+ # 接口测试报告:<feature 标题>
11
+
12
+ > feature-id: <feature-id>
13
+ > 生成时间: <YYYY-MM-DD HH:MM>
14
+ > 关联测试规格: <文件前缀>-api-spec.md
15
+ > 关联 .bru 集合: docs/bruno/<服务>/<feature-id>/
16
+
17
+ ## 1. 汇总
18
+
19
+ | 指标 | 值 |
20
+ |---|---|
21
+ | 总接口数 | <N> |
22
+ | 通过 | <N> |
23
+ | 失败 | <N> |
24
+ | 跳过 | <N> |
25
+ | 总耗时 | <ms> |
26
+
27
+ 通过率:<通过/总> %
28
+
29
+ ## 2. 逐接口结果
30
+
31
+ | 方法 | 路径 | 状态 | HTTP | 断言 | DB 核实 | 耗时(ms) |
32
+ |---|---|---|---|---|---|---|
33
+ | GET | /api/v1/users/:id | 通过 | 200 | 通过 | - | 239 |
34
+ | POST | /api/v1/users | 通过 | 201 | 通过 | 通过 | 512 |
35
+ | PUT | /api/v1/users/:id | 失败-DB副作用 | 200 | 通过 | 失败 | 480 |
36
+ | DELETE | /api/v1/users/:id | 失败-断言 | 200 | 失败 | - | 350 |
37
+ | GET | /api/v1/orders/:id | 失败-HTTP | 404 | - | - | 120 |
38
+
39
+ 状态枚举:通过 / 失败-断言 / 失败-DB副作用 / 失败-HTTP / 失败-连接 / 跳过
40
+
41
+ ## 3. 失败原因分类
42
+
43
+ ### 失败-DB副作用(1 个)
44
+
45
+ #### PUT /api/v1/users/:id
46
+ - HTTP: 200(接口通)
47
+ - 断言:通过
48
+ - DB 核实:失败
49
+ - 预期:users 表 name 字段更新为"新名字"
50
+ - 实际:users 表 name 字段仍为"旧名字"
51
+ - 差异:name 未更新
52
+ - 可能原因:代码 bug(update 语句未生效)/ 测试数据问题(参数传错)/ 断言过严
53
+ - 建议下一步:走 /implementation 排查 update 逻辑
54
+
55
+ ### 失败-断言(1 个)
56
+
57
+ #### DELETE /api/v1/users/:id
58
+ - HTTP: 200
59
+ - 断言:失败
60
+ - 期望:response.body.success = true
61
+ - 实际:response.body.success = false
62
+ - 可能原因:接口实际未删除(代码 bug)/ 断言写错(响应结构变了)
63
+ - 建议下一步:走 /implementation 排查 delete 逻辑,或调整 .bru 的 tests 段
64
+
65
+ ### 失败-HTTP(1 个)
66
+
67
+ #### GET /api/v1/orders/:id
68
+ - HTTP: 404
69
+ - 可能原因:路由未注册 / 路径不对 / id 不存在
70
+ - 建议下一步:确认路由注册,或换真实 id
71
+
72
+ ## 4. 写接口 DB 核实小结
73
+
74
+ | 接口 | 核实结论 | 查询表 | 预期 | 实际 |
75
+ |---|---|---|---|---|
76
+ | POST /api/v1/users | 通过 | users | 新增一行 | 新增一行,id=12346 |
77
+ | PUT /api/v1/users/:id | 失败 | users | name 更新为"新名字" | name 仍为"旧名字" |
78
+ | DELETE /api/v1/users/:id | 未核实(断言已失败) | - | - | - |
79
+
80
+ ## 5. 下一步建议
81
+
82
+ - 失败-DB副作用(1 个):疑似代码 bug,建议走 `/implementation` 排查 update 逻辑
83
+ - 失败-断言(1 个):需确认是代码 bug 还是断言写错,建议先看响应体再决定
84
+ - 失败-HTTP(1 个):确认路由注册,可能是测试数据问题
85
+
86
+ 修完后重跑 `/write-api` 验证。
87
+
88
+ ## 6. 产物清单
89
+
90
+ - 测试规格:<文件前缀>-api-spec.md
91
+ - .bru collection:docs/bruno/<服务>/<feature-id>/
92
+ - Markdown 报告:本文件
93
+ - JSONL 验证记录:<文件前缀>-测试验证.jsonl
94
+ ```
95
+
96
+ ## 填写说明
97
+
98
+ - §1 汇总由 S5 + S6 结果统计
99
+ - §2 逐接口结果的"DB 核实"列:查询接口填"-",写接口填"通过/失败/未核实"
100
+ - §3 失败原因分类按状态枚举分组,每组列具体接口 + 预期 vs 实际 + 可能原因 + 建议下一步
101
+ - §4 仅在本次有写接口时填
102
+ - §5 下一步建议按失败类型给,不自动调下游 skill,由用户决定
103
+ - §6 产物清单固定四项
@@ -0,0 +1,5 @@
1
+ {"interface": "GET /api/v1/users/:id", "http_status": 200, "assertions": [{"name": "status is 200", "passed": true, "expected": 200, "actual": 200}, {"name": "response has id", "passed": true, "expected": "property id", "actual": "id=12345"}, {"name": "id is number", "passed": true, "expected": "number", "actual": 12345}], "db_verification": {"required": false, "conclusion": "not_required", "queries": [], "expected": null, "actual": null, "error": null}, "final_status": "通过", "duration_ms": 239}
2
+ {"interface": "POST /api/v1/users", "http_status": 201, "assertions": [{"name": "status is 201", "passed": true, "expected": 201, "actual": 201}, {"name": "response has id", "passed": true, "expected": "property id", "actual": "id=12346"}], "db_verification": {"required": true, "conclusion": "通过", "queries": ["SELECT id, name, email FROM users WHERE id = 12346"], "expected": "新增一行 name=测试用户 email=test@example.com", "actual": "新增一行 id=12346 name=测试用户 email=test@example.com", "error": null}, "final_status": "通过", "duration_ms": 512}
3
+ {"interface": "PUT /api/v1/users/:id", "http_status": 200, "assertions": [{"name": "status is 200", "passed": true, "expected": 200, "actual": 200}], "db_verification": {"required": true, "conclusion": "失败", "queries": ["SELECT name FROM users WHERE id = 12345"], "expected": "name 更新为 新名字", "actual": "name 仍为 旧名字", "error": null}, "final_status": "失败-DB副作用", "duration_ms": 480}
4
+ {"interface": "GET /api/v1/orders/:id", "http_status": 404, "assertions": [], "db_verification": {"required": false, "conclusion": "not_required", "queries": [], "expected": null, "actual": null, "error": null}, "final_status": "失败-HTTP", "duration_ms": 120}
5
+ {"interface": "POST /api/v1/users (db-query failed)", "http_status": 201, "assertions": [{"name": "status is 201", "passed": true, "expected": 201, "actual": 201}], "db_verification": {"required": true, "conclusion": "无法核实", "queries": [], "expected": "新增一行", "actual": null, "error": "db-query 连接失败: ConnectionFailedError"}, "final_status": "失败-DB副作用", "duration_ms": 380}
@@ -0,0 +1,60 @@
1
+ # R3 跑测试规范
2
+
3
+ ## bru run 命令
4
+
5
+ ```
6
+ bru run docs/bruno/<服务>/<接口名>/ --env local --output <临时 JSON 路径> -r
7
+ ```
8
+
9
+ ### 参数说明
10
+
11
+ | 参数 | 说明 |
12
+ |---|---|
13
+ | 路径参数 | R1 清单涉及的接口目录(从 api-spec §5 取),不是全项目 `docs/bruno/` |
14
+ | `--env local` | 使用 `docs/bruno/environments/local.bru` 的变量(用户切换时透传 `--env staging` / `--env production`) |
15
+ | `--output <path>` | JSON 中间结果输出路径(临时,跑完即丢,不归档) |
16
+ | `-r` | 递归跑目录下所有 .bru |
17
+
18
+ ### 跑哪些接口
19
+
20
+ **只跑 R1 清单涉及的接口目录**,不是全项目 `docs/bruno/`。
21
+
22
+ 理由:用户指定需求或接口后,范围已锁定;跑全项目是另一个场景(全量回归),用户应自行 `bru run docs/bruno/ -r`,不归本 skill 管。
23
+
24
+ ### 多接口目录的处理
25
+
26
+ R1 清单可能涉及多个接口目录(如 `getUser/` + `createUser/` + `common/login/`)。两种跑法:
27
+
28
+ - **分批跑**:每个接口目录单独 `bru run`,结果汇总(更细粒度,易定位崩溃)
29
+ - **合并跑**:把所有路径作为参数一次跑(bru run 支持多路径参数)
30
+
31
+ 推荐**分批跑**——某个接口目录崩溃时不影响其他接口,且日志更清晰。
32
+
33
+ ## 失败处理
34
+
35
+ ### 单接口失败(bru run 正常返回,但某些接口 HTTP 错或断言失败)
36
+
37
+ 不算崩溃,继续 R4。失败的接口在 JSON 中间结果里有状态,汇总到 R5 报告。
38
+
39
+ ### bru run 整体崩溃(进程退出非 0,非单接口失败)
40
+
41
+ 报"测试执行器异常" + 输出 bru 原始 stderr,**不继续 R4**。
42
+
43
+ 崩溃常见原因:
44
+ - bruno CLI 版本 bug
45
+ - .bru 文件语法错(write-api 生成的 .bru 不符合 bruno-lang v2)
46
+ - 环境配置错(env 文件读不了)
47
+
48
+ 崩溃时不继续 R4——继续也没意义(JSON 中间结果可能不完整);让用户判断是修 .bru、调 bruno 版本,还是回 write-api 重新生成。
49
+
50
+ ## JSON 中间结果
51
+
52
+ `bru run --output <path>` 产出的 JSON,**临时产物,不归档**。
53
+
54
+ 理由:JSON 是 bruno 的执行原始记录,字段多且对用户不友好;最终给用户看的是 R5 的 Markdown 报告 + JSONL 验证记录。JSON 跑完即丢。
55
+
56
+ ## bru CLI 版本
57
+
58
+ 测试工具是开源 bruno(`@usebruno/cli`),要求项目已装 bru CLI(`npm install -g @usebruno/cli` 或项目本地装)。
59
+
60
+ 若 bru 命令不存在 → 报"未找到 bru CLI,请先装 `npm install -g @usebruno/cli`"并退出。