cgraphx 1.2.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 (136) hide show
  1. package/dist/.claude-template/hooks/precommit-check/precommit-check.cjs +90 -0
  2. package/dist/.claude-template/skills/cgraphx-guide/how-to-use.html +99 -78
  3. package/dist/.claude-template/skills/precommit-review/SKILL.md +50 -0
  4. package/dist/.claude-template/skills/run-api-test/SKILL.md +187 -0
  5. package/dist/.claude-template/skills/run-api-test/assets/template-test-report.md +103 -0
  6. package/dist/.claude-template/skills/run-api-test/assets/template-test-verify.jsonl +5 -0
  7. package/dist/.claude-template/skills/run-api-test/references/bru-run.md +60 -0
  8. package/dist/.claude-template/skills/run-api-test/references/db-verification.md +81 -0
  9. package/dist/.claude-template/skills/run-api-test/references/report-format.md +104 -0
  10. package/dist/.claude-template/skills/run-api-test/references/service-readiness.md +61 -0
  11. package/dist/.claude-template/skills/run-api-test/references/test-scope.md +64 -0
  12. package/dist/.claude-template/skills/write-api/SKILL.md +150 -0
  13. package/dist/.claude-template/skills/write-api/assets/template-api-spec.md +112 -0
  14. package/dist/.claude-template/skills/write-api/assets/template-request.bru +75 -0
  15. package/dist/.claude-template/skills/write-api/references/ai-prompts.md +133 -0
  16. package/dist/.claude-template/skills/write-api/references/api-spec-format.md +108 -0
  17. package/dist/.claude-template/skills/write-api/references/bru-format.md +144 -0
  18. package/dist/.claude-template/skills/write-api/references/collection-layout.md +81 -0
  19. package/dist/.claude-template/skills/write-api/references/environment-setup.md +105 -0
  20. package/dist/.claude-template/skills/write-api/references/interface-scope.md +74 -0
  21. package/dist/api-test/ai-fields.d.ts +37 -0
  22. package/dist/api-test/ai-fields.d.ts.map +1 -0
  23. package/dist/api-test/ai-fields.js +114 -0
  24. package/dist/api-test/ai-fields.js.map +1 -0
  25. package/dist/api-test/assemble.d.ts +76 -0
  26. package/dist/api-test/assemble.d.ts.map +1 -0
  27. package/dist/api-test/assemble.js +185 -0
  28. package/dist/api-test/assemble.js.map +1 -0
  29. package/dist/api-test/bru-cli-invoker.d.ts +72 -0
  30. package/dist/api-test/bru-cli-invoker.d.ts.map +1 -0
  31. package/dist/api-test/bru-cli-invoker.js +169 -0
  32. package/dist/api-test/bru-cli-invoker.js.map +1 -0
  33. package/dist/api-test/bru-report-parser.d.ts +24 -0
  34. package/dist/api-test/bru-report-parser.d.ts.map +1 -0
  35. package/dist/api-test/bru-report-parser.js +110 -0
  36. package/dist/api-test/bru-report-parser.js.map +1 -0
  37. package/dist/api-test/bru-runner.d.ts +101 -0
  38. package/dist/api-test/bru-runner.d.ts.map +1 -0
  39. package/dist/api-test/bru-runner.js +316 -0
  40. package/dist/api-test/bru-runner.js.map +1 -0
  41. package/dist/api-test/bru-writer.d.ts +52 -0
  42. package/dist/api-test/bru-writer.d.ts.map +1 -0
  43. package/dist/api-test/bru-writer.js +159 -0
  44. package/dist/api-test/bru-writer.js.map +1 -0
  45. package/dist/api-test/call-chain-extractor.d.ts +80 -0
  46. package/dist/api-test/call-chain-extractor.d.ts.map +1 -0
  47. package/dist/api-test/call-chain-extractor.js +179 -0
  48. package/dist/api-test/call-chain-extractor.js.map +1 -0
  49. package/dist/api-test/cli.d.ts +133 -0
  50. package/dist/api-test/cli.d.ts.map +1 -0
  51. package/dist/api-test/cli.js +1009 -0
  52. package/dist/api-test/cli.js.map +1 -0
  53. package/dist/api-test/config.d.ts +75 -0
  54. package/dist/api-test/config.d.ts.map +1 -0
  55. package/dist/api-test/config.js +406 -0
  56. package/dist/api-test/config.js.map +1 -0
  57. package/dist/api-test/db-query-cli.d.ts +51 -0
  58. package/dist/api-test/db-query-cli.d.ts.map +1 -0
  59. package/dist/api-test/db-query-cli.js +119 -0
  60. package/dist/api-test/db-query-cli.js.map +1 -0
  61. package/dist/api-test/enhance-prepare.d.ts +111 -0
  62. package/dist/api-test/enhance-prepare.d.ts.map +1 -0
  63. package/dist/api-test/enhance-prepare.js +425 -0
  64. package/dist/api-test/enhance-prepare.js.map +1 -0
  65. package/dist/api-test/enhance-write.d.ts +28 -0
  66. package/dist/api-test/enhance-write.d.ts.map +1 -0
  67. package/dist/api-test/enhance-write.js +145 -0
  68. package/dist/api-test/enhance-write.js.map +1 -0
  69. package/dist/api-test/errors.d.ts +48 -0
  70. package/dist/api-test/errors.d.ts.map +1 -0
  71. package/dist/api-test/errors.js +76 -0
  72. package/dist/api-test/errors.js.map +1 -0
  73. package/dist/api-test/field-extractor.d.ts +98 -0
  74. package/dist/api-test/field-extractor.d.ts.map +1 -0
  75. package/dist/api-test/field-extractor.js +327 -0
  76. package/dist/api-test/field-extractor.js.map +1 -0
  77. package/dist/api-test/impl-finder.d.ts +37 -0
  78. package/dist/api-test/impl-finder.d.ts.map +1 -0
  79. package/dist/api-test/impl-finder.js +54 -0
  80. package/dist/api-test/impl-finder.js.map +1 -0
  81. package/dist/api-test/index.d.ts +41 -0
  82. package/dist/api-test/index.d.ts.map +1 -0
  83. package/dist/api-test/index.js +124 -0
  84. package/dist/api-test/index.js.map +1 -0
  85. package/dist/api-test/java-parser.d.ts +89 -0
  86. package/dist/api-test/java-parser.d.ts.map +1 -0
  87. package/dist/api-test/java-parser.js +508 -0
  88. package/dist/api-test/java-parser.js.map +1 -0
  89. package/dist/api-test/md-writer.d.ts +49 -0
  90. package/dist/api-test/md-writer.d.ts.map +1 -0
  91. package/dist/api-test/md-writer.js +202 -0
  92. package/dist/api-test/md-writer.js.map +1 -0
  93. package/dist/api-test/parser-httpservice.d.ts +91 -0
  94. package/dist/api-test/parser-httpservice.d.ts.map +1 -0
  95. package/dist/api-test/parser-httpservice.js +271 -0
  96. package/dist/api-test/parser-httpservice.js.map +1 -0
  97. package/dist/api-test/report.d.ts +188 -0
  98. package/dist/api-test/report.d.ts.map +1 -0
  99. package/dist/api-test/report.js +522 -0
  100. package/dist/api-test/report.js.map +1 -0
  101. package/dist/api-test/snapshot.d.ts +26 -0
  102. package/dist/api-test/snapshot.d.ts.map +1 -0
  103. package/dist/api-test/snapshot.js +150 -0
  104. package/dist/api-test/snapshot.js.map +1 -0
  105. package/dist/api-test/test-history.d.ts +48 -0
  106. package/dist/api-test/test-history.d.ts.map +1 -0
  107. package/dist/api-test/test-history.js +122 -0
  108. package/dist/api-test/test-history.js.map +1 -0
  109. package/dist/api-test/types.d.ts +174 -0
  110. package/dist/api-test/types.d.ts.map +1 -0
  111. package/dist/api-test/types.js +13 -0
  112. package/dist/api-test/types.js.map +1 -0
  113. package/dist/api-test/verify-prepare.d.ts +30 -0
  114. package/dist/api-test/verify-prepare.d.ts.map +1 -0
  115. package/dist/api-test/verify-prepare.js +150 -0
  116. package/dist/api-test/verify-prepare.js.map +1 -0
  117. package/dist/api-test/verify-write.d.ts +31 -0
  118. package/dist/api-test/verify-write.d.ts.map +1 -0
  119. package/dist/api-test/verify-write.js +159 -0
  120. package/dist/api-test/verify-write.js.map +1 -0
  121. package/dist/dbquery/dump-schema.d.ts +46 -0
  122. package/dist/dbquery/dump-schema.d.ts.map +1 -0
  123. package/dist/dbquery/dump-schema.js +379 -0
  124. package/dist/dbquery/dump-schema.js.map +1 -0
  125. package/dist/installer/targets/claude.d.ts +15 -0
  126. package/dist/installer/targets/claude.d.ts.map +1 -1
  127. package/dist/installer/targets/claude.js +53 -0
  128. package/dist/installer/targets/claude.js.map +1 -1
  129. package/package.json +1 -1
  130. package/scripts/agent-eval/block-cgraphx-and-gitnexus-cli-hook.sh +0 -43
  131. package/scripts/agent-eval/block-cgraphx-cli-hook.sh +0 -32
  132. package/scripts/agent-eval/block-cgraphx-cli-settings.json +0 -16
  133. package/scripts/agent-eval/cli-vs-mcp-3arm.sh +0 -121
  134. package/scripts/agent-eval/multi-tool-eval.sh +0 -171
  135. package/scripts/agent-eval/parse-cli-vs-mcp.mjs +0 -232
  136. package/scripts/agent-eval/parse-multi-tool.mjs +0 -242
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PreToolUse hook for Bash: precommit-check
4
+ *
5
+ * 守门员:拦截 git commit(当暂存含修改/删除/重命名文件时),要求 agent
6
+ * 先调用 /precommit-review skill 审查 staged diff,再带
7
+ * CGRAPHX_PRECOMMIT_REVIEWED=1 前缀重试。纯新增文件直接放行,不制造摩擦。
8
+ *
9
+ * 本脚本不做差异判断 —— 只做"是不是 git commit + 有没有非纯新增文件"的
10
+ * 事实判定。真正的可疑模式识别由 /precommit-review skill 让 agent 自己
11
+ * 跑 git diff --cached 比对完成。
12
+ *
13
+ * 输出协议(PreToolUse):命中拦截时输出
14
+ * { hookSpecificOutput: { hookEventName: "PreToolUse",
15
+ * permissionDecision: "deny",
16
+ * permissionDecisionReason: <指名 /precommit-review> } }
17
+ * 不命中时静默 exit 0(放行)。任何异常都吞掉 exit 0,永不阻断正常流程。
18
+ */
19
+
20
+ const { execSync } = require('child_process');
21
+ const fs = require('fs');
22
+
23
+ const ENV_BYPASS = 'CGRAPHX_PRECOMMIT_REVIEWED=1';
24
+
25
+ function readInput() {
26
+ try {
27
+ const data = fs.readFileSync(0, 'utf-8');
28
+ return data ? JSON.parse(data) : {};
29
+ } catch (e) {
30
+ return {};
31
+ }
32
+ }
33
+
34
+ function deny(reason) {
35
+ process.stdout.write(JSON.stringify({
36
+ hookSpecificOutput: {
37
+ hookEventName: 'PreToolUse',
38
+ permissionDecision: 'deny',
39
+ permissionDecisionReason: reason,
40
+ },
41
+ }));
42
+ }
43
+
44
+ function main() {
45
+ const input = readInput();
46
+ const cmd = String((input && input.tool_input && input.tool_input.command) || '');
47
+
48
+ // 只拦 git commit(覆盖 -m / --amend / --fixup 等所有子形式)
49
+ if (!/\bgit\s+commit\b/.test(cmd)) return;
50
+
51
+ // 已审查过的重试 —— agent 在 skill 审查后会带 ENV_BYPASS 前缀重提交
52
+ if (cmd.includes(ENV_BYPASS)) return;
53
+
54
+ // 拿暂存文件状态
55
+ let staged;
56
+ try {
57
+ staged = execSync('git diff --cached --name-status', {
58
+ encoding: 'utf-8',
59
+ cwd: process.cwd(),
60
+ stdio: ['ignore', 'pipe', 'ignore'],
61
+ }) || '';
62
+ } catch (e) {
63
+ return; // 非 git 仓库 / git 不可用 —— 不阻断
64
+ }
65
+ if (!staged.trim()) return; // 没暂存任何东西,交给 git 报错
66
+
67
+ // 纯新增(A)直接放行;M/D/R/C/T/U 等都视为"非纯新增"
68
+ const nonNew = staged
69
+ .split('\n')
70
+ .filter(Boolean)
71
+ .filter((line) => line.split('\t')[0] !== 'A');
72
+
73
+ if (nonNew.length === 0) return; // 纯新增,放行
74
+
75
+ const reason =
76
+ `本次 git commit 暂存了 ${nonNew.length} 个修改/删除/重命名文件,提交前请先调用 ` +
77
+ `\`/precommit-review\` skill 审查 staged diff —— 检查被注释的开关(如 // @Component / @JmsListener / @Scheduled)、` +
78
+ `被注释的业务调用、未闭合的逻辑、写死的魔法字符串、TODO/临时标记等可疑修改。\n\n` +
79
+ `审查通过(或确认无需修改)后,用以下形式重试提交以跳过本检查:\n` +
80
+ ` ${ENV_BYPASS} git commit ...\n\n` +
81
+ `(本 hook 不做差异判断,只做守门;真正的可疑识别由 /precommit-review skill 让 agent 自己比对 staged diff 完成。)`;
82
+
83
+ deny(reason);
84
+ }
85
+
86
+ try {
87
+ main();
88
+ } catch (e) {
89
+ // hook 永不阻断正常流程 —— 任何意外都放行
90
+ }
@@ -186,49 +186,61 @@ footer {
186
186
  footer p { margin: 0; }
187
187
 
188
188
  /* docs/ 目录速查 */
189
- .docs-map {
190
- list-style: none;
191
- padding-left: 0;
192
- margin: 0;
193
- }
194
- .docs-map li {
195
- padding: 12px 0;
196
- border-bottom: 1px dashed var(--color-border);
197
- margin-bottom: 0;
189
+ .docs-tree {
190
+ background: var(--color-bg-subtle);
191
+ border: 1px solid var(--color-border);
192
+ border-left: 4px solid var(--color-cgraphx);
193
+ border-radius: var(--radius);
194
+ padding: 22px 26px;
195
+ font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
196
+ font-size: 13.5px;
197
+ line-height: 1.8;
198
+ color: var(--color-text);
199
+ overflow-x: auto;
200
+ margin: 0 0 16px;
201
+ white-space: pre;
198
202
  }
199
- .docs-map li:last-child { border-bottom: none; padding-bottom: 0; }
200
- .docs-map .dir {
203
+ .docs-tree b {
201
204
  font-weight: 600;
202
205
  color: var(--color-primary-dark);
203
- background: var(--color-bg-code);
204
- padding: 2px 6px;
205
- border-radius: 3px;
206
- font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
207
- font-size: 0.85em;
208
- margin-right: 8px;
209
- white-space: nowrap;
210
206
  }
211
- .docs-map .desc {
212
- color: var(--color-text-secondary);
213
- font-size: 14.5px;
207
+ .docs-tree .skill {
208
+ color: var(--color-primary);
209
+ font-weight: 600;
214
210
  }
215
- .docs-map .owner {
216
- display: block;
217
- margin-top: 6px;
218
- font-size: 13px;
211
+ .docs-tree .ann {
219
212
  color: var(--color-text-tertiary);
220
- line-height: 1.6;
221
213
  }
222
- .docs-map .owner code { font-size: 12.5px; }
223
- .docs-map .owner .label {
214
+ .docs-tree .must {
215
+ color: #2e7d32;
224
216
  font-weight: 600;
217
+ }
218
+ .docs-tree .opt {
219
+ color: #e65100;
220
+ font-weight: 600;
221
+ }
222
+ .docs-legend {
223
+ display: flex;
224
+ gap: 20px;
225
+ flex-wrap: wrap;
226
+ font-size: 13px;
225
227
  color: var(--color-text-secondary);
226
- margin-right: 4px;
228
+ margin: 0 0 20px;
227
229
  }
228
- .docs-map .owner .manual {
229
- color: var(--color-text-tertiary);
230
- font-style: italic;
230
+ .docs-legend span {
231
+ display: inline-flex;
232
+ align-items: center;
233
+ gap: 6px;
234
+ }
235
+ .docs-legend .dot {
236
+ display: inline-block;
237
+ width: 8px;
238
+ height: 8px;
239
+ border-radius: 50%;
231
240
  }
241
+ .docs-legend .dot.must { background: #2e7d32; }
242
+ .docs-legend .dot.opt { background: #e65100; }
243
+ .docs-legend .dot.local { background: var(--color-cgraphx); }
232
244
 
233
245
  /* Responsive */
234
246
  @media (max-width: 768px) {
@@ -250,7 +262,7 @@ footer p { margin: 0; }
250
262
  <div class="eyebrow">cgraphx 安装与使用</div>
251
263
  <h1>cgraphx 怎么用</h1>
252
264
  <p class="subtitle">本地优先的代码智能 · 给 AI agent 用的代码图谱</p>
253
- <p class="meta">最后更新:2026-07-02</p>
265
+ <p class="meta">最后更新:2026-07-13</p>
254
266
  </header>
255
267
 
256
268
  <section>
@@ -313,6 +325,16 @@ footer p { margin: 0; }
313
325
  </ul>
314
326
  </div>
315
327
 
328
+ <div class="phase">
329
+ <div class="phase-label">编码完成后 · 按需</div>
330
+ <ul class="phase-list">
331
+ <li><code>/write-api</code> 自动生成 bruno 测试接口<em>(识别新增接口 → 生成测试规格 + .bru + 多环境配置 + bruno.json,只造弹药不跑测试)</em></li>
332
+ <li><code>/run-api-test</code> 跑接口测试 + 核实写接口 DB 副作用 + 出报告<em>(指定需求或接口触发;写接口必须查 DB 验数据,HTTP 200 ≠ 通过;失败只报告不修不重跑)</em></li>
333
+ <li><code>/write-api-doc</code> 生成静态 HTML 接口文档<em>(与 write-api / run-api-test 独立并列)</em></li>
334
+ <li><code>/code-impact-docgen</code> 自测通过后合成 feature 设计文档</li>
335
+ </ul>
336
+ </div>
337
+
316
338
  <div class="phase">
317
339
  <div class="phase-label">工作回顾 · 按需</div>
318
340
  <ul class="phase-list">
@@ -347,54 +369,53 @@ footer p { margin: 0; }
347
369
 
348
370
  <section>
349
371
  <h2>docs/ 目录速查</h2>
350
- <p>翻文档时知道去哪儿找 —— 哪个目录由哪个 skill 自动维护、哪些是项目自身的文档。</p>
351
-
352
- <ul class="docs-map">
353
- <li>
354
- <code class="dir">docs/knowledge/</code>
355
- <span class="desc">业务知识库 —— 决策 / 概念定义 / 历史教训,被 <code>codegraph_docs_*</code> 索引。</span>
356
- <span class="owner"><span class="label">维护:</span><code>code-impact-markdown</code>、<code>code-impact-init</code> 写;<code>code-impact-api</code> 查;<code>code-impact-docgen</code> 从这里合成人类阅读文档。</span>
357
- </li>
358
- <li>
359
- <code class="dir">docs/features/</code>
360
- <span class="desc">单次需求的工作目录 —— <code>{date}-{slug}/</code> 下集中放 PRD / spec / plan / knowledge。</span>
361
- <span class="owner"><span class="label">维护:</span>全流程 skills —— <code>clarify-requirements</code> → <code>write-prd</code> → <code>write-spec</code> → <code>write-plan</code> → <code>implementation</code> / <code>subagent-implement</code>。</span>
362
- </li>
363
- <li>
364
- <code class="dir">docs/schema-knowledge/</code>
365
- <span class="desc">DB schema 知识沉淀 —— 表结构 / 字段含义 / 业务假设的验证记录。</span>
366
- <span class="owner"><span class="label">维护:</span><code>db-query</code>(查 MySQL / PostgreSQL 后自动沉淀)。</span>
367
- </li>
368
- <li>
369
- <code class="dir">docs/reports/</code>
370
- <span class="desc">时间线报告 —— 日报 / 周报 / 月报 HTML。</span>
371
- <span class="owner"><span class="label">维护:</span><code>developer-timeline</code>。</span>
372
- </li>
373
- <li>
374
- <code class="dir">docs/published/</code>
375
- <span class="desc">面向人类阅读的合成文档(HTML / Markdown),对外可分享。</span>
376
- <span class="owner"><span class="label">维护:</span><code>code-impact-docgen</code>(从 <code>docs/knowledge/</code> 合成产出)。</span>
377
- </li>
378
- <li>
379
- <code class="dir">docs/benchmarks/</code>
380
- <span class="desc">cgraphx 自身的性能基准 / 检索质量对比文档。</span>
381
- <span class="owner"><span class="manual">无 skill 维护 —— maintainer 配合 <code>agent-eval</code> 手动产出。</span></span>
382
- </li>
383
- <li>
384
- <code class="dir">docs/design/</code>
385
- <span class="desc">cgraphx 自身的设计文档 —— 架构 / 算法 / 方法论 playbooks。</span>
386
- <span class="owner"><span class="manual">无 skill 维护 —— maintainer 手动维护。</span></span>
387
- </li>
388
- <li>
389
- <code class="dir">docs/plans/</code>
390
- <span class="desc">历史遗留的早期计划文档;新需求一律走 <code>docs/features/{id}/plan/</code>。</span>
391
- <span class="owner"><span class="manual">无 skill 维护 —— 仅历史归档,不要往这里写新文件。</span></span>
392
- </li>
393
- </ul>
372
+ <p>翻文档时知道去哪儿找 —— 哪个目录由哪个 skill 自动维护。</p>
373
+
374
+ <div class="docs-legend">
375
+ <span><span class="dot must"></span>必有</span>
376
+ <span><span class="dot opt"></span>可选(按需)</span>
377
+ <span><span class="dot local"></span>本地测试相关</span>
378
+ </div>
379
+
380
+ <pre class="docs-tree"><b>docs/</b> <span class="ann"># 必有</span>
381
+ ├── <b>bruno/</b> <span class="ann"># 本地,write-api + run-api-test 维护</span>
382
+ │ ├── bruno.json <span class="ann"># bruno app 识别整个 collection</span>
383
+ │ ├── <b>environments/</b>
384
+ │ │ ├── local.bru <span class="ann"># write-api 生成骨架,用户填 secret</span>
385
+ │ │ ├── staging.bru
386
+ │ │ └── production.bru
387
+ │ ├── <b>common/</b> <span class="ann"># 通用接口(登录 / 健康检查等)</span>
388
+ │ │ └── &lt;接口名&gt;/&lt;场景&gt;.bru
389
+ │ └── <b>&lt;服务名&gt;/</b> <span class="ann"># 如 a-service / b-service</span>
390
+ │ └── <b>&lt;接口名&gt;/</b> <span class="ann"># 接口跨 feature 复用,不绑 feature-id</span>
391
+ │ ├── &lt;场景1&gt;.bru <span class="ann"># 如 正常.bru</span>
392
+ │ └── &lt;场景2&gt;.bru <span class="ann"># 缺prodInstId.bru</span>
393
+
394
+ ├── <b>features/</b> <span class="ann"># 必有,全流程 skills 维护</span>
395
+ │ └── <b>&lt;前缀&gt;/</b> <span class="ann"># 前缀 = 需求/bug编号 + 名称,如 CRM-req19230-号百商品详情查询接口</span>
396
+ │ ├── &lt;前缀&gt;-需求文档.md <span class="skill">/write-prd</span>
397
+ │ ├── &lt;前缀&gt;-spec.md <span class="must">必有</span> <span class="skill">/write-spec</span>
398
+ │ ├── <b>plan/</b> <span class="opt">可选</span> <span class="ann">(按复杂度)</span> <span class="skill">/write-plan</span>
399
+ │ ├── &lt;前缀&gt;-api-spec.md <span class="skill">/write-api</span>
400
+ │ ├── &lt;前缀&gt;-测试报告.md <span class="skill">/run-api-test</span>
401
+ │ ├── &lt;前缀&gt;-测试验证.jsonl <span class="skill">/run-api-test</span>
402
+ │ └── &lt;前缀&gt;-设计文档.md <span class="skill">/code-impact-docgen</span>
403
+
404
+ ├── <b>knowledge/</b> <span class="ann"># 公共必选,业务知识库</span>
405
+ <span class="skill">/code-impact-init</span> <span class="ann">批量写</span>
406
+ <span class="skill">/code-impact-markdown</span> <span class="ann">按需写</span>
407
+
408
+ └── <b>schema-knowledge/</b> <span class="opt">可选</span> <span class="ann">DB schema 知识</span>
409
+ <span class="skill">/db-query</span> <span class="ann">自动写</span>
410
+ </pre>
411
+
412
+ <div class="highlight">
413
+ <p><strong>两个核心目录</strong>——<code>docs/features/</code> 是单次需求工作目录(必须有 spec.md),<code>docs/knowledge/</code> 是跨需求共享的业务知识库。<strong>bruno/ schema-knowledge/ 按需出现</strong>,只在跑接口测试 / 查 DB 时产生。</p>
414
+ </div>
394
415
  </section>
395
416
 
396
417
  <footer>
397
- <p>cgraphx 使用说明 · 2026-07-02</p>
418
+ <p>cgraphx 使用说明 · 2026-07-13</p>
398
419
  </footer>
399
420
 
400
421
  </div>
@@ -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 产物清单固定四项