@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,1071 @@
1
+ # CLI 命令与编排层详细设计
2
+
3
+ > 归档时间:2026-03-15
4
+ > 归档原因:历史编排设计稿,workflow 段落仍保留规划态并混入旧 `.codemap` 路径。
5
+ > 当前依据:`ARCHITECTURE.md`、`src/cli/commands/workflow.ts`、`src/orchestrator/workflow/*`
6
+ > 状态:仅供历史对照,不作为当前执行依据。
7
+
8
+
9
+ > 版本: 2.5
10
+ > 所属模块: 编排层 - CLI 命令与工具编排器
11
+
12
+ ---
13
+
14
+ ## 1. 工具编排器设计
15
+
16
+ ### 1.1 核心类
17
+
18
+ ```typescript
19
+ // src/orchestrator/tool-orchestrator.ts
20
+
21
+ class ToolOrchestrator {
22
+ // 超时配置(毫秒)
23
+ private readonly DEFAULT_TIMEOUT = 30000;
24
+
25
+ // 日志记录器
26
+ private logger = console;
27
+
28
+ // 预定义回退链(仅内部调试用,默认关闭)
29
+ // 用户可见输出必须走 CodeMap 语义链路
30
+ private fallbackChains: Record<string, string[]> = {
31
+ 'ast-grep': ['rg-internal'], // AST搜索 → 文本搜索(内部)
32
+ 'codemap': ['rg-internal'], // 结构分析 → 文本搜索(内部)
33
+ };
34
+ }
35
+ ```
36
+
37
+ ### 1.2 超时控制
38
+
39
+ ```typescript
40
+ /**
41
+ * 带超时控制的工具执行
42
+ */
43
+ async runToolWithTimeout(
44
+ tool: string,
45
+ intent: CodemapIntent,
46
+ timeout: number = this.DEFAULT_TIMEOUT
47
+ ): Promise<UnifiedResult[]> {
48
+ try {
49
+ this.logger.debug(`执行工具: ${tool}, 超时: ${timeout}ms`);
50
+
51
+ const controller = new AbortController();
52
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
53
+
54
+ const results = await this.runTool(tool, intent, { signal: controller.signal });
55
+ clearTimeout(timeoutId);
56
+
57
+ this.logger.debug(`工具 ${tool} 执行成功,返回 ${results.length} 条结果`);
58
+ return results;
59
+ } catch (error) {
60
+ if (error instanceof Error && error.name === 'AbortError') {
61
+ this.logger.warn(`工具 ${tool} 执行超时 (${timeout}ms)`);
62
+ } else {
63
+ this.logger.error(`工具 ${tool} 执行失败: ${error}`);
64
+ }
65
+ // 超时或错误时返回空结果,触发回退
66
+ return [];
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### 1.3 错误隔离
72
+
73
+ ```typescript
74
+ /**
75
+ * 错误隔离的工具执行
76
+ */
77
+ async runToolSafely(
78
+ tool: string,
79
+ intent: CodemapIntent
80
+ ): Promise<{ results: UnifiedResult[]; error?: Error }> {
81
+ try {
82
+ const results = await this.runToolWithTimeout(tool, intent);
83
+ return { results };
84
+ } catch (error) {
85
+ this.logger.error(`工具 ${tool} 执行异常:`, error);
86
+ return { results: [], error: error as Error };
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### 1.4 回退执行
92
+
93
+ ```typescript
94
+ async executeWithFallback(
95
+ intent: CodemapIntent,
96
+ primaryTool: string
97
+ ): Promise<{ results: UnifiedResult[]; tool: string; confidence: ConfidenceResult }> {
98
+ // 1. 执行主工具
99
+ let results = await this.runTool(primaryTool, intent);
100
+ let confidence = calculateConfidence(results, intent.intent);
101
+
102
+ // 2. 检查是否需要回退(低于当前 intent 的中等阈值)
103
+ const threshold = getThreshold(intent.intent, 'medium');
104
+ if (confidence.score < threshold) {
105
+ const fallbackTools = this.fallbackChains[primaryTool] || [];
106
+
107
+ for (const fallbackTool of fallbackTools) {
108
+ console.warn(`[LOW CONFIDENCE] ${primaryTool} confidence: ${confidence.score.toFixed(2)}, trying ${fallbackTool}...`);
109
+
110
+ const fallbackResults = await this.runTool(fallbackTool, intent);
111
+ const fallbackConfidence = calculateConfidence(fallbackResults, intent.intent);
112
+
113
+ // 3. 合并结果(去重 + 排序)
114
+ results = this.mergeResults(results, fallbackResults);
115
+
116
+ // 更新置信度(取最大值)
117
+ confidence = {
118
+ score: Math.max(confidence.score, fallbackConfidence.score),
119
+ level: confidence.score > fallbackConfidence.score ? confidence.level : fallbackConfidence.level,
120
+ reasons: [...confidence.reasons, ...fallbackConfidence.reasons]
121
+ };
122
+
123
+ // 4. 达到阈值则停止回退
124
+ if (confidence.score >= threshold) {
125
+ confidence.reasons.push(`回退到 ${fallbackTool} 后达到阈值`);
126
+ break;
127
+ }
128
+ }
129
+ }
130
+
131
+ return { results, tool: primaryTool, confidence };
132
+ }
133
+ ```
134
+
135
+ ---
136
+
137
+ ## 2. 工具适配器设计
138
+
139
+ ### 2.1 适配器基类
140
+
141
+ ```typescript
142
+ interface ToolAdapter {
143
+ name: string;
144
+ weight: number;
145
+ isAvailable(): Promise<boolean>;
146
+ execute(keywords: string[], options: ToolOptions): Promise<UnifiedResult[]>;
147
+ }
148
+ ```
149
+
150
+ ### 2.2 ast-grep 适配器
151
+
152
+ ```typescript
153
+ // src/orchestrator/adapters/ast-grep-adapter.ts
154
+
155
+ class AstGrepAdapter implements ToolAdapter {
156
+ readonly name = 'ast-grep';
157
+ readonly weight = 1.0;
158
+ private available: boolean | null = null;
159
+
160
+ /**
161
+ * 检测 ast-grep 是否可用
162
+ * 如果不可用,后续调用会自动回退到内部文本兜底链路
163
+ */
164
+ async isAvailable(): Promise<boolean> {
165
+ if (this.available !== null) return this.available;
166
+
167
+ try {
168
+ // 使用 execFile 避免命令注入风险
169
+ await execFile('sg', ['--version']);
170
+ this.available = true;
171
+ } catch {
172
+ this.available = false;
173
+ }
174
+ return this.available;
175
+ }
176
+
177
+ async execute(keywords: string[], options: ToolOptions): Promise<UnifiedResult[]> {
178
+ // 先检查是否可用
179
+ if (!(await this.isAvailable())) {
180
+ throw new Error('ast-grep 不可用');
181
+ }
182
+
183
+ // 使用 spawn/execFile 避免命令注入风险
184
+ const args = ['-p', '.', '--json', ...keywords];
185
+ const { stdout } = await execFile('sg', args);
186
+
187
+ // ast-grep JSON 输出是匹配对象流,每行一个 JSON 对象
188
+ const results: UnifiedResult[] = [];
189
+ const lines = stdout.split('\n').filter(line => line.trim());
190
+
191
+ for (const line of lines) {
192
+ try {
193
+ const r = JSON.parse(line);
194
+ // 兼容两种输出格式:直接对象或 { results: [...] } 包装
195
+ const matches = r.results || [r];
196
+ for (const match of matches) {
197
+ results.push({
198
+ id: `ast-grep-${match.file}-${match.line}`,
199
+ source: 'ast-grep',
200
+ toolScore: match.score || 0.9,
201
+ type: 'code',
202
+ file: match.file,
203
+ line: match.line,
204
+ content: this.truncateByToken(match.content, 160),
205
+ relevance: match.score || 0.9,
206
+ keywords
207
+ });
208
+ }
209
+ } catch {
210
+ // 跳过无法解析的行
211
+ }
212
+ }
213
+
214
+ return results;
215
+ }
216
+
217
+ /**
218
+ * 按 token 数量截断内容
219
+ */
220
+ private truncateByToken(content: string, maxTokens: number): string {
221
+ const tokens = content.split(/[\s\u4e00-\u9fa5]/).filter(Boolean);
222
+ if (tokens.length <= maxTokens) return content;
223
+ return tokens.slice(0, maxTokens).join(' ') + '...';
224
+ }
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## 3. 意图路由设计
231
+
232
+ ### 3.1 路由接口
233
+
234
+ ```typescript
235
+ interface CodemapIntent {
236
+ intent: IntentType;
237
+ targets: string[];
238
+ keywords: string[];
239
+ scope: 'direct' | 'transitive';
240
+ tool: string;
241
+ }
242
+
243
+ class IntentRouter {
244
+ route(args: AnalyzeArgs): CodemapIntent {
245
+ // 根据参数确定 intent 类型
246
+ // ...
247
+ }
248
+ }
249
+ ```
250
+
251
+ ### 3.2 命令映射
252
+
253
+ | analyze 参数 | 底层复用 | 增强点 |
254
+ |--------------|----------|--------|
255
+ | `--intent impact` | `ImpactCommand` | + ast-grep 搜索 + Git 分析 + 置信度 |
256
+ | `--intent dependency` | `DepsCommand` | + Token 裁剪 |
257
+ | `--intent complexity` | `ComplexityCommand` | + Token 裁剪 |
258
+ | `--intent search` | 新实现 | 使用 ast-grep + 置信度 |
259
+ | `--intent overview` | 新实现 | 使用 Codemap 核心 |
260
+ | `--intent documentation` | 新实现 | 使用 codemap 搜索 Markdown 文件 |
261
+ | `--intent refactor` | 新实现 | 使用 ast-grep |
262
+
263
+ ---
264
+
265
+ ## 4. AnalyzeCommand 实现
266
+
267
+ ### 4.1 命令类
268
+
269
+ ```typescript
270
+ // src/cli/commands/analyze.ts
271
+
272
+ export class AnalyzeCommand {
273
+ private orchestrator = new ToolOrchestrator();
274
+ private router = new IntentRouter();
275
+ private fusion = new ResultFusion();
276
+
277
+ // 复用现有命令
278
+ private impactCmd = new ImpactCommand();
279
+ private depsCmd = new DepsCommand();
280
+ private complexityCmd = new ComplexityCommand();
281
+
282
+ async run(args: AnalyzeArgs): Promise<void> {
283
+ const intent = this.router.route(args);
284
+ const outputMode = args.outputMode || 'human';
285
+
286
+ switch (intent.intent) {
287
+ case 'impact':
288
+ // 复用现有 impact + 增强
289
+ const impactResult = await this.impactCmd.run({
290
+ targets: intent.targets,
291
+ scope: intent.scope
292
+ });
293
+ // 额外调用 ast-grep 增强搜索
294
+ const searchResult = await this.orchestrator.runTool('ast-grep', intent.keywords);
295
+ // 融合结果:展平为单一数组
296
+ return this.output(this.fuseResults(...impactResult, ...searchResult));
297
+
298
+ case 'dependency':
299
+ const depsResult = await this.depsCmd.run({ targets: intent.targets });
300
+ return this.output(this.formatOutput(depsResult, args));
301
+
302
+ case 'complexity':
303
+ const complexityResult = await this.complexityCmd.run({ targets: intent.targets });
304
+ return this.output(this.formatOutput(complexityResult, args));
305
+
306
+ case 'search':
307
+ case 'overview':
308
+ case 'documentation':
309
+ case 'refactor':
310
+ // 新功能,走编排器(带置信度和回退)
311
+ const { results, tool, confidence } = await this.orchestrator.executeWithFallback(
312
+ intent,
313
+ intent.tool
314
+ );
315
+ // machine/json 模式禁止额外前缀日志,保证纯 JSON 输出契约
316
+ if (outputMode === 'human' && !args.json) {
317
+ console.log(`Tool: ${tool}, Confidence: ${confidence.level} (${confidence.score.toFixed(2)})`);
318
+ }
319
+ return this.output(results);
320
+ }
321
+ }
322
+
323
+ private fuseResults(...results: UnifiedResult[]): UnifiedResult[] {
324
+ // 展平所有结果
325
+ const allResults = results.flat();
326
+ const byTool = new Map<string, UnifiedResult[]>();
327
+ allResults.forEach(r => {
328
+ const existing = byTool.get(r.source) || [];
329
+ existing.push(r);
330
+ byTool.set(r.source, existing);
331
+ });
332
+ return this.fusion.fuse(byTool, { topK: 8, keywordWeights: {} });
333
+ }
334
+ }
335
+ ```
336
+
337
+ ---
338
+
339
+ ## 5. 向后兼容
340
+
341
+ ### 5.1 ImpactCommand 增强模式
342
+
343
+ ```typescript
344
+ // src/cli/commands/impact.ts
345
+
346
+ export class ImpactCommand {
347
+ // 保持原有接口不变
348
+ async run(args: ImpactArgs): Promise<UnifiedResult[]> {
349
+ // 原有逻辑...
350
+ }
351
+
352
+ // 新增:增强模式(供 analyze 调用)
353
+ async runEnhanced(args: ImpactArgs): Promise<UnifiedResult[]> {
354
+ const basic = await this.run(args);
355
+ return this.toUnifiedResults(basic);
356
+ }
357
+
358
+ private toUnifiedResults(basic: ImpactResult): UnifiedResult[] {
359
+ // 转换为统一格式
360
+ return basic.dependencies.map(d => ({
361
+ id: `impact-${d.file}`,
362
+ source: 'codemap',
363
+ toolScore: d.score || 0.9,
364
+ type: 'file',
365
+ file: d.file,
366
+ relevance: d.score || 0.9,
367
+ keywords: [],
368
+ metadata: { dependencies: d.dependents }
369
+ }));
370
+ }
371
+ }
372
+ ```
373
+
374
+ ---
375
+
376
+ ## 6. 模块依赖图
377
+
378
+ ```
379
+ CLI 入口
380
+
381
+
382
+ AnalyzeCommand (analyze.ts)
383
+
384
+ ├──────▶ IntentRouter (intent-router.ts)
385
+
386
+ ├──────▶ ToolOrchestrator (tool-orchestrator.ts)
387
+ │ │
388
+ │ ├─────▶ AstGrepAdapter (ast-grep-adapter.ts)
389
+ │ ├─────▶ CodemapAdapter (codemap-adapter.ts)
390
+ │ ├─────▶ RgInternalAdapter (rg-adapter.ts, 内部兜底)
391
+ │ │
392
+ │ └─────▶ ResultFusion (result-fusion.ts)
393
+ │ │
394
+ │ └─────▶ Confidence (confidence.ts)
395
+
396
+ └──────▶ 现有命令 (impact.ts, deps.ts, complexity.ts)
397
+ ```
398
+
399
+ ---
400
+
401
+ ## 7. 配置设计
402
+
403
+ ```json
404
+ {
405
+ "orchestrator": {
406
+ "enabled": true,
407
+ "tools": {
408
+ "ast-grep": { "enabled": true, "command": "sg", "required": false },
409
+ "rg-internal": { "enabled": false, "command": "rg", "required": false }
410
+ },
411
+ "output": {
412
+ "topK": 8,
413
+ "maxTokenPerItem": 160
414
+ },
415
+ "confidence": {
416
+ "thresholds": {
417
+ "high": 0.6,
418
+ "medium": 0.3
419
+ }
420
+ },
421
+ "fallback": {
422
+ "enabled": true
423
+ }
424
+ }
425
+ }
426
+ ```
427
+
428
+ ---
429
+
430
+ ## 8. 工作流编排器设计 (v2.5 规划)
431
+
432
+ ### 8.1 设计目标
433
+
434
+ 串联所有模块的"粘合剂",解决阶段割裂问题:
435
+
436
+ | 问题 | 解决方案 |
437
+ |------|----------|
438
+ | 阶段连接不紧密 | 状态机 + 检查点机制 |
439
+ | 容易迷失阶段 | 交互式工作流引导 |
440
+ | 中断后无法恢复 | 上下文持久化 |
441
+ | 交付物不明确 | 阶段契约定义 |
442
+
443
+ ### 8.2 核心概念
444
+
445
+ #### 工作流阶段定义
446
+
447
+ ```typescript
448
+ // src/orchestrator/workflow/types.ts
449
+
450
+ type WorkflowPhase =
451
+ | 'reference' // 参考搜索
452
+ | 'impact' // 影响分析
453
+ | 'risk' // 风险评估
454
+ | 'implementation' // 代码实现
455
+ | 'commit' // 提交验证
456
+ | 'ci'; // CI 流水线
457
+
458
+ interface PhaseDefinition {
459
+ name: WorkflowPhase;
460
+ action: 'analyze' | 'ci' | 'manual'; // 阶段执行方式
461
+ analyzeIntent?: IntentType; // 仅 action=analyze 时需要
462
+ ciCommand?: string; // 仅 action=ci 时需要
463
+ entryCondition: PhaseCondition; // 入口条件
464
+ deliverables: Deliverable[]; // 交付物
465
+ nextPhase?: WorkflowPhase; // 下一阶段
466
+ commands: string[]; // 可执行的命令
467
+ }
468
+
469
+ interface PhaseCondition {
470
+ minConfidence?: number; // 最低置信度
471
+ requiredArtifacts?: string[]; // 必需的产物
472
+ }
473
+
474
+ interface Deliverable {
475
+ name: string;
476
+ path: string;
477
+ validator: (path: string) => boolean;
478
+ }
479
+ ```
480
+
481
+ #### 工作流上下文
482
+
483
+ ```typescript
484
+ // src/orchestrator/workflow/workflow-context.ts
485
+
486
+ interface WorkflowContext {
487
+ id: string; // 工作流实例 ID
488
+ task: string; // 用户任务描述
489
+ currentPhase: WorkflowPhase;
490
+ phaseStatus: PhaseStatus;
491
+
492
+ // 阶段产物(自动传递)
493
+ artifacts: Map<WorkflowPhase, PhaseArtifacts>;
494
+
495
+ // 分析结果缓存
496
+ cachedResults: {
497
+ reference?: UnifiedResult[];
498
+ impact?: UnifiedResult[];
499
+ risk?: RiskScore;
500
+ };
501
+
502
+ // 用户确认状态
503
+ userConfirmed: Set<WorkflowPhase>;
504
+
505
+ // 时间戳
506
+ startedAt: Date;
507
+ updatedAt: Date;
508
+ }
509
+
510
+ interface PhaseArtifacts {
511
+ phase: WorkflowPhase;
512
+ results?: UnifiedResult[];
513
+ confidence?: ConfidenceResult;
514
+ metadata?: Record<string, unknown>;
515
+ createdAt: Date;
516
+ }
517
+
518
+ type PhaseStatus = 'pending' | 'running' | 'completed' | 'verified' | 'skipped';
519
+ ```
520
+
521
+ ### 8.3 工作流编排器类
522
+
523
+ ```typescript
524
+ // src/orchestrator/workflow/workflow-orchestrator.ts
525
+
526
+ class WorkflowOrchestrator {
527
+ private context: WorkflowContext | null = null;
528
+ private phaseDefinitions: Map<WorkflowPhase, PhaseDefinition>;
529
+ private persistence: WorkflowPersistence;
530
+
531
+ constructor() {
532
+ this.phaseDefinitions = this.initializePhaseDefinitions();
533
+ this.persistence = new WorkflowPersistence();
534
+ }
535
+
536
+ /**
537
+ * 启动新的工作流
538
+ */
539
+ async start(task: string): Promise<WorkflowContext> {
540
+ this.context = {
541
+ id: this.generateId(),
542
+ task,
543
+ currentPhase: 'reference',
544
+ phaseStatus: 'pending',
545
+ artifacts: new Map(),
546
+ cachedResults: {},
547
+ userConfirmed: new Set(),
548
+ startedAt: new Date(),
549
+ updatedAt: new Date()
550
+ };
551
+
552
+ // 保存初始状态
553
+ await this.persistence.save(this.context);
554
+
555
+ return this.context;
556
+ }
557
+
558
+ /**
559
+ * 执行当前阶段
560
+ */
561
+ async executeCurrentPhase(analyzeArgs: AnalyzeArgs): Promise<PhaseResult> {
562
+ if (!this.context) {
563
+ throw new Error('No active workflow. Call start() first.');
564
+ }
565
+
566
+ const phase = this.context.currentPhase;
567
+ const definition = this.phaseDefinitions.get(phase);
568
+
569
+ if (!definition) {
570
+ throw new Error(`Unknown phase: ${phase}`);
571
+ }
572
+
573
+ // 更新状态为 running
574
+ this.context.phaseStatus = 'running';
575
+ await this.persistence.save(this.context);
576
+
577
+ // 按阶段执行方式运行(避免将非 analyze 阶段误当作 intent)
578
+ const results = await this.runPhase(definition, analyzeArgs);
579
+
580
+ // 仅 analyze 阶段计算置信度
581
+ const confidence = definition.action === 'analyze' && definition.analyzeIntent
582
+ ? calculateConfidence(results, definition.analyzeIntent)
583
+ : { score: 1, level: 'high', reasons: ['non-analyze phase'] };
584
+
585
+ // 保存产物
586
+ const artifacts: PhaseArtifacts = {
587
+ phase,
588
+ results,
589
+ confidence,
590
+ createdAt: new Date()
591
+ };
592
+ this.context.artifacts.set(phase, artifacts);
593
+ this.context.cachedResults[phase] = results;
594
+
595
+ // 更新状态为 completed
596
+ this.context.phaseStatus = 'completed';
597
+ this.context.updatedAt = new Date();
598
+ await this.persistence.save(this.context);
599
+
600
+ return { artifacts, confidence, canProceed: this.checkProceedCondition(confidence) };
601
+ }
602
+
603
+ private async runPhase(
604
+ definition: PhaseDefinition,
605
+ analyzeArgs: AnalyzeArgs
606
+ ): Promise<UnifiedResult[]> {
607
+ if (definition.action === 'analyze' && definition.analyzeIntent) {
608
+ return this.runAnalysis(definition.analyzeIntent, analyzeArgs);
609
+ }
610
+ if (definition.action === 'ci' && definition.ciCommand) {
611
+ await this.runCICommand(definition.ciCommand);
612
+ return [];
613
+ }
614
+ return [];
615
+ }
616
+
617
+ /**
618
+ * 验证是否可以进入下一阶段
619
+ */
620
+ private checkProceedCondition(confidence: ConfidenceResult): boolean {
621
+ const phase = this.context!.currentPhase;
622
+ const definition = this.phaseDefinitions.get(phase);
623
+
624
+ if (!definition) return false;
625
+
626
+ const { entryCondition } = definition;
627
+
628
+ // 检查置信度
629
+ if (entryCondition.minConfidence && confidence.score < entryCondition.minConfidence) {
630
+ return false;
631
+ }
632
+
633
+ return true;
634
+ }
635
+
636
+ /**
637
+ * 推进到下一阶段
638
+ */
639
+ async proceedToNextPhase(): Promise<WorkflowPhase> {
640
+ if (!this.context) {
641
+ throw new Error('No active workflow');
642
+ }
643
+
644
+ const current = this.context.currentPhase;
645
+ const definition = this.phaseDefinitions.get(current);
646
+
647
+ if (!definition?.nextPhase) {
648
+ throw new Error('No next phase available');
649
+ }
650
+
651
+ // 验证当前阶段已完成
652
+ if (this.context.phaseStatus !== 'completed') {
653
+ throw new Error(`Current phase ${current} is not completed`);
654
+ }
655
+
656
+ // 标记当前阶段为 verified
657
+ this.context.phaseStatus = 'verified';
658
+
659
+ // 推进到下一阶段
660
+ this.context.currentPhase = definition.nextPhase;
661
+ this.context.phaseStatus = 'pending';
662
+ this.context.updatedAt = new Date();
663
+
664
+ await this.persistence.save(this.context);
665
+
666
+ return definition.nextPhase;
667
+ }
668
+
669
+ /**
670
+ * 获取工作流状态
671
+ */
672
+ async getStatus(): Promise<WorkflowStatus> {
673
+ if (!this.context) {
674
+ this.context = await this.persistence.loadActive();
675
+ }
676
+ if (!this.context) return { active: false };
677
+
678
+ return {
679
+ active: true,
680
+ task: this.context.task,
681
+ currentPhase: this.context.currentPhase,
682
+ phaseStatus: this.context.phaseStatus,
683
+ progress: this.calculateProgress(),
684
+ artifacts: Array.from(this.context.artifacts.keys())
685
+ };
686
+ }
687
+
688
+ private calculateProgress(): number {
689
+ const totalPhases = this.phaseDefinitions.size;
690
+ const completedPhases = Array.from(this.context!.artifacts.keys()).length;
691
+ return (completedPhases / totalPhases) * 100;
692
+ }
693
+
694
+ private initializePhaseDefinitions(): Map<WorkflowPhase, PhaseDefinition> {
695
+ return new Map([
696
+ ['reference', {
697
+ name: 'reference',
698
+ action: 'analyze',
699
+ analyzeIntent: 'reference',
700
+ entryCondition: { minConfidence: 0.3 },
701
+ deliverables: [
702
+ { name: 'reference-results', path: '.mycodemap/workflow/reference.json', validator: () => true }
703
+ ],
704
+ nextPhase: 'impact',
705
+ commands: ['codemap analyze --intent reference']
706
+ }],
707
+ ['impact', {
708
+ name: 'impact',
709
+ action: 'analyze',
710
+ analyzeIntent: 'impact',
711
+ entryCondition: { minConfidence: 0.4 },
712
+ deliverables: [
713
+ { name: 'impact-report', path: '.mycodemap/workflow/impact.json', validator: () => true }
714
+ ],
715
+ nextPhase: 'risk',
716
+ commands: ['codemap analyze --intent impact']
717
+ }],
718
+ ['risk', {
719
+ name: 'risk',
720
+ action: 'ci',
721
+ ciCommand: 'codemap ci assess-risk --threshold 0.7',
722
+ entryCondition: {},
723
+ deliverables: [
724
+ { name: 'risk-assessment', path: '.mycodemap/workflow/risk.json', validator: () => true }
725
+ ],
726
+ nextPhase: 'implementation',
727
+ commands: ['codemap ci assess-risk']
728
+ }],
729
+ ['implementation', {
730
+ name: 'implementation',
731
+ action: 'manual',
732
+ entryCondition: {},
733
+ deliverables: [
734
+ { name: 'implementation', path: 'src/', validator: () => true }
735
+ ],
736
+ nextPhase: 'commit',
737
+ commands: []
738
+ }],
739
+ ['commit', {
740
+ name: 'commit',
741
+ action: 'manual',
742
+ entryCondition: {},
743
+ deliverables: [
744
+ { name: 'commit', path: '.git/COMMIT_EDITMSG', validator: () => true }
745
+ ],
746
+ nextPhase: 'ci',
747
+ commands: ['git commit']
748
+ }],
749
+ ['ci', {
750
+ name: 'ci',
751
+ action: 'ci',
752
+ ciCommand: 'npm test && codemap ci check-commits && codemap ci check-headers && codemap ci check-output-contract',
753
+ entryCondition: {},
754
+ deliverables: [],
755
+ commands: []
756
+ }]
757
+ ]);
758
+ }
759
+ }
760
+ ```
761
+
762
+ ### 8.4 工作流持久化
763
+
764
+ ```typescript
765
+ // src/orchestrator/workflow/workflow-persistence.ts
766
+
767
+ class WorkflowPersistence {
768
+ private storagePath = '.codemap/workflow';
769
+ private activePath = '.mycodemap/workflow/active.json';
770
+
771
+ async save(context: WorkflowContext): Promise<void> {
772
+ const fs = require('fs').promises;
773
+ const path = require('path');
774
+
775
+ // 确保目录存在
776
+ await fs.mkdir(this.storagePath, { recursive: true });
777
+
778
+ const filePath = path.join(this.storagePath, `${context.id}.json`);
779
+ await fs.writeFile(filePath, JSON.stringify(this.serialize(context), null, 2));
780
+ await fs.writeFile(this.activePath, JSON.stringify({ id: context.id }, null, 2));
781
+ }
782
+
783
+ async load(id: string): Promise<WorkflowContext | null> {
784
+ const fs = require('fs').promises;
785
+ const path = require('path');
786
+
787
+ const filePath = path.join(this.storagePath, `${id}.json`);
788
+
789
+ try {
790
+ const content = await fs.readFile(filePath, 'utf-8');
791
+ return this.deserialize(JSON.parse(content));
792
+ } catch {
793
+ return null;
794
+ }
795
+ }
796
+
797
+ async loadActive(): Promise<WorkflowContext | null> {
798
+ const fs = require('fs').promises;
799
+ try {
800
+ const content = await fs.readFile(this.activePath, 'utf-8');
801
+ const { id } = JSON.parse(content);
802
+ return id ? this.load(id) : null;
803
+ } catch {
804
+ return null;
805
+ }
806
+ }
807
+
808
+ async list(): Promise<WorkflowSummary[]> {
809
+ const fs = require('fs').promises;
810
+ const path = require('path');
811
+
812
+ const dir = path.join(process.cwd(), this.storagePath);
813
+
814
+ try {
815
+ const files = await fs.readdir(dir);
816
+ const summaries: WorkflowSummary[] = [];
817
+
818
+ for (const file of files) {
819
+ if (!file.endsWith('.json')) continue;
820
+
821
+ const content = await fs.readFile(path.join(dir, file), 'utf-8');
822
+ const ctx = JSON.parse(content);
823
+
824
+ summaries.push({
825
+ id: ctx.id,
826
+ task: ctx.task,
827
+ currentPhase: ctx.currentPhase,
828
+ phaseStatus: ctx.phaseStatus,
829
+ updatedAt: ctx.updatedAt
830
+ });
831
+ }
832
+
833
+ return summaries;
834
+ } catch {
835
+ return [];
836
+ }
837
+ }
838
+
839
+ async delete(id: string): Promise<void> {
840
+ const fs = require('fs').promises;
841
+ const path = require('path');
842
+
843
+ const filePath = path.join(this.storagePath, `${id}.json`);
844
+ await fs.unlink(filePath);
845
+ }
846
+
847
+ private serialize(context: WorkflowContext) {
848
+ return {
849
+ ...context,
850
+ artifacts: Array.from(context.artifacts.entries()),
851
+ userConfirmed: Array.from(context.userConfirmed.values())
852
+ };
853
+ }
854
+
855
+ private deserialize(raw: any): WorkflowContext {
856
+ return {
857
+ ...raw,
858
+ artifacts: new Map(raw.artifacts || []),
859
+ userConfirmed: new Set(raw.userConfirmed || []),
860
+ startedAt: new Date(raw.startedAt),
861
+ updatedAt: new Date(raw.updatedAt)
862
+ };
863
+ }
864
+ }
865
+ ```
866
+
867
+ ### 8.5 工作流 CLI 交互
868
+
869
+ ```typescript
870
+ // src/cli/commands/workflow.ts
871
+
872
+ import { WorkflowOrchestrator } from '../../orchestrator/workflow/workflow-orchestrator';
873
+ import { Command } from 'commander';
874
+
875
+ const workflow = new Command('workflow').description('Workflow management');
876
+
877
+ workflow.command('start')
878
+ .description('Start a new development workflow')
879
+ .argument('<task>', 'Task description')
880
+ .action(async (task: string) => {
881
+ const orchestrator = new WorkflowOrchestrator();
882
+ const context = await orchestrator.start(task);
883
+
884
+ console.log(`
885
+ [WORKFLOW STARTED]
886
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
887
+
888
+ Task: ${task}
889
+ ID: ${context.id}
890
+ Phase: ${context.currentPhase}
891
+
892
+ Next steps:
893
+ 1. codemap workflow status # 查看当前状态
894
+ 2. codemap analyze --intent reference --keywords ...
895
+ 3. codemap workflow proceed # 进入下一阶段
896
+ `);
897
+ });
898
+
899
+ workflow.command('status')
900
+ .description('Show current workflow status')
901
+ .action(async () => {
902
+ const orchestrator = new WorkflowOrchestrator();
903
+ const status = await orchestrator.getStatus();
904
+
905
+ if (!status.active) {
906
+ console.log('No active workflow. Run "codemap workflow start" first.');
907
+ return;
908
+ }
909
+
910
+ console.log(`
911
+ [WORKFLOW STATUS]
912
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
913
+
914
+ Task: ${status.task}
915
+ Phase: ${status.currentPhase}
916
+ Status: ${status.phaseStatus}
917
+ Progress: ${status.progress.toFixed(0)}%
918
+
919
+ Completed phases: ${status.artifacts?.join(', ') || 'none'}
920
+ `);
921
+ });
922
+
923
+ workflow.command('visualize')
924
+ .description('Visualize current workflow status')
925
+ .action(async () => {
926
+ // 读取活动工作流并渲染 ASCII 视图
927
+ });
928
+
929
+ workflow.command('template')
930
+ .description('Workflow template management')
931
+ .command('apply <name>')
932
+ .action(async (name: string) => {
933
+ // 对活动工作流应用模板并持久化
934
+ });
935
+
936
+ workflow.command('proceed')
937
+ .description('Proceed to next phase')
938
+ .option('-f, --force', 'Skip verification')
939
+ .action(async (options) => {
940
+ const orchestrator = new WorkflowOrchestrator();
941
+ const status = await orchestrator.getStatus();
942
+
943
+ if (!status.active) {
944
+ console.log('No active workflow.');
945
+ return;
946
+ }
947
+
948
+ if (status.phaseStatus !== 'completed' && !options.force) {
949
+ console.log(`Current phase ${status.currentPhase} is not completed. Use --force to override.`);
950
+ return;
951
+ }
952
+
953
+ const next = await orchestrator.proceedToNextPhase();
954
+
955
+ console.log(`
956
+ [PHASE COMPLETED]
957
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
958
+
959
+ Current phase: ${status.currentPhase}
960
+ Status: ${status.phaseStatus}
961
+ Next phase: ${next}
962
+
963
+ Type "codemap workflow proceed" to continue to next phase.
964
+ `);
965
+ });
966
+
967
+ export default workflow;
968
+ ```
969
+
970
+ ### 8.6 阶段连接机制
971
+
972
+ #### 检查点验证
973
+
974
+ ```typescript
975
+ // 每个阶段结束时验证交付物
976
+
977
+ class PhaseCheckpoint {
978
+ /**
979
+ * 验证阶段交付物
980
+ */
981
+ async validate(phase: WorkflowPhase, artifacts: PhaseArtifacts): Promise<CheckpointResult> {
982
+ const definition = this.getPhaseDefinition(phase);
983
+ const results: CheckItem[] = [];
984
+
985
+ for (const deliverable of definition.deliverables) {
986
+ const exists = await this.checkFileExists(deliverable.path);
987
+ const valid = deliverable.validator(deliverable.path);
988
+
989
+ results.push({
990
+ name: deliverable.name,
991
+ path: deliverable.path,
992
+ exists,
993
+ valid
994
+ });
995
+ }
996
+
997
+ return {
998
+ passed: results.every(r => r.exists && r.valid),
999
+ items: results
1000
+ };
1001
+ }
1002
+ }
1003
+ ```
1004
+
1005
+ #### 置信度引导
1006
+
1007
+ ```typescript
1008
+ // 根据置信度决定是否自动推进或等待用户确认
1009
+
1010
+ class ConfidenceGuide {
1011
+ /**
1012
+ * 获取置信度指导建议
1013
+ */
1014
+ getGuidance(confidence: ConfidenceResult, phase: WorkflowPhase): Guidance {
1015
+ if (confidence.level === 'high') {
1016
+ return {
1017
+ action: 'auto-proceed',
1018
+ message: `High confidence (${confidence.score.toFixed(2)}), proceeding to next phase...`
1019
+ };
1020
+ }
1021
+
1022
+ if (confidence.level === 'medium') {
1023
+ return {
1024
+ action: 'confirm-proceed',
1025
+ message: `Medium confidence (${confidence.score.toFixed(2)}), review results before proceeding?`,
1026
+ suggestion: 'Run additional analysis with broader scope'
1027
+ };
1028
+ }
1029
+
1030
+ return {
1031
+ action: 'hold',
1032
+ message: `Low confidence (${confidence.score.toFixed(2)}), current phase needs more work`,
1033
+ suggestion: confidence.reasons.join('; ')
1034
+ };
1035
+ }
1036
+ }
1037
+ ```
1038
+
1039
+ ### 8.7 模块依赖图
1040
+
1041
+ ```
1042
+ 工作流编排器 (workflow-orchestrator.ts)
1043
+
1044
+ ├── 依赖: IntentRouter (intent-router.ts)
1045
+ ├── 依赖: ToolOrchestrator (tool-orchestrator.ts)
1046
+ ├── 依赖: ConfidenceCalculator (confidence.ts)
1047
+ ├── 依赖: ResultFusion (result-fusion.ts)
1048
+ ├── 依赖: GitAnalyzer (git-analyzer.ts)
1049
+ ├── 依赖: AIFeedGenerator (ai-feed-generator.ts)
1050
+ ├── 依赖: TestLinker (test-linker.ts)
1051
+
1052
+ └── 被以下模块使用:
1053
+ └── CLI Commands (workflow.ts)
1054
+ ```
1055
+
1056
+ ### 8.8 配置扩展
1057
+
1058
+ ```json
1059
+ {
1060
+ "workflow": {
1061
+ "enabled": true,
1062
+ "autoProceedThreshold": 0.7,
1063
+ "persistencePath": ".codemap/workflow",
1064
+ "phases": {
1065
+ "reference": { "minConfidence": 0.3 },
1066
+ "impact": { "minConfidence": 0.4 },
1067
+ "risk": { "minConfidence": 0 }
1068
+ }
1069
+ }
1070
+ }
1071
+ ```