@mycodemap/mycodemap 0.1.0 → 0.2.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 (283) hide show
  1. package/CHANGELOG.md +164 -6
  2. package/README.md +407 -141
  3. package/dist/cli/commands/ci.d.ts +7 -1
  4. package/dist/cli/commands/ci.d.ts.map +1 -1
  5. package/dist/cli/commands/ci.js +38 -0
  6. package/dist/cli/commands/ci.js.map +1 -1
  7. package/dist/cli/commands/cycles.d.ts.map +1 -1
  8. package/dist/cli/commands/cycles.js +2 -0
  9. package/dist/cli/commands/cycles.js.map +1 -1
  10. package/dist/cli/commands/export.d.ts +6 -0
  11. package/dist/cli/commands/export.d.ts.map +1 -0
  12. package/dist/cli/commands/export.js +108 -0
  13. package/dist/cli/commands/export.js.map +1 -0
  14. package/dist/cli/commands/generate.d.ts.map +1 -1
  15. package/dist/cli/commands/generate.js +96 -0
  16. package/dist/cli/commands/generate.js.map +1 -1
  17. package/dist/cli/commands/init.d.ts.map +1 -1
  18. package/dist/cli/commands/init.js +3 -1
  19. package/dist/cli/commands/init.js.map +1 -1
  20. package/dist/cli/commands/logs.d.ts +5 -0
  21. package/dist/cli/commands/logs.d.ts.map +1 -0
  22. package/dist/cli/commands/logs.js +189 -0
  23. package/dist/cli/commands/logs.js.map +1 -0
  24. package/dist/cli/commands/report.d.ts +12 -0
  25. package/dist/cli/commands/report.d.ts.map +1 -0
  26. package/dist/cli/commands/report.js +158 -0
  27. package/dist/cli/commands/report.js.map +1 -0
  28. package/dist/cli/commands/server.d.ts +9 -0
  29. package/dist/cli/commands/server.d.ts.map +1 -0
  30. package/dist/cli/commands/server.js +68 -0
  31. package/dist/cli/commands/server.js.map +1 -0
  32. package/dist/cli/commands/watch-foreground.d.ts.map +1 -1
  33. package/dist/cli/commands/watch-foreground.js +2 -0
  34. package/dist/cli/commands/watch-foreground.js.map +1 -1
  35. package/dist/cli/commands/watch.d.ts.map +1 -1
  36. package/dist/cli/commands/watch.js +2 -0
  37. package/dist/cli/commands/watch.js.map +1 -1
  38. package/dist/cli/first-run-guide.d.ts +23 -0
  39. package/dist/cli/first-run-guide.d.ts.map +1 -0
  40. package/dist/cli/first-run-guide.js +83 -0
  41. package/dist/cli/first-run-guide.js.map +1 -0
  42. package/dist/cli/index.js +85 -1
  43. package/dist/cli/index.js.map +1 -1
  44. package/dist/cli/platform-check.d.ts +21 -0
  45. package/dist/cli/platform-check.d.ts.map +1 -0
  46. package/dist/cli/platform-check.js +94 -0
  47. package/dist/cli/platform-check.js.map +1 -0
  48. package/dist/cli/tree-sitter-check.d.ts +35 -0
  49. package/dist/cli/tree-sitter-check.d.ts.map +1 -0
  50. package/dist/cli/tree-sitter-check.js +133 -0
  51. package/dist/cli/tree-sitter-check.js.map +1 -0
  52. package/dist/cli/utils/sanitize.d.ts +54 -0
  53. package/dist/cli/utils/sanitize.d.ts.map +1 -0
  54. package/dist/cli/utils/sanitize.js +131 -0
  55. package/dist/cli/utils/sanitize.js.map +1 -0
  56. package/dist/cli-new/commands/export.d.ts +15 -0
  57. package/dist/cli-new/commands/export.d.ts.map +1 -0
  58. package/dist/cli-new/commands/export.js +107 -0
  59. package/dist/cli-new/commands/export.js.map +1 -0
  60. package/dist/cli-new/commands/query.d.ts +14 -0
  61. package/dist/cli-new/commands/query.d.ts.map +1 -0
  62. package/dist/cli-new/commands/query.js +120 -0
  63. package/dist/cli-new/commands/query.js.map +1 -0
  64. package/dist/cli-new/commands/server.d.ts +13 -0
  65. package/dist/cli-new/commands/server.d.ts.map +1 -0
  66. package/dist/cli-new/commands/server.js +94 -0
  67. package/dist/cli-new/commands/server.js.map +1 -0
  68. package/dist/cli-new/index.d.ts +11 -0
  69. package/dist/cli-new/index.d.ts.map +1 -0
  70. package/dist/cli-new/index.js +63 -0
  71. package/dist/cli-new/index.js.map +1 -0
  72. package/dist/cli-new/types/index.d.ts +88 -0
  73. package/dist/cli-new/types/index.d.ts.map +1 -0
  74. package/dist/cli-new/types/index.js +7 -0
  75. package/dist/cli-new/types/index.js.map +1 -0
  76. package/dist/domain/entities/CodeGraph.d.ts +134 -0
  77. package/dist/domain/entities/CodeGraph.d.ts.map +1 -0
  78. package/dist/domain/entities/CodeGraph.js +316 -0
  79. package/dist/domain/entities/CodeGraph.js.map +1 -0
  80. package/dist/domain/entities/Dependency.d.ts +78 -0
  81. package/dist/domain/entities/Dependency.d.ts.map +1 -0
  82. package/dist/domain/entities/Dependency.js +132 -0
  83. package/dist/domain/entities/Dependency.js.map +1 -0
  84. package/dist/domain/entities/Module.d.ts +75 -0
  85. package/dist/domain/entities/Module.d.ts.map +1 -0
  86. package/dist/domain/entities/Module.js +151 -0
  87. package/dist/domain/entities/Module.js.map +1 -0
  88. package/dist/domain/entities/Project.d.ts +50 -0
  89. package/dist/domain/entities/Project.d.ts.map +1 -0
  90. package/dist/domain/entities/Project.js +99 -0
  91. package/dist/domain/entities/Project.js.map +1 -0
  92. package/dist/domain/entities/Symbol.d.ts +75 -0
  93. package/dist/domain/entities/Symbol.d.ts.map +1 -0
  94. package/dist/domain/entities/Symbol.js +130 -0
  95. package/dist/domain/entities/Symbol.js.map +1 -0
  96. package/dist/domain/events/DomainEvent.d.ts +76 -0
  97. package/dist/domain/events/DomainEvent.d.ts.map +1 -0
  98. package/dist/domain/events/DomainEvent.js +153 -0
  99. package/dist/domain/events/DomainEvent.js.map +1 -0
  100. package/dist/domain/index.d.ts +10 -0
  101. package/dist/domain/index.d.ts.map +1 -0
  102. package/dist/domain/index.js +18 -0
  103. package/dist/domain/index.js.map +1 -0
  104. package/dist/domain/repositories/CodeGraphRepository.d.ts +58 -0
  105. package/dist/domain/repositories/CodeGraphRepository.d.ts.map +1 -0
  106. package/dist/domain/repositories/CodeGraphRepository.js +37 -0
  107. package/dist/domain/repositories/CodeGraphRepository.js.map +1 -0
  108. package/dist/domain/services/CodeGraphBuilder.d.ts +50 -0
  109. package/dist/domain/services/CodeGraphBuilder.d.ts.map +1 -0
  110. package/dist/domain/services/CodeGraphBuilder.js +121 -0
  111. package/dist/domain/services/CodeGraphBuilder.js.map +1 -0
  112. package/dist/infrastructure/parser/implementations/GoParser.d.ts +25 -0
  113. package/dist/infrastructure/parser/implementations/GoParser.d.ts.map +1 -0
  114. package/dist/infrastructure/parser/implementations/GoParser.js +158 -0
  115. package/dist/infrastructure/parser/implementations/GoParser.js.map +1 -0
  116. package/dist/infrastructure/parser/implementations/PythonParser.d.ts +30 -0
  117. package/dist/infrastructure/parser/implementations/PythonParser.d.ts.map +1 -0
  118. package/dist/infrastructure/parser/implementations/PythonParser.js +201 -0
  119. package/dist/infrastructure/parser/implementations/PythonParser.js.map +1 -0
  120. package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts +63 -0
  121. package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts.map +1 -0
  122. package/dist/infrastructure/parser/implementations/TypeScriptParser.js +420 -0
  123. package/dist/infrastructure/parser/implementations/TypeScriptParser.js.map +1 -0
  124. package/dist/infrastructure/parser/index.d.ts +13 -0
  125. package/dist/infrastructure/parser/index.d.ts.map +1 -0
  126. package/dist/infrastructure/parser/index.js +32 -0
  127. package/dist/infrastructure/parser/index.js.map +1 -0
  128. package/dist/infrastructure/parser/interfaces/ParserBase.d.ts +124 -0
  129. package/dist/infrastructure/parser/interfaces/ParserBase.d.ts.map +1 -0
  130. package/dist/infrastructure/parser/interfaces/ParserBase.js +200 -0
  131. package/dist/infrastructure/parser/interfaces/ParserBase.js.map +1 -0
  132. package/dist/infrastructure/parser/registry/ParserRegistry.d.ts +68 -0
  133. package/dist/infrastructure/parser/registry/ParserRegistry.d.ts.map +1 -0
  134. package/dist/infrastructure/parser/registry/ParserRegistry.js +116 -0
  135. package/dist/infrastructure/parser/registry/ParserRegistry.js.map +1 -0
  136. package/dist/infrastructure/repositories/CodeGraphRepositoryImpl.d.ts +44 -0
  137. package/dist/infrastructure/repositories/CodeGraphRepositoryImpl.d.ts.map +1 -0
  138. package/dist/infrastructure/repositories/CodeGraphRepositoryImpl.js +129 -0
  139. package/dist/infrastructure/repositories/CodeGraphRepositoryImpl.js.map +1 -0
  140. package/dist/infrastructure/repositories/index.d.ts +3 -0
  141. package/dist/infrastructure/repositories/index.d.ts.map +1 -0
  142. package/dist/infrastructure/repositories/index.js +7 -0
  143. package/dist/infrastructure/repositories/index.js.map +1 -0
  144. package/dist/infrastructure/storage/StorageFactory.d.ts +53 -0
  145. package/dist/infrastructure/storage/StorageFactory.d.ts.map +1 -0
  146. package/dist/infrastructure/storage/StorageFactory.js +150 -0
  147. package/dist/infrastructure/storage/StorageFactory.js.map +1 -0
  148. package/dist/infrastructure/storage/adapters/FileSystemStorage.d.ts +52 -0
  149. package/dist/infrastructure/storage/adapters/FileSystemStorage.d.ts.map +1 -0
  150. package/dist/infrastructure/storage/adapters/FileSystemStorage.js +315 -0
  151. package/dist/infrastructure/storage/adapters/FileSystemStorage.js.map +1 -0
  152. package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts +52 -0
  153. package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts.map +1 -0
  154. package/dist/infrastructure/storage/adapters/KuzuDBStorage.js +235 -0
  155. package/dist/infrastructure/storage/adapters/KuzuDBStorage.js.map +1 -0
  156. package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts +37 -0
  157. package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts.map +1 -0
  158. package/dist/infrastructure/storage/adapters/MemoryStorage.js +229 -0
  159. package/dist/infrastructure/storage/adapters/MemoryStorage.js.map +1 -0
  160. package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts +49 -0
  161. package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts.map +1 -0
  162. package/dist/infrastructure/storage/adapters/Neo4jStorage.js +222 -0
  163. package/dist/infrastructure/storage/adapters/Neo4jStorage.js.map +1 -0
  164. package/dist/infrastructure/storage/index.d.ts +6 -0
  165. package/dist/infrastructure/storage/index.d.ts.map +1 -0
  166. package/dist/infrastructure/storage/index.js +13 -0
  167. package/dist/infrastructure/storage/index.js.map +1 -0
  168. package/dist/infrastructure/storage/interfaces/StorageBase.d.ts +76 -0
  169. package/dist/infrastructure/storage/interfaces/StorageBase.d.ts.map +1 -0
  170. package/dist/infrastructure/storage/interfaces/StorageBase.js +116 -0
  171. package/dist/infrastructure/storage/interfaces/StorageBase.js.map +1 -0
  172. package/dist/interface/config/index.d.ts +102 -0
  173. package/dist/interface/config/index.d.ts.map +1 -0
  174. package/dist/interface/config/index.js +7 -0
  175. package/dist/interface/config/index.js.map +1 -0
  176. package/dist/interface/types/index.d.ts +425 -0
  177. package/dist/interface/types/index.d.ts.map +1 -0
  178. package/dist/interface/types/index.js +8 -0
  179. package/dist/interface/types/index.js.map +1 -0
  180. package/dist/interface/types/parser.d.ts +103 -0
  181. package/dist/interface/types/parser.d.ts.map +1 -0
  182. package/dist/interface/types/parser.js +7 -0
  183. package/dist/interface/types/parser.js.map +1 -0
  184. package/dist/interface/types/storage.d.ts +98 -0
  185. package/dist/interface/types/storage.d.ts.map +1 -0
  186. package/dist/interface/types/storage.js +7 -0
  187. package/dist/interface/types/storage.js.map +1 -0
  188. package/dist/orchestrator/test-linker.js +1 -1
  189. package/dist/orchestrator/test-linker.js.map +1 -1
  190. package/dist/server/CodeMapServer.d.ts +51 -0
  191. package/dist/server/CodeMapServer.d.ts.map +1 -0
  192. package/dist/server/CodeMapServer.js +146 -0
  193. package/dist/server/CodeMapServer.js.map +1 -0
  194. package/dist/server/handlers/AnalysisHandler.d.ts +82 -0
  195. package/dist/server/handlers/AnalysisHandler.d.ts.map +1 -0
  196. package/dist/server/handlers/AnalysisHandler.js +196 -0
  197. package/dist/server/handlers/AnalysisHandler.js.map +1 -0
  198. package/dist/server/handlers/QueryHandler.d.ts +57 -0
  199. package/dist/server/handlers/QueryHandler.d.ts.map +1 -0
  200. package/dist/server/handlers/QueryHandler.js +260 -0
  201. package/dist/server/handlers/QueryHandler.js.map +1 -0
  202. package/dist/server/index.d.ts +7 -0
  203. package/dist/server/index.d.ts.map +1 -0
  204. package/dist/server/index.js +13 -0
  205. package/dist/server/index.js.map +1 -0
  206. package/dist/server/routes/api.d.ts +8 -0
  207. package/dist/server/routes/api.d.ts.map +1 -0
  208. package/dist/server/routes/api.js +372 -0
  209. package/dist/server/routes/api.js.map +1 -0
  210. package/dist/server/types/index.d.ts +171 -0
  211. package/dist/server/types/index.d.ts.map +1 -0
  212. package/dist/server/types/index.js +7 -0
  213. package/dist/server/types/index.js.map +1 -0
  214. package/dist/types/index.d.ts +6 -372
  215. package/dist/types/index.d.ts.map +1 -1
  216. package/dist/types/index.js +9 -3
  217. package/dist/types/index.js.map +1 -1
  218. package/docs/AI_ASSISTANT_SETUP.md +811 -0
  219. package/docs/PUBLISHING.md +162 -0
  220. package/docs/README.md +37 -0
  221. package/docs/SETUP_GUIDE.md +493 -0
  222. package/docs/ai-guide/COMMANDS.md +369 -0
  223. package/docs/ai-guide/INTEGRATION.md +513 -0
  224. package/docs/ai-guide/OUTPUT.md +465 -0
  225. package/docs/ai-guide/PATTERNS.md +409 -0
  226. package/docs/ai-guide/PROMPTS.md +414 -0
  227. package/docs/ai-guide/QUICKSTART.md +114 -0
  228. package/docs/ai-guide/README.md +66 -0
  229. package/docs/archive/AI_INTEGRATION_GUIDE_ARCHIVED.md +391 -0
  230. package/docs/archive/ARCHIVE.md +39 -0
  231. package/docs/archive/MYCLAUDE_GUIDE.md +305 -0
  232. package/docs/archive/PUBLISH_NPM_DESIGN_V1.md +1699 -0
  233. package/docs/archive/PUBLISH_NPM_DESIGN_V2.md +396 -0
  234. package/docs/archive/README.md +29 -0
  235. package/docs/archive/TASK_DESIGN_COVERAGE_REPORT.md +320 -0
  236. package/docs/archive/TEST_SUMMARY.md +140 -0
  237. package/docs/archive/comprehensive_test_report.md +337 -0
  238. package/docs/archive/design-docs/CI_GATEWAY_DESIGN.md +790 -0
  239. package/docs/archive/design-docs/PUBLISH_NPM_DESIGN_FINAL.md +491 -0
  240. package/docs/archive/design-docs/REFACTOR_ARCHITECTURE_OVERVIEW.md +558 -0
  241. package/docs/archive/design-docs/REFACTOR_CONFIDENCE_DESIGN.md +250 -0
  242. package/docs/archive/design-docs/REFACTOR_GIT_ANALYZER_DESIGN.md +791 -0
  243. package/docs/archive/design-docs/REFACTOR_ORCHESTRATOR_DESIGN.md +1071 -0
  244. package/docs/archive/design-docs/REFACTOR_RESULT_FUSION_DESIGN.md +321 -0
  245. package/docs/archive/design-docs/REFACTOR_TEST_LINKER_DESIGN.md +317 -0
  246. package/docs/archive/myclaude.md +1084 -0
  247. package/docs/archive/plans/2026-03-14-go-language-support-design.md +92 -0
  248. package/docs/archive/product-specs/REFACTOR_REQUIREMENTS.md +976 -0
  249. package/docs/archive/scenario-2-deps-analysis.md +353 -0
  250. package/docs/archive/test-report-symbol-search.md +384 -0
  251. package/docs/archive/test-scenario-4-complexity-analysis.md +460 -0
  252. package/docs/archive/test_report_scenario5.md +615 -0
  253. package/docs/archive/test_scenario_3_impact_analysis_report.md +520 -0
  254. package/docs/design-docs/README.md +26 -0
  255. package/docs/exec-plans/MVP3-IMPLEMENTATION-ROADMAP.md +524 -0
  256. package/docs/exec-plans/README.md +29 -0
  257. package/docs/exec-plans/active/.gitkeep +0 -0
  258. package/docs/exec-plans/completed/.gitkeep +0 -0
  259. package/docs/exec-plans/completed/2026-03-03-deps-path-extension-fix.md +186 -0
  260. package/docs/exec-plans/completed/2026-03-03-post-task-plan.md +135 -0
  261. package/docs/exec-plans/completed/harness-engineering-rollout.md +184 -0
  262. package/docs/exec-plans/tech-debt/.gitkeep +0 -0
  263. package/docs/exec-plans/tech-debt/2026-03-15-lint-guardrail-gap.md +30 -0
  264. package/docs/generated/README.md +19 -0
  265. package/docs/product-specs/MVP3-ARCHITECTURE-COMPARISON.md +504 -0
  266. package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-PRD.md +322 -0
  267. package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-TECH-PRD.md +1374 -0
  268. package/docs/product-specs/README.md +22 -0
  269. package/docs/references/README.md +15 -0
  270. package/docs/references/tmp.md +527 -0
  271. package/docs/rules/README.md +16 -0
  272. package/docs/rules/architecture-guardrails.md +349 -0
  273. package/docs/rules/code-quality-redlines.md +321 -0
  274. package/docs/rules/deployment.md +23 -0
  275. package/docs/rules/engineering-with-codex-openai.md +202 -0
  276. package/docs/rules/testing.md +73 -0
  277. package/docs/rules/validation.md +39 -0
  278. package/examples/README.md +61 -0
  279. package/examples/claude/codemap-skill.md +94 -0
  280. package/examples/codex/codemap-agent.md +66 -0
  281. package/examples/copilot/copilot-instructions.md +24 -0
  282. package/examples/kimi/codemap-skill.md +92 -0
  283. package/package.json +22 -7
@@ -0,0 +1,790 @@
1
+ # CI 门禁护栏详细设计
2
+
3
+ > 归档时间:2026-03-15
4
+ > 归档原因:历史 CI 设计稿,已被现行规则、hooks 和工作流实现替代。
5
+ > 当前依据:`docs/rules/engineering-with-codex-openai.md`、`docs/rules/validation.md`、`.githooks/pre-commit`、`.github/workflows/ci-gateway.yml`
6
+ > 状态:仅供历史对照,不作为当前执行依据。
7
+
8
+
9
+ > 版本: 1.3
10
+ > 所属模块: CI/CD - Git 工作流门禁
11
+ > 日期: 2026-03-04
12
+
13
+ ---
14
+
15
+ ## 1. 设计目标
16
+
17
+ 建立双层次 CI 门禁护栏,确保代码质量:
18
+
19
+ 1. **本地门禁** (pre-commit hook):快速反馈,提交前检查
20
+ 2. **服务端门禁** (GitHub Actions):最终把关,PR 合并前检查
21
+
22
+ **极简原则**:
23
+ - 总代码量 < 150 行
24
+ - 纯文本输出,无 emoji、无颜色(AI 可解析)
25
+ - 强制标签化 Commit,回答苏格拉底问题
26
+
27
+ ---
28
+
29
+ ## 2. 门禁检查项
30
+
31
+ ### 2.1 检查项清单
32
+
33
+ | 层级 | 检查项 | 失败处理 | 实现方式 |
34
+ |------|--------|----------|----------|
35
+ | **本地** | 测试通过 | ❌ 阻止提交 | `npm test` |
36
+ | **本地** | Commit 格式 | ❌ 阻止提交 | commit-msg hook |
37
+ | **本地** | 文件头注释 | ❌ 阻止提交 | pre-commit hook |
38
+ | **本地** | Commit 文件数量 | ❌ 阻止提交 | commit-msg hook / pre-commit hook |
39
+ | **本地** | 生成代码地图 | ⚠️ 警告 | `codemap generate` |
40
+ | **服务端** | 测试通过 | ❌ 阻止合并 | `npm test` |
41
+ | **服务端** | Commit 格式 | ❌ 阻止合并 | `codemap ci check-commits` |
42
+ | **服务端** | Commit 文件数量 | ❌ 阻止合并 | `codemap ci check-commit-size` |
43
+ | **服务端** | 文件头注释 | ❌ 阻止合并 | `codemap ci check-headers` |
44
+ | **服务端** | 代码地图同步 | ❌ 阻止合并 | `git diff --exit-code` |
45
+ | **服务端** | 危险置信度 | ❌ 阻止合并 | `codemap ci assess-risk` |
46
+ | **服务端** | 输出契约校验 | ❌ 阻止合并 | `codemap ci check-output-contract` |
47
+
48
+ ---
49
+
50
+ ## 3. 本地门禁实现
51
+
52
+ ### 3.1 commit-msg Hook
53
+
54
+ **文件**: `.git/hooks/commit-msg`
55
+
56
+ ```bash
57
+ #!/bin/sh
58
+ # Commit-msg hook: 验证 Commit 消息格式和文件数量
59
+
60
+ MSG_FILE=$1
61
+ MSG=$(head -1 "$MSG_FILE")
62
+
63
+ VALID_TAGS="BUGFIX FEATURE REFACTOR CONFIG DOCS DELETE"
64
+
65
+ # 1. 检查 commit 格式
66
+ if ! echo "$MSG" | grep -qE '^\[(BUGFIX|FEATURE|REFACTOR|CONFIG|DOCS|DELETE)\]'; then
67
+ echo "ERROR: Commit message must start with an uppercase tag."
68
+ echo "Format: [TAG] scope: message"
69
+ echo "Valid tags: $VALID_TAGS"
70
+ exit 1
71
+ fi
72
+
73
+ if ! echo "$MSG" | grep -qE '^\[(BUGFIX|FEATURE|REFACTOR|CONFIG|DOCS|DELETE)\]\s+[^:]+:\s+.+'; then
74
+ echo "ERROR: scope and message are required."
75
+ echo "Format: [TAG] scope: message"
76
+ echo "Example: [FEATURE] cli: add new command"
77
+ exit 1
78
+ fi
79
+
80
+ # 2. 检查 commit 文件数量(初始化 commit 除外)
81
+ MAX_FILES_PER_COMMIT=10
82
+ COMMIT_FILE_COUNT=$(git diff-tree --no-commit-id --name-only -r HEAD 2>/dev/null | wc -l)
83
+
84
+ IS_INITIAL_COMMIT=false
85
+ if [ -z "$(git rev-parse --verify HEAD 2>/dev/null)" ]; then
86
+ IS_INITIAL_COMMIT=true
87
+ fi
88
+
89
+ if [ "$COMMIT_FILE_COUNT" -gt "$MAX_FILES_PER_COMMIT" ] && [ "$IS_INITIAL_COMMIT" = "false" ]; then
90
+ echo "ERROR: Commit contains $COMMIT_FILE_COUNT files, exceeding limit of $MAX_FILES_PER_COMMIT"
91
+ echo "Please split your changes into smaller, focused commits."
92
+ exit 1
93
+ fi
94
+
95
+ echo "Commit message validated"
96
+ exit 0
97
+ ```
98
+
99
+ ### 3.2 Commit 文件数量检查
100
+
101
+ **规则**: 单 commit 文件数量不能超过 **10 个**,超过需要合理理由。
102
+
103
+ **豁免情况**:
104
+ - **初始化 commit**: 仓库的第一个 commit 可以超过 10 个文件
105
+ - **特殊场景**: 需要提供充分的理由说明(在 commit body 中解释)
106
+
107
+ **本地检查**:
108
+ - pre-commit hook 检查 staged 文件数量
109
+ - commit-msg hook 检查最终 commit 的文件数量
110
+
111
+ **服务端检查**:
112
+ - `codemap ci check-commit-size` 检查范围内的所有 commit
113
+
114
+ **有效例外场景**:
115
+ 1. 批量依赖更新(包含 lock 文件变更)
116
+ 2. 自动化代码生成结果
117
+ 3. 大规模重构(无逻辑变更)
118
+
119
+ **拆分大型 commit 的方法**:
120
+ ```bash
121
+ # 撤销最后一次 commit(保留改动)
122
+ git reset HEAD~1
123
+
124
+ # 选择性添加文件
125
+ git add -p
126
+
127
+ # 分批次提交
128
+ git commit -m "[FEATURE] module-a: add feature X"
129
+ git add <more-files>
130
+ git commit -m "[FEATURE] module-b: add feature Y"
131
+ ```
132
+
133
+ ### 3.4 pre-commit Hook
134
+
135
+ **文件**: `.git/hooks/pre-commit`
136
+
137
+ ```bash
138
+ #!/bin/sh
139
+ # Pre-commit hook: 运行测试和文件头检查
140
+
141
+ echo "Running pre-commit checks..."
142
+
143
+ # 1. 运行与变更相关的测试(失败即阻断)
144
+ echo "Running tests for changed files..."
145
+ npx vitest run --changed
146
+ if [ $? -ne 0 ]; then
147
+ echo "ERROR: Tests failed, commit rejected"
148
+ exit 1
149
+ fi
150
+
151
+ echo "Tests passed"
152
+
153
+ # 2. 检查 staged 文件数量(初始化 commit 除外)
154
+ MAX_FILES_PER_COMMIT=10
155
+ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | wc -l)
156
+
157
+ IS_INITIAL_COMMIT=false
158
+ git rev-parse --verify HEAD >/dev/null 2>&1
159
+ if [ $? -ne 0 ]; then
160
+ IS_INITIAL_COMMIT=true
161
+ fi
162
+
163
+ if [ "$STAGED_FILES" -gt "$MAX_FILES_PER_COMMIT" ] && [ "$IS_INITIAL_COMMIT" = "false" ]; then
164
+ echo "WARNING: Staged files count ($STAGED_FILES) exceeds limit ($MAX_FILES_PER_COMMIT)"
165
+ echo "Single commit should not contain more than $MAX_FILES_PER_COMMIT files."
166
+ echo "Please consider splitting your changes into smaller, focused commits."
167
+ exit 1
168
+ fi
169
+
170
+ # 3. 检查文件头注释(只检查 staged 的 TS 源文件)
171
+ echo "Checking file headers..."
172
+ STAGED_TS_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.ts$' | grep -v '\.test\.ts$' | grep -v '\.d\.ts$')
173
+
174
+ if [ -n "$STAGED_TS_FILES" ]; then
175
+ MISSING_HEADERS=0
176
+ for file in $STAGED_TS_FILES; do
177
+ if [ ! -f "$file" ]; then
178
+ continue
179
+ fi
180
+ HEAD_CONTENT=$(head -10 "$file")
181
+ if ! echo "$HEAD_CONTENT" | grep -q '\[META\]'; then
182
+ echo "ERROR: $file missing [META] comment"
183
+ MISSING_HEADERS=$((MISSING_HEADERS + 1))
184
+ fi
185
+ if ! echo "$HEAD_CONTENT" | grep -q '\[WHY\]'; then
186
+ echo "ERROR: $file missing [WHY] comment"
187
+ MISSING_HEADERS=$((MISSING_HEADERS + 1))
188
+ fi
189
+ done
190
+
191
+ if [ $MISSING_HEADERS -gt 0 ]; then
192
+ echo "Add header comments at file top:"
193
+ echo "// [META] since:YYYY-MM | owner:team | stable:false"
194
+ echo "// [WHY] Explain why this file exists"
195
+ exit 1
196
+ fi
197
+ fi
198
+
199
+ echo "File headers passed"
200
+
201
+ # 4. 生成 AI 饲料(警告级,不阻断)
202
+ echo "Generating AI feed..."
203
+ npx mycodemap generate --quiet >/dev/null 2>&1 &
204
+
205
+ echo "Pre-commit checks passed"
206
+ exit 0
207
+ ```
208
+
209
+ ### 3.3 Husky 集成(推荐)
210
+
211
+ **安装**: `npm install husky --save-dev`
212
+
213
+ **package.json**:
214
+ ```json
215
+ {
216
+ "scripts": {
217
+ "prepare": "husky install",
218
+ "test": "vitest run"
219
+ },
220
+ "devDependencies": {
221
+ "husky": "^8.0.0"
222
+ }
223
+ }
224
+ ```
225
+
226
+ **初始化**:
227
+ ```bash
228
+ npx husky install
229
+ npx husky add .husky/commit-msg 'node scripts/verify-commit.js "$1"'
230
+ npx husky add .husky/pre-commit 'npm test && node scripts/check-headers.js'
231
+ ```
232
+
233
+ ---
234
+
235
+ ## 4. 服务端门禁实现
236
+
237
+ ### 4.1 GitHub Actions Workflow
238
+
239
+ **文件**: `.github/workflows/ci-gateway.yml`
240
+
241
+ ```yaml
242
+ name: CI Gateway
243
+
244
+ on:
245
+ push:
246
+ branches: [ main, develop ]
247
+ pull_request:
248
+ branches: [ main, develop ]
249
+
250
+ jobs:
251
+ ci-gateway:
252
+ runs-on: ubuntu-latest
253
+
254
+ steps:
255
+ - name: Checkout
256
+ uses: actions/checkout@v4
257
+ with:
258
+ fetch-depth: 0 # 需要完整历史检查 commit
259
+
260
+ - name: Setup Node.js
261
+ uses: actions/setup-node@v4
262
+ with:
263
+ node-version: '20'
264
+ cache: 'npm'
265
+
266
+ - name: Install dependencies
267
+ run: npm ci
268
+
269
+ # 1. 运行测试
270
+ - name: Run tests
271
+ run: npm test
272
+
273
+ # 2. 检查 Commit 格式
274
+ - name: Check commit format
275
+ run: npx codemap ci check-commits
276
+
277
+ # 3. 检查 Commit 文件数量
278
+ - name: Check commit size
279
+ run: npx codemap ci check-commit-size
280
+
281
+ # 4. 检查文件头注释
282
+ - name: Check file headers
283
+ run: npx codemap ci check-headers
284
+
285
+ # 5. 生成代码地图并检查同步
286
+ - name: Generate code map
287
+ run: |
288
+ npx codemap generate
289
+ git diff --exit-code .mycodemap/ || (echo "Code map is out of sync. Run 'codemap generate' and commit the changes." && exit 1)
290
+
291
+ # 6. 评估危险置信度
292
+ - name: Assess risk
293
+ run: npx codemap ci assess-risk --threshold=0.7
294
+
295
+ # 6. 输出契约检查(machine/json)
296
+ - name: Check output contract
297
+ run: npx codemap ci check-output-contract --schema-version v1.0.0 --top-k 8 --max-tokens 160
298
+ ```
299
+
300
+ ### 4.2 CI 子命令实现
301
+
302
+ **文件**: `src/cli/commands/ci.ts`
303
+
304
+ ```typescript
305
+ // src/cli/commands/ci.ts
306
+ // 极简实现: ~80 行
307
+
308
+ import { Command } from 'commander';
309
+ import { execSync } from 'child_process';
310
+ import { GitAnalyzer } from '../../orchestrator/git-analyzer.js';
311
+ import { FileHeaderScanner } from '../../orchestrator/file-header-scanner.js';
312
+ import { globby } from 'globby';
313
+
314
+ const ci = new Command('ci').description('CI gateway commands');
315
+
316
+ // 检查 Commit 格式
317
+ ci.command('check-commits')
318
+ .description('Validate commit message format')
319
+ .action(() => {
320
+ const analyzer = new GitAnalyzer();
321
+ const commits = execSync('git log --format=%s origin/main..HEAD', { encoding: 'utf-8' })
322
+ .split('\n')
323
+ .filter(Boolean);
324
+
325
+ let errors = 0;
326
+ for (const msg of commits) {
327
+ const tag = analyzer.parseCommitTag(msg);
328
+ if (!tag) {
329
+ console.error(`ERROR: Invalid commit format: "${msg}"`);
330
+ errors++;
331
+ }
332
+ }
333
+
334
+ if (errors > 0) {
335
+ console.error(`\n${errors} commits failed validation`);
336
+ process.exit(1);
337
+ }
338
+
339
+ console.log(`✓ ${commits.length} commits validated`);
340
+ });
341
+
342
+ // 检查文件头注释
343
+ ci.command('check-headers')
344
+ .description('Validate file header comments')
345
+ .action(async () => {
346
+ const scanner = new FileHeaderScanner();
347
+ const files = await globby(['src/**/*.ts', '!src/**/*.test.ts']);
348
+
349
+ let errors = 0;
350
+ for (const file of files) {
351
+ const result = scanner.validate(file);
352
+ if (!result.valid) {
353
+ console.error(`ERROR: ${file} missing: ${result.missing.join(', ')}`);
354
+ errors++;
355
+ }
356
+ }
357
+
358
+ if (errors > 0) {
359
+ console.error(`\n${errors} files missing required headers`);
360
+ process.exit(1);
361
+ }
362
+
363
+ console.log(`✓ ${files.length} files validated`);
364
+ });
365
+
366
+ // 评估危险置信度(简化版,不依赖 AI Feed)
367
+ ci.command('assess-risk')
368
+ .description('Assess risk level of changes')
369
+ .option('-t, --threshold <n>', 'Risk threshold (0-1)', '0.7')
370
+ .action(async (options) => {
371
+ const changedFiles = execSync('git diff --name-only origin/main...HEAD', { encoding: 'utf-8' })
372
+ .split('\n')
373
+ .filter(f => f.endsWith('.ts') && !f.endsWith('.test.ts'));
374
+
375
+ if (changedFiles.length === 0) {
376
+ console.log('✓ No changed TypeScript files');
377
+ return;
378
+ }
379
+
380
+ // 简化版风险评估:基于文件数量和变更范围
381
+ let riskScore = 0.3; // 基础风险
382
+
383
+ // 文件数量风险
384
+ if (changedFiles.length > 10) {
385
+ riskScore += 0.2;
386
+ }
387
+ if (changedFiles.length > 20) {
388
+ riskScore += 0.2;
389
+ }
390
+
391
+ // 核心文件变更风险
392
+ const coreFiles = changedFiles.filter(f =>
393
+ f.includes('/core/') ||
394
+ f.includes('/orchestrator/') ||
395
+ f.endsWith('/index.ts')
396
+ );
397
+ if (coreFiles.length > 0) {
398
+ riskScore += 0.15;
399
+ }
400
+
401
+ riskScore = Math.min(1, riskScore);
402
+
403
+ console.log(`Risk assessment: score=${riskScore.toFixed(2)}, threshold=${options.threshold}`);
404
+
405
+ if (riskScore > parseFloat(options.threshold)) {
406
+ console.log('ERROR: Risk score exceeds threshold');
407
+ console.log(`Changed files: ${changedFiles.length}`);
408
+ console.log('Risk mitigation notes required. Add explanation to commit body.');
409
+ process.exit(1);
410
+ } else {
411
+ console.log('✓ Risk assessment passed');
412
+ }
413
+ });
414
+
415
+ // 检查 Commit 文件数量
416
+ ci.command('check-commit-size')
417
+ .description('Check if commit file count exceeds limit (init commit exempt)')
418
+ .option('-r, --range <range>', 'Git log range to check', 'origin/main..HEAD')
419
+ .option('-m, --max-files <number>', 'Max files per commit', '10')
420
+ .action(async (options) => {
421
+ const maxFiles = parseInt(options.maxFiles, 10);
422
+ const { execSync } = require('child_process');
423
+
424
+ const range = options.range || 'origin/main..HEAD';
425
+ const commits = execSync(`git log --format=%H ${range}`, { encoding: 'utf-8' })
426
+ .split('\n')
427
+ .filter(Boolean);
428
+
429
+ let hasErrors = false;
430
+
431
+ for (const hash of commits) {
432
+ const message = execSync(`git log -1 --format=%s ${hash}`, { encoding: 'utf-8' }).trim();
433
+ const fileCount = parseInt(
434
+ execSync(`git diff-tree --no-commit-id --name-only -r ${hash} | wc -l`, { encoding: 'utf-8' }).trim(),
435
+ 10
436
+ );
437
+
438
+ if (fileCount > maxFiles) {
439
+ console.error(`ERROR: Commit ${hash.substring(0, 7)} has ${fileCount} files (limit: ${maxFiles})`);
440
+ console.error(` Message: ${message}`);
441
+ hasErrors = true;
442
+ }
443
+ }
444
+
445
+ if (hasErrors) {
446
+ console.error('\nLarge commits detected. Please split your changes.');
447
+ process.exit(1);
448
+ }
449
+
450
+ console.log(`All ${commits.length} commits pass file count check`);
451
+ });
452
+
453
+ // 输出契约校验 (P1-1 新增)
454
+ ci.command('check-output-contract')
455
+ .description('Validate output contract (schemaVersion, Top-K, token limit)')
456
+ .option('-s, --schema-version <version>', 'Expected schema version', 'v1.0.0')
457
+ .option('-k, --top-k <number>', 'Expected Top-K limit', '8')
458
+ .option('-t, --max-tokens <number>', 'Max tokens per result', '160')
459
+ .action(async (options) => {
460
+ const schemaVersion = options.schemaVersion || 'v1.0.0';
461
+ const topK = parseInt(options.topK) || 8;
462
+ const maxTokens = parseInt(options.maxTokens) || 160;
463
+
464
+ // 运行 analyze 命令获取输出(machine 模式必须为纯 JSON)
465
+ const { execSync } = require('child_process');
466
+ let output;
467
+ try {
468
+ output = execSync('npx codemap analyze --intent search --keywords test --output-mode machine --json', {
469
+ encoding: 'utf-8',
470
+ timeout: 30000
471
+ });
472
+ } catch (error) {
473
+ // 如果命令失败,尝试其他方式获取输出
474
+ console.error('ERROR: Failed to run analyze command');
475
+ process.exit(1);
476
+ }
477
+
478
+ let parsed;
479
+ try {
480
+ parsed = JSON.parse(output);
481
+ } catch {
482
+ console.error('ERROR: Invalid JSON output');
483
+ process.exit(1);
484
+ }
485
+
486
+ let errors = 0;
487
+
488
+ // 1. 校验 schemaVersion
489
+ if (!parsed.schemaVersion) {
490
+ console.error('ERROR: Missing schemaVersion in output');
491
+ errors++;
492
+ } else if (parsed.schemaVersion !== schemaVersion) {
493
+ console.error(`ERROR: schemaVersion mismatch: expected ${schemaVersion}, got ${parsed.schemaVersion}`);
494
+ errors++;
495
+ }
496
+
497
+ // 2. 校验 Top-K
498
+ const resultCount = parsed.results?.length || 0;
499
+ if (resultCount > topK) {
500
+ console.error(`ERROR: Result count ${resultCount} exceeds Top-K limit ${topK}`);
501
+ errors++;
502
+ }
503
+
504
+ // 3. 校验 token 限制 (简单估算)
505
+ if (parsed.results) {
506
+ for (const result of parsed.results) {
507
+ const tokenEstimate = result.content?.split(/[\s\u4e00-\u9fa5]/).filter(Boolean).length || 0;
508
+ if (tokenEstimate > maxTokens) {
509
+ console.error(`ERROR: Result token count ${tokenEstimate} exceeds limit ${maxTokens}`);
510
+ errors++;
511
+ break; // 只报告一次
512
+ }
513
+ }
514
+ }
515
+
516
+ if (errors > 0) {
517
+ console.error(`\n${errors} output contract violations detected`);
518
+ process.exit(1);
519
+ }
520
+
521
+ console.log(`✓ Output contract validated (schema: ${schemaVersion}, topK: ≤${topK}, tokens: ≤${maxTokens})`);
522
+ });
523
+
524
+ export default ci;
525
+ ```
526
+
527
+ ---
528
+
529
+ ## 5. 文件头注释模板
530
+
531
+ ### 5.1 自动添加脚本
532
+
533
+ **文件**: `scripts/add-headers.js`
534
+
535
+ ```javascript
536
+ #!/usr/bin/env node
537
+ // 自动添加文件头注释模板
538
+
539
+ import fs from 'fs';
540
+ import { globby } from 'globby';
541
+
542
+ const TEMPLATE = `// [META] since:2024-03 | owner:backend-team | stable:false
543
+ // [WHY] TODO: 回答为什么存在这个文件
544
+
545
+ `;
546
+
547
+ async function main() {
548
+ const files = await globby(['src/**/*.ts', '!src/**/*.test.ts']);
549
+
550
+ for (const file of files) {
551
+ const content = fs.readFileSync(file, 'utf-8');
552
+
553
+ if (!content.includes('[META]')) {
554
+ const newContent = TEMPLATE + content;
555
+ fs.writeFileSync(file, newContent);
556
+ console.log(`Updated: ${file}`);
557
+ }
558
+ }
559
+
560
+ console.log(`\nProcessed ${files.length} files`);
561
+ console.log('Please edit [WHY] comments to explain file purpose');
562
+ }
563
+
564
+ main();
565
+ ```
566
+
567
+ **使用**:
568
+ ```bash
569
+ node scripts/add-headers.js
570
+ ```
571
+
572
+ ---
573
+
574
+ ## 6. 迁移指南
575
+
576
+ ### 6.1 现有项目迁移步骤
577
+
578
+ 1. **安装依赖**:
579
+ ```bash
580
+ npm install husky --save-dev
581
+ npm install
582
+ ```
583
+
584
+ 2. **初始化 hooks**:
585
+ ```bash
586
+ npx husky install
587
+ npx husky add .husky/commit-msg 'node scripts/verify-commit.js "$1"'
588
+ npx husky add .husky/pre-commit 'npm test && node scripts/check-headers.js'
589
+ ```
590
+
591
+ 3. **批量添加文件头**:
592
+ ```bash
593
+ node scripts/add-headers.js
594
+ # 然后手动编辑 [WHY] 注释
595
+ ```
596
+
597
+ 4. **更新现有 Commit**(可选):
598
+ ```bash
599
+ # 修改最后一次 commit
600
+ git commit --amend -m "[REFACTOR] project: add CI gateway and file headers"
601
+ ```
602
+
603
+ ### 6.2 Commit 格式转换示例
604
+
605
+ | 旧格式 | 新格式 |
606
+ |--------|--------|
607
+ | `fix: bug in parser` | `[BUGFIX] parser: fix token handling bug` |
608
+ | `add new feature` | `[FEATURE] cli: add analyze command` |
609
+ | `update docs` | `[DOCS] readme: update installation guide` |
610
+ | `refactor cache` | `[REFACTOR] cache: simplify LRU implementation` |
611
+
612
+ ---
613
+
614
+ ## 7. 失败场景处理
615
+
616
+ ### 7.1 本地提交失败
617
+
618
+ ```bash
619
+ $ git commit -m "fix bug"
620
+ ERROR: 提交信息必须以大写标签开头
621
+
622
+ 格式: [TAG] scope: message
623
+
624
+ 允许的 TAG:
625
+ [BUGFIX] - 修复问题
626
+ [FEATURE] - 新功能
627
+ [REFACTOR] - 重构
628
+ [CONFIG] - 配置变更
629
+ [DOCS] - 文档
630
+ [DELETE] - 删除代码
631
+
632
+ 示例:
633
+ [BUGFIX] git-analyzer: fix risk score calculation
634
+ ```
635
+
636
+ ### 7.2 服务端 PR 失败
637
+
638
+ GitHub Actions 会显示:
639
+ - ❌ Tests failed
640
+ - ❌ Invalid commit format
641
+ - ❌ Missing file headers
642
+ - ⚠️ High risk files detected
643
+
644
+ ---
645
+
646
+ ## 8. 模块依赖
647
+
648
+ ```
649
+ CI Gateway
650
+
651
+ ├── Git Hooks
652
+ │ ├── commit-msg (验证格式)
653
+ │ └── pre-commit (测试+文件头)
654
+
655
+ ├── GitHub Actions
656
+ │ └── .github/workflows/ci-gateway.yml
657
+
658
+ ├── CLI Commands (src/cli/commands/ci.ts)
659
+ │ ├── check-commits
660
+ │ ├── check-commit-size (v1.3 新增)
661
+ │ ├── check-headers
662
+ │ ├── assess-risk (简化版)
663
+ │ └── check-output-contract (P1-1 新增)
664
+
665
+ └── Dependencies
666
+ ├── GitAnalyzer (解析 commit tag)
667
+ └── FileHeaderScanner (验证注释)
668
+ ```
669
+
670
+ ---
671
+
672
+ ## 9. 工作流集成 (v2.5 规划)
673
+
674
+ ### 9.1 工作流阶段的 CI 验证
675
+
676
+ 在编排层工作流中,CI 门禁作为最后一个阶段自动执行:
677
+
678
+ ```typescript
679
+ // 工作流阶段的 CI 集成
680
+
681
+ const PHASE_CI_CONFIG: Record<WorkflowPhase, CIConfig> = {
682
+ reference: {
683
+ preChecks: [],
684
+ postChecks: [],
685
+ required: false
686
+ },
687
+ impact: {
688
+ preChecks: [],
689
+ postChecks: [],
690
+ required: false
691
+ },
692
+ risk: {
693
+ preChecks: ['assess-risk'],
694
+ postChecks: [],
695
+ required: true
696
+ },
697
+ implementation: {
698
+ preChecks: ['check-headers'],
699
+ postChecks: [],
700
+ required: true
701
+ },
702
+ commit: {
703
+ preChecks: ['check-commits', 'check-headers'],
704
+ postChecks: [],
705
+ required: true
706
+ },
707
+ ci: {
708
+ preChecks: ['check-commits', 'check-headers', 'assess-risk', 'check-output-contract'],
709
+ postChecks: ['npm test'],
710
+ required: true
711
+ }
712
+ };
713
+ ```
714
+
715
+ ### 9.2 工作流 CI 执行器
716
+
717
+ ```typescript
718
+ class WorkflowCIExecutor {
719
+ private ciCommands: Map<string, () => Promise<CICheckResult>>;
720
+
721
+ /**
722
+ * 在指定阶段执行 CI 检查
723
+ */
724
+ async executePhaseChecks(phase: WorkflowPhase): Promise<CIExecutionResult> {
725
+ const config = PHASE_CI_CONFIG[phase];
726
+ const results: CICheckResult[] = [];
727
+
728
+ // 执行预检查
729
+ for (const check of config.preChecks) {
730
+ const executor = this.ciCommands.get(check);
731
+ if (executor) {
732
+ const result = await executor();
733
+ results.push(result);
734
+
735
+ if (!result.passed && config.required) {
736
+ return {
737
+ phase,
738
+ passed: false,
739
+ results,
740
+ failedCheck: check
741
+ };
742
+ }
743
+ }
744
+ }
745
+
746
+ return {
747
+ phase,
748
+ passed: results.every(r => r.passed),
749
+ results
750
+ };
751
+ }
752
+ }
753
+ ```
754
+
755
+ ---
756
+
757
+ ## 10. 检查项汇总
758
+
759
+ | 检查项 | 本地 | 服务端 | 工具 |
760
+ |--------|------|--------|------|
761
+ | 测试通过 | ✅ | ✅ | `npm test` |
762
+ | Commit 格式 `[TAG]` | ✅ | ✅ | `commit-msg hook` / `codemap ci check-commits` |
763
+ | Commit 文件数量 (≤10) | ✅ | ✅ | `commit-msg hook` / `codemap ci check-commit-size` |
764
+ | 文件头 `[META]` | ✅ | ✅ | `pre-commit hook` / `codemap ci check-headers` |
765
+ | 文件头 `[WHY]` | ✅ | ✅ | `pre-commit hook` / `codemap ci check-headers` |
766
+ | 代码地图生成 | ⚠️ | ✅ | `codemap generate` |
767
+ | 危险置信度评估 | ❌ | ✅ (P0-2) | `codemap ci assess-risk` |
768
+ | 输出契约校验 | ❌ | ✅ (P1-1) | `codemap ci check-output-contract` |
769
+
770
+ ---
771
+
772
+ ## 11. 极简实现统计
773
+
774
+ | 组件 | 代码量 | 文件 |
775
+ |------|--------|------|
776
+ | commit-msg hook | ~50 行 | `.git/hooks/commit-msg` |
777
+ | pre-commit hook | ~60 行 | `.git/hooks/pre-commit` |
778
+ | CI 子命令 | ~100 行 | `src/cli/commands/ci.ts` |
779
+ | **总计** | **~210 行** | **符合极简原则** |
780
+
781
+ ---
782
+
783
+ ## 附录:版本历史
784
+
785
+ | 版本 | 日期 | 变更 |
786
+ |------|------|------|
787
+ | 1.0 | 2026-02-28 | 初始版本 |
788
+ | 1.1 | 2026-03-01 | 添加输出契约校验 |
789
+ | 1.2 | 2026-03-03 | 移除 AI 饲料相关功能,简化风险评估 |
790
+ | 1.3 | 2026-03-04 | 添加 commit 文件数量限制检查(≤10 个)|