@mycodemap/mycodemap 0.4.1 → 0.4.2

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 (222) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +214 -221
  3. package/dist/cli/commands/analyze-options.d.ts +36 -0
  4. package/dist/cli/commands/analyze-options.d.ts.map +1 -0
  5. package/dist/cli/commands/analyze-options.js +147 -0
  6. package/dist/cli/commands/analyze-options.js.map +1 -0
  7. package/dist/cli/commands/analyze.d.ts +93 -4
  8. package/dist/cli/commands/analyze.d.ts.map +1 -1
  9. package/dist/cli/commands/analyze.js +592 -176
  10. package/dist/cli/commands/analyze.js.map +1 -1
  11. package/dist/cli/commands/ci.d.ts +47 -1
  12. package/dist/cli/commands/ci.d.ts.map +1 -1
  13. package/dist/cli/commands/ci.js +208 -1
  14. package/dist/cli/commands/ci.js.map +1 -1
  15. package/dist/cli/commands/export.d.ts.map +1 -1
  16. package/dist/cli/commands/export.js +2 -2
  17. package/dist/cli/commands/export.js.map +1 -1
  18. package/dist/cli/commands/generate.d.ts +8 -2
  19. package/dist/cli/commands/generate.d.ts.map +1 -1
  20. package/dist/cli/commands/generate.js +151 -22
  21. package/dist/cli/commands/generate.js.map +1 -1
  22. package/dist/cli/commands/init.d.ts.map +1 -1
  23. package/dist/cli/commands/init.js +2 -13
  24. package/dist/cli/commands/init.js.map +1 -1
  25. package/dist/cli/commands/ship/checker.d.ts.map +1 -1
  26. package/dist/cli/commands/ship/checker.js +0 -3
  27. package/dist/cli/commands/ship/checker.js.map +1 -1
  28. package/dist/cli/commands/ship/rules/quality-rules.d.ts +0 -1
  29. package/dist/cli/commands/ship/rules/quality-rules.d.ts.map +1 -1
  30. package/dist/cli/commands/ship/rules/quality-rules.js +4 -76
  31. package/dist/cli/commands/ship/rules/quality-rules.js.map +1 -1
  32. package/dist/cli/commands/workflow.js +4 -4
  33. package/dist/cli/commands/workflow.js.map +1 -1
  34. package/dist/cli/config-loader.d.ts +31 -0
  35. package/dist/cli/config-loader.d.ts.map +1 -0
  36. package/dist/cli/config-loader.js +235 -0
  37. package/dist/cli/config-loader.js.map +1 -0
  38. package/dist/cli/index.js +18 -63
  39. package/dist/cli/index.js.map +1 -1
  40. package/dist/cli/removed-commands.d.ts +9 -0
  41. package/dist/cli/removed-commands.d.ts.map +1 -0
  42. package/dist/cli/removed-commands.js +48 -0
  43. package/dist/cli/removed-commands.js.map +1 -0
  44. package/dist/cli/storage-runtime.d.ts +8 -0
  45. package/dist/cli/storage-runtime.d.ts.map +1 -0
  46. package/dist/cli/storage-runtime.js +14 -0
  47. package/dist/cli/storage-runtime.js.map +1 -0
  48. package/dist/cli/tree-sitter-check.d.ts.map +1 -1
  49. package/dist/cli/tree-sitter-check.js +0 -1
  50. package/dist/cli/tree-sitter-check.js.map +1 -1
  51. package/dist/cli-new/commands/export.d.ts.map +1 -1
  52. package/dist/cli-new/commands/export.js +2 -2
  53. package/dist/cli-new/commands/export.js.map +1 -1
  54. package/dist/cli-new/commands/query.d.ts.map +1 -1
  55. package/dist/cli-new/commands/query.js +5 -4
  56. package/dist/cli-new/commands/query.js.map +1 -1
  57. package/dist/cli-new/index.d.ts.map +1 -1
  58. package/dist/cli-new/index.js +0 -2
  59. package/dist/cli-new/index.js.map +1 -1
  60. package/dist/core/analyzer.d.ts.map +1 -1
  61. package/dist/core/analyzer.js +7 -39
  62. package/dist/core/analyzer.js.map +1 -1
  63. package/dist/core/file-discovery.d.ts +17 -0
  64. package/dist/core/file-discovery.d.ts.map +1 -0
  65. package/dist/core/file-discovery.js +75 -0
  66. package/dist/core/file-discovery.js.map +1 -0
  67. package/dist/core/global-index.d.ts +5 -0
  68. package/dist/core/global-index.d.ts.map +1 -1
  69. package/dist/core/global-index.js +71 -21
  70. package/dist/core/global-index.js.map +1 -1
  71. package/dist/generator/index.d.ts.map +1 -1
  72. package/dist/generator/index.js +8 -0
  73. package/dist/generator/index.js.map +1 -1
  74. package/dist/infrastructure/parser/implementations/GoParser.d.ts +2 -5
  75. package/dist/infrastructure/parser/implementations/GoParser.d.ts.map +1 -1
  76. package/dist/infrastructure/parser/implementations/GoParser.js +2 -5
  77. package/dist/infrastructure/parser/implementations/GoParser.js.map +1 -1
  78. package/dist/infrastructure/parser/implementations/PythonParser.d.ts +1 -5
  79. package/dist/infrastructure/parser/implementations/PythonParser.d.ts.map +1 -1
  80. package/dist/infrastructure/parser/implementations/PythonParser.js +1 -5
  81. package/dist/infrastructure/parser/implementations/PythonParser.js.map +1 -1
  82. package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts +1 -5
  83. package/dist/infrastructure/parser/implementations/TypeScriptParser.d.ts.map +1 -1
  84. package/dist/infrastructure/parser/implementations/TypeScriptParser.js +1 -5
  85. package/dist/infrastructure/parser/implementations/TypeScriptParser.js.map +1 -1
  86. package/dist/infrastructure/storage/StorageFactory.d.ts +0 -1
  87. package/dist/infrastructure/storage/StorageFactory.d.ts.map +1 -1
  88. package/dist/infrastructure/storage/StorageFactory.js +4 -29
  89. package/dist/infrastructure/storage/StorageFactory.js.map +1 -1
  90. package/dist/infrastructure/storage/adapters/FileSystemStorage.d.ts.map +1 -1
  91. package/dist/infrastructure/storage/adapters/FileSystemStorage.js +24 -137
  92. package/dist/infrastructure/storage/adapters/FileSystemStorage.js.map +1 -1
  93. package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts +10 -18
  94. package/dist/infrastructure/storage/adapters/KuzuDBStorage.d.ts.map +1 -1
  95. package/dist/infrastructure/storage/adapters/KuzuDBStorage.js +103 -146
  96. package/dist/infrastructure/storage/adapters/KuzuDBStorage.js.map +1 -1
  97. package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts +0 -1
  98. package/dist/infrastructure/storage/adapters/MemoryStorage.d.ts.map +1 -1
  99. package/dist/infrastructure/storage/adapters/MemoryStorage.js +16 -136
  100. package/dist/infrastructure/storage/adapters/MemoryStorage.js.map +1 -1
  101. package/dist/infrastructure/storage/graph-helpers.d.ts +16 -0
  102. package/dist/infrastructure/storage/graph-helpers.d.ts.map +1 -0
  103. package/dist/infrastructure/storage/graph-helpers.js +161 -0
  104. package/dist/infrastructure/storage/graph-helpers.js.map +1 -0
  105. package/dist/infrastructure/storage/index.d.ts.map +1 -1
  106. package/dist/interface/config/index.d.ts +10 -1
  107. package/dist/interface/config/index.d.ts.map +1 -1
  108. package/dist/interface/types/index.d.ts +13 -0
  109. package/dist/interface/types/index.d.ts.map +1 -1
  110. package/dist/interface/types/storage.d.ts +1 -4
  111. package/dist/interface/types/storage.d.ts.map +1 -1
  112. package/dist/orchestrator/confidence.d.ts +9 -9
  113. package/dist/orchestrator/confidence.d.ts.map +1 -1
  114. package/dist/orchestrator/confidence.js +44 -67
  115. package/dist/orchestrator/confidence.js.map +1 -1
  116. package/dist/orchestrator/file-header-scanner.d.ts.map +1 -1
  117. package/dist/orchestrator/file-header-scanner.js +22 -31
  118. package/dist/orchestrator/file-header-scanner.js.map +1 -1
  119. package/dist/orchestrator/intent-router.d.ts +2 -11
  120. package/dist/orchestrator/intent-router.d.ts.map +1 -1
  121. package/dist/orchestrator/intent-router.js +58 -49
  122. package/dist/orchestrator/intent-router.js.map +1 -1
  123. package/dist/orchestrator/tool-orchestrator.d.ts.map +1 -1
  124. package/dist/orchestrator/tool-orchestrator.js +6 -4
  125. package/dist/orchestrator/tool-orchestrator.js.map +1 -1
  126. package/dist/orchestrator/types.d.ts +113 -2
  127. package/dist/orchestrator/types.d.ts.map +1 -1
  128. package/dist/orchestrator/types.js +29 -0
  129. package/dist/orchestrator/types.js.map +1 -1
  130. package/dist/orchestrator/workflow/config.d.ts +4 -12
  131. package/dist/orchestrator/workflow/config.d.ts.map +1 -1
  132. package/dist/orchestrator/workflow/config.js +4 -6
  133. package/dist/orchestrator/workflow/config.js.map +1 -1
  134. package/dist/orchestrator/workflow/git-analyzer.d.ts.map +1 -1
  135. package/dist/orchestrator/workflow/git-analyzer.js +9 -19
  136. package/dist/orchestrator/workflow/git-analyzer.js.map +1 -1
  137. package/dist/orchestrator/workflow/phase-inheritance.d.ts.map +1 -1
  138. package/dist/orchestrator/workflow/phase-inheritance.js +14 -23
  139. package/dist/orchestrator/workflow/phase-inheritance.js.map +1 -1
  140. package/dist/orchestrator/workflow/result-fusion.d.ts.map +1 -1
  141. package/dist/orchestrator/workflow/result-fusion.js +9 -11
  142. package/dist/orchestrator/workflow/result-fusion.js.map +1 -1
  143. package/dist/orchestrator/workflow/templates.d.ts +4 -1
  144. package/dist/orchestrator/workflow/templates.d.ts.map +1 -1
  145. package/dist/orchestrator/workflow/templates.js +49 -207
  146. package/dist/orchestrator/workflow/templates.js.map +1 -1
  147. package/dist/orchestrator/workflow/test-linker.d.ts.map +1 -1
  148. package/dist/orchestrator/workflow/test-linker.js +12 -24
  149. package/dist/orchestrator/workflow/test-linker.js.map +1 -1
  150. package/dist/orchestrator/workflow/types.d.ts +11 -8
  151. package/dist/orchestrator/workflow/types.d.ts.map +1 -1
  152. package/dist/orchestrator/workflow/types.js +8 -1
  153. package/dist/orchestrator/workflow/types.js.map +1 -1
  154. package/dist/orchestrator/workflow/visualizer.d.ts.map +1 -1
  155. package/dist/orchestrator/workflow/visualizer.js +7 -9
  156. package/dist/orchestrator/workflow/visualizer.js.map +1 -1
  157. package/dist/orchestrator/workflow/workflow-context.d.ts.map +1 -1
  158. package/dist/orchestrator/workflow/workflow-context.js +3 -5
  159. package/dist/orchestrator/workflow/workflow-context.js.map +1 -1
  160. package/dist/orchestrator/workflow/workflow-orchestrator.d.ts +0 -4
  161. package/dist/orchestrator/workflow/workflow-orchestrator.d.ts.map +1 -1
  162. package/dist/orchestrator/workflow/workflow-orchestrator.js +7 -99
  163. package/dist/orchestrator/workflow/workflow-orchestrator.js.map +1 -1
  164. package/dist/parser/index.d.ts.map +1 -1
  165. package/dist/parser/index.js +2 -2
  166. package/dist/parser/index.js.map +1 -1
  167. package/dist/plugins/index.d.ts +5 -3
  168. package/dist/plugins/index.d.ts.map +1 -1
  169. package/dist/plugins/index.js +19 -8
  170. package/dist/plugins/index.js.map +1 -1
  171. package/dist/plugins/plugin-loader.d.ts +21 -6
  172. package/dist/plugins/plugin-loader.d.ts.map +1 -1
  173. package/dist/plugins/plugin-loader.js +170 -54
  174. package/dist/plugins/plugin-loader.js.map +1 -1
  175. package/dist/plugins/plugin-registry.d.ts +7 -4
  176. package/dist/plugins/plugin-registry.d.ts.map +1 -1
  177. package/dist/plugins/plugin-registry.js +62 -14
  178. package/dist/plugins/plugin-registry.js.map +1 -1
  179. package/dist/plugins/types.d.ts +16 -6
  180. package/dist/plugins/types.d.ts.map +1 -1
  181. package/dist/plugins/types.js +2 -0
  182. package/dist/plugins/types.js.map +1 -1
  183. package/dist/server/handlers/AnalysisHandler.d.ts +16 -2
  184. package/dist/server/handlers/AnalysisHandler.d.ts.map +1 -1
  185. package/dist/server/handlers/AnalysisHandler.js +31 -47
  186. package/dist/server/handlers/AnalysisHandler.js.map +1 -1
  187. package/dist/server/routes/api.d.ts.map +1 -1
  188. package/dist/server/routes/api.js +31 -12
  189. package/dist/server/routes/api.js.map +1 -1
  190. package/docs/AI_ASSISTANT_SETUP.md +3 -1
  191. package/docs/SETUP_GUIDE.md +41 -17
  192. package/docs/ai-guide/COMMANDS.md +106 -102
  193. package/docs/ai-guide/INTEGRATION.md +23 -21
  194. package/docs/ai-guide/OUTPUT.md +206 -10
  195. package/docs/ai-guide/PATTERNS.md +64 -15
  196. package/docs/ai-guide/PROMPTS.md +12 -12
  197. package/docs/ai-guide/QUICKSTART.md +35 -19
  198. package/docs/ai-guide/README.md +22 -4
  199. package/docs/product-specs/MVP3-ARCHITECTURE-COMPARISON.md +159 -434
  200. package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-PRD.md +169 -261
  201. package/docs/product-specs/MVP3-ARCHITECTURE-REDESIGN-TECH-PRD.md +201 -1259
  202. package/docs/product-specs/README.md +8 -1
  203. package/docs/rules/architecture-guardrails.md +1 -2
  204. package/docs/rules/engineering-with-codex-openai.md +15 -9
  205. package/docs/rules/validation.md +26 -4
  206. package/mycodemap.config.schema.json +76 -5
  207. package/package.json +1 -1
  208. package/scripts/sync-analyze-docs.js +500 -0
  209. package/scripts/validate-ai-docs.js +54 -1
  210. package/scripts/validate-docs.js +746 -26
  211. package/dist/cli/commands/server.d.ts +0 -9
  212. package/dist/cli/commands/server.d.ts.map +0 -1
  213. package/dist/cli/commands/server.js +0 -68
  214. package/dist/cli/commands/server.js.map +0 -1
  215. package/dist/cli-new/commands/server.d.ts +0 -13
  216. package/dist/cli-new/commands/server.d.ts.map +0 -1
  217. package/dist/cli-new/commands/server.js +0 -94
  218. package/dist/cli-new/commands/server.js.map +0 -1
  219. package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts +0 -49
  220. package/dist/infrastructure/storage/adapters/Neo4jStorage.d.ts.map +0 -1
  221. package/dist/infrastructure/storage/adapters/Neo4jStorage.js +0 -222
  222. package/dist/infrastructure/storage/adapters/Neo4jStorage.js.map +0 -1
@@ -0,0 +1,500 @@
1
+ // [META] since:2026-03 | owner:docs-team | stable:false
2
+ // [WHY] 为 analyze 的 canonical 文档示例提供单一渲染源,并支持校验/同步 generated block
3
+
4
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import ts from 'typescript';
8
+
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
+ const defaultRootDir = path.resolve(__dirname, '..');
11
+
12
+ function parseCliArgs(argv) {
13
+ const rootFlagIndex = argv.indexOf('--root');
14
+ const check = argv.includes('--check');
15
+
16
+ if (rootFlagIndex === -1) {
17
+ return { rootDir: defaultRootDir, check };
18
+ }
19
+
20
+ const rootValue = argv[rootFlagIndex + 1];
21
+ if (!rootValue) {
22
+ console.error('ERROR: --root requires a directory path');
23
+ process.exit(1);
24
+ }
25
+
26
+ return {
27
+ rootDir: path.resolve(rootValue),
28
+ check,
29
+ };
30
+ }
31
+
32
+ function renderCommentedBashBlock(sections) {
33
+ const lines = ['```bash'];
34
+
35
+ sections.forEach((section, index) => {
36
+ lines.push(`# ${section.title}`);
37
+ lines.push(...section.commands);
38
+
39
+ if (index < sections.length - 1) {
40
+ lines.push('');
41
+ }
42
+ });
43
+
44
+ lines.push('```');
45
+ return lines.join('\n');
46
+ }
47
+
48
+ function renderReadmeAnalyzeExamples() {
49
+ return renderCommentedBashBlock([
50
+ {
51
+ title: '查找符号 / 文本',
52
+ commands: [
53
+ 'mycodemap analyze -i find -k SourceLocation',
54
+ 'mycodemap analyze -i find -t src/orchestrator -k IntentRouter --json',
55
+ ],
56
+ },
57
+ {
58
+ title: '阅读文件(影响 + 复杂度聚合)',
59
+ commands: [
60
+ 'mycodemap analyze -i read -t src/cli/index.ts',
61
+ 'mycodemap analyze -i read -t src/cli/index.ts --scope transitive',
62
+ 'mycodemap analyze -i read -t src/cli/index.ts --include-tests --json',
63
+ ],
64
+ },
65
+ {
66
+ title: '关联关系(依赖 + 引用聚合)',
67
+ commands: [
68
+ 'mycodemap analyze -i link -t src/cli/index.ts',
69
+ 'mycodemap analyze -i link -t src/interface/types.ts --json',
70
+ ],
71
+ },
72
+ {
73
+ title: '展示模块概览 / 文档',
74
+ commands: [
75
+ 'mycodemap analyze -i show -t src/orchestrator',
76
+ 'mycodemap analyze -i show -t src/domain/services --output-mode human',
77
+ ],
78
+ },
79
+ {
80
+ title: '机器可读输出(JSON / structured)',
81
+ commands: [
82
+ 'mycodemap analyze -i read -t src/index.ts --json',
83
+ 'mycodemap analyze -i link -t src/index.ts --structured --json',
84
+ ],
85
+ },
86
+ ]);
87
+ }
88
+
89
+ function renderCommandsAnalyzeIntentExamples() {
90
+ return renderCommentedBashBlock([
91
+ {
92
+ title: '1. find - 查找符号 / 文本',
93
+ commands: [
94
+ 'mycodemap analyze -i find -k "UnifiedResult"',
95
+ 'mycodemap analyze -i find -t "src/orchestrator" -k "IntentRouter" --topK 20',
96
+ ],
97
+ },
98
+ {
99
+ title: '2. read - 阅读文件(影响 + 复杂度)',
100
+ commands: [
101
+ 'mycodemap analyze -i read -t "src/index.ts"',
102
+ 'mycodemap analyze -i read -t "src/index.ts" --scope transitive',
103
+ 'mycodemap analyze -i read -t "src/index.ts" --include-tests',
104
+ ],
105
+ },
106
+ {
107
+ title: '3. link - 关联关系(依赖 + 引用)',
108
+ commands: [
109
+ 'mycodemap analyze -i link -t "src/orchestrator"',
110
+ 'mycodemap analyze -i link -t "src/interface/types.ts" --json',
111
+ ],
112
+ },
113
+ {
114
+ title: '4. show - 模块概览 / 文档',
115
+ commands: [
116
+ 'mycodemap analyze -i show -t "src/"',
117
+ 'mycodemap analyze -i show -t "src/domain/services" --output-mode human',
118
+ ],
119
+ },
120
+ ]);
121
+ }
122
+
123
+ function renderCommandsAnalyzeOutputExamples() {
124
+ return renderCommentedBashBlock([
125
+ {
126
+ title: 'JSON 输出',
127
+ commands: ['mycodemap analyze -i read -t "src/index.ts" --json'],
128
+ },
129
+ {
130
+ title: '纯结构化(移除自然语言字段)',
131
+ commands: ['mycodemap analyze -i link -t "src/index.ts" --structured --json'],
132
+ },
133
+ {
134
+ title: '机器可读模式',
135
+ commands: ['mycodemap analyze -i show -t "src/index.ts" --output-mode machine'],
136
+ },
137
+ {
138
+ title: '人类可读模式',
139
+ commands: ['mycodemap analyze -i show -t "src/index.ts" --output-mode human'],
140
+ },
141
+ ]);
142
+ }
143
+
144
+ function renderMarkdownTemplateBlock(lines) {
145
+ return ['```markdown', ...lines, '```'].join('\n');
146
+ }
147
+
148
+ function renderAiGuideProjectTemplate() {
149
+ return renderMarkdownTemplateBlock([
150
+ '我需要理解这个 TypeScript 项目的结构。',
151
+ '请执行:',
152
+ '1. `node dist/cli/index.js generate`',
153
+ '2. 阅读 `.mycodemap/AI_MAP.md`',
154
+ '3. 使用 `analyze -i show -t "src/" --json`',
155
+ '4. 输出项目结构分析',
156
+ ]);
157
+ }
158
+
159
+ function renderAiGuideImpactTemplate() {
160
+ return renderMarkdownTemplateBlock([
161
+ '我需要修改 {{FILE}},请分析影响范围。',
162
+ '请执行:',
163
+ '1. `node dist/cli/index.js analyze -i read -t "{{FILE}}" --scope transitive --json`',
164
+ '2. 分析直接依赖和传递依赖',
165
+ '3. 评估风险等级',
166
+ '4. 给出修改建议',
167
+ ]);
168
+ }
169
+
170
+ function getObjectProperty(objectExpression, propertyName) {
171
+ return objectExpression.properties.find(property => {
172
+ if (!ts.isPropertyAssignment(property)) {
173
+ return false;
174
+ }
175
+
176
+ if (ts.isIdentifier(property.name) || ts.isStringLiteral(property.name)) {
177
+ return property.name.text === propertyName;
178
+ }
179
+
180
+ return false;
181
+ });
182
+ }
183
+
184
+ function getStringLiteralValue(objectExpression, propertyName, options = {}) {
185
+ const property = getObjectProperty(objectExpression, propertyName);
186
+ if (!property) {
187
+ return options.optional ? undefined : null;
188
+ }
189
+
190
+ const { initializer } = property;
191
+ if (ts.isStringLiteral(initializer) || ts.isNoSubstitutionTemplateLiteral(initializer)) {
192
+ return initializer.text;
193
+ }
194
+
195
+ return options.optional ? undefined : null;
196
+ }
197
+
198
+ function getBooleanLiteralValue(objectExpression, propertyName) {
199
+ const property = getObjectProperty(objectExpression, propertyName);
200
+ if (!property) {
201
+ return undefined;
202
+ }
203
+
204
+ if (property.initializer.kind === ts.SyntaxKind.TrueKeyword) {
205
+ return true;
206
+ }
207
+
208
+ if (property.initializer.kind === ts.SyntaxKind.FalseKeyword) {
209
+ return false;
210
+ }
211
+
212
+ return undefined;
213
+ }
214
+
215
+ function loadAnalyzeDocOptions(rootDir) {
216
+ const sourcePath = path.join(rootDir, 'src/cli/commands/analyze-options.ts');
217
+ if (!existsSync(sourcePath)) {
218
+ throw new Error('Missing required file: src/cli/commands/analyze-options.ts');
219
+ }
220
+
221
+ const sourceText = readFileSync(sourcePath, 'utf8');
222
+ const sourceFile = ts.createSourceFile(
223
+ sourcePath,
224
+ sourceText,
225
+ ts.ScriptTarget.Latest,
226
+ true,
227
+ ts.ScriptKind.TS
228
+ );
229
+
230
+ let definitionsNode = null;
231
+ for (const statement of sourceFile.statements) {
232
+ if (!ts.isVariableStatement(statement)) {
233
+ continue;
234
+ }
235
+
236
+ for (const declaration of statement.declarationList.declarations) {
237
+ if (
238
+ ts.isIdentifier(declaration.name) &&
239
+ declaration.name.text === 'ANALYZE_OPTION_DEFINITIONS' &&
240
+ declaration.initializer &&
241
+ ts.isAsExpression(declaration.initializer) &&
242
+ ts.isArrayLiteralExpression(declaration.initializer.expression)
243
+ ) {
244
+ definitionsNode = declaration.initializer.expression;
245
+ }
246
+ }
247
+ }
248
+
249
+ if (!definitionsNode) {
250
+ throw new Error('Unable to locate ANALYZE_OPTION_DEFINITIONS in src/cli/commands/analyze-options.ts');
251
+ }
252
+
253
+ return definitionsNode.elements.flatMap(element => {
254
+ if (!ts.isObjectLiteralExpression(element)) {
255
+ return [];
256
+ }
257
+
258
+ if (getBooleanLiteralValue(element, 'includeInDocs') === false) {
259
+ return [];
260
+ }
261
+
262
+ const flags = getStringLiteralValue(element, 'flags');
263
+ const docDescription =
264
+ getStringLiteralValue(element, 'docDescription', { optional: true }) ??
265
+ getStringLiteralValue(element, 'description');
266
+ const defaultValue =
267
+ getStringLiteralValue(element, 'docDefaultValue', { optional: true }) ??
268
+ getStringLiteralValue(element, 'defaultValue', { optional: true }) ??
269
+ '-';
270
+
271
+ if (!flags || !docDescription) {
272
+ throw new Error('Failed to parse analyze option documentation metadata');
273
+ }
274
+
275
+ return [
276
+ {
277
+ flags,
278
+ docDescription,
279
+ defaultValue,
280
+ },
281
+ ];
282
+ });
283
+ }
284
+
285
+ function renderAnalyzeOptionsTable(rootDir) {
286
+ const options = loadAnalyzeDocOptions(rootDir);
287
+ const lines = [
288
+ '| 选项 | 说明 | 默认值 |',
289
+ '|------|------|--------|',
290
+ ...options.map(option => {
291
+ const defaultValue = option.defaultValue === '-' ? '-' : `\`${option.defaultValue}\``;
292
+ return `| \`${option.flags}\` | ${option.docDescription} | ${defaultValue} |`;
293
+ }),
294
+ ];
295
+
296
+ return lines.join('\n');
297
+ }
298
+
299
+ const ANALYZE_DOC_BLOCKS = [
300
+ {
301
+ relativePath: 'README.md',
302
+ marker: 'analyze-readme-examples',
303
+ render: () => renderReadmeAnalyzeExamples(),
304
+ },
305
+ {
306
+ relativePath: 'README.md',
307
+ marker: 'analyze-readme-options',
308
+ render: rootDir => renderAnalyzeOptionsTable(rootDir),
309
+ },
310
+ {
311
+ relativePath: 'docs/ai-guide/COMMANDS.md',
312
+ marker: 'analyze-commands-intents',
313
+ render: () => renderCommandsAnalyzeIntentExamples(),
314
+ },
315
+ {
316
+ relativePath: 'docs/ai-guide/COMMANDS.md',
317
+ marker: 'analyze-commands-output',
318
+ render: () => renderCommandsAnalyzeOutputExamples(),
319
+ },
320
+ {
321
+ relativePath: 'docs/ai-guide/COMMANDS.md',
322
+ marker: 'analyze-commands-options',
323
+ render: rootDir => renderAnalyzeOptionsTable(rootDir),
324
+ },
325
+ {
326
+ relativePath: 'AI_GUIDE.md',
327
+ marker: 'analyze-ai-guide-project-template',
328
+ render: () => renderAiGuideProjectTemplate(),
329
+ },
330
+ {
331
+ relativePath: 'AI_GUIDE.md',
332
+ marker: 'analyze-ai-guide-impact-template',
333
+ render: () => renderAiGuideImpactTemplate(),
334
+ },
335
+ ];
336
+
337
+ function createGeneratedBlock(marker, content) {
338
+ return `<!-- BEGIN GENERATED: ${marker} -->\n${content}\n<!-- END GENERATED: ${marker} -->`;
339
+ }
340
+
341
+ function escapeRegExp(text) {
342
+ return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
343
+ }
344
+
345
+ function replaceGeneratedBlock(text, marker, renderedContent) {
346
+ const startMarker = `<!-- BEGIN GENERATED: ${marker} -->`;
347
+ const endMarker = `<!-- END GENERATED: ${marker} -->`;
348
+
349
+ if (!text.includes(startMarker) || !text.includes(endMarker)) {
350
+ return {
351
+ ok: false,
352
+ reason: `Missing generated block markers for ${marker}`,
353
+ };
354
+ }
355
+
356
+ const expectedBlock = createGeneratedBlock(marker, renderedContent);
357
+ const blockPattern = new RegExp(
358
+ `${escapeRegExp(startMarker)}[\\s\\S]*?${escapeRegExp(endMarker)}`
359
+ );
360
+
361
+ return {
362
+ ok: true,
363
+ expectedBlock,
364
+ nextText: text.replace(blockPattern, expectedBlock),
365
+ };
366
+ }
367
+
368
+ function readRequiredFile(rootDir, relativePath) {
369
+ const absolutePath = path.join(rootDir, relativePath);
370
+ if (!existsSync(absolutePath)) {
371
+ return {
372
+ ok: false,
373
+ reason: `Missing required file: ${relativePath}`,
374
+ };
375
+ }
376
+
377
+ return {
378
+ ok: true,
379
+ absolutePath,
380
+ text: readFileSync(absolutePath, 'utf8'),
381
+ };
382
+ }
383
+
384
+ export function collectAnalyzeDocSyncFailures(rootDir) {
385
+ const failures = [];
386
+
387
+ for (const block of ANALYZE_DOC_BLOCKS) {
388
+ const fileResult = readRequiredFile(rootDir, block.relativePath);
389
+ if (!fileResult.ok) {
390
+ failures.push(fileResult.reason);
391
+ continue;
392
+ }
393
+
394
+ let renderedContent;
395
+ try {
396
+ renderedContent = block.render(rootDir);
397
+ } catch (error) {
398
+ failures.push(
399
+ `${block.relativePath}: failed to render "${block.marker}": ${error instanceof Error ? error.message : String(error)}`
400
+ );
401
+ continue;
402
+ }
403
+
404
+ const blockResult = replaceGeneratedBlock(fileResult.text, block.marker, renderedContent);
405
+ if (!blockResult.ok) {
406
+ failures.push(`${block.relativePath}: ${blockResult.reason}`);
407
+ continue;
408
+ }
409
+
410
+ if (fileResult.text !== blockResult.nextText) {
411
+ failures.push(
412
+ `${block.relativePath}: generated block "${block.marker}" is out of sync with scripts/sync-analyze-docs.js`
413
+ );
414
+ }
415
+ }
416
+
417
+ return failures;
418
+ }
419
+
420
+ export function syncAnalyzeDocs(rootDir) {
421
+ const changedFiles = new Set();
422
+ const failures = [];
423
+
424
+ for (const block of ANALYZE_DOC_BLOCKS) {
425
+ const fileResult = readRequiredFile(rootDir, block.relativePath);
426
+ if (!fileResult.ok) {
427
+ failures.push(fileResult.reason);
428
+ continue;
429
+ }
430
+
431
+ let renderedContent;
432
+ try {
433
+ renderedContent = block.render(rootDir);
434
+ } catch (error) {
435
+ failures.push(
436
+ `${block.relativePath}: failed to render "${block.marker}": ${error instanceof Error ? error.message : String(error)}`
437
+ );
438
+ continue;
439
+ }
440
+
441
+ const blockResult = replaceGeneratedBlock(fileResult.text, block.marker, renderedContent);
442
+ if (!blockResult.ok) {
443
+ failures.push(`${block.relativePath}: ${blockResult.reason}`);
444
+ continue;
445
+ }
446
+
447
+ if (fileResult.text !== blockResult.nextText) {
448
+ writeFileSync(fileResult.absolutePath, blockResult.nextText);
449
+ changedFiles.add(block.relativePath);
450
+ }
451
+ }
452
+
453
+ return {
454
+ changedFiles: [...changedFiles],
455
+ failures,
456
+ };
457
+ }
458
+
459
+ function isCliEntrypoint() {
460
+ const entryPath = process.argv[1];
461
+ return Boolean(entryPath) && path.resolve(entryPath) === fileURLToPath(import.meta.url);
462
+ }
463
+
464
+ function main(argv) {
465
+ const { rootDir, check } = parseCliArgs(argv);
466
+
467
+ if (check) {
468
+ const failures = collectAnalyzeDocSyncFailures(rootDir);
469
+ if (failures.length > 0) {
470
+ console.error('ERROR: analyze documentation blocks are out of sync');
471
+ for (const failure of failures) {
472
+ console.error(`- ${failure}`);
473
+ }
474
+ process.exit(1);
475
+ }
476
+
477
+ console.log('Analyze documentation blocks are in sync');
478
+ return;
479
+ }
480
+
481
+ const { changedFiles, failures } = syncAnalyzeDocs(rootDir);
482
+ if (failures.length > 0) {
483
+ console.error('ERROR: failed to sync analyze documentation blocks');
484
+ for (const failure of failures) {
485
+ console.error(`- ${failure}`);
486
+ }
487
+ process.exit(1);
488
+ }
489
+
490
+ if (changedFiles.length === 0) {
491
+ console.log('Analyze documentation blocks already up to date');
492
+ return;
493
+ }
494
+
495
+ console.log(`Synced analyze documentation blocks: ${changedFiles.join(', ')}`);
496
+ }
497
+
498
+ if (isCliEntrypoint()) {
499
+ main(process.argv.slice(2));
500
+ }
@@ -6,7 +6,23 @@ import path from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
 
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
- const rootDir = path.resolve(__dirname, '..');
9
+ const defaultRootDir = path.resolve(__dirname, '..');
10
+ let rootDir = defaultRootDir;
11
+
12
+ function parseRootDir(argv) {
13
+ const rootFlagIndex = argv.indexOf('--root');
14
+ if (rootFlagIndex === -1) {
15
+ return defaultRootDir;
16
+ }
17
+
18
+ const rootValue = argv[rootFlagIndex + 1];
19
+ if (!rootValue) {
20
+ console.error('ERROR: --root requires a directory path');
21
+ process.exit(1);
22
+ }
23
+
24
+ return path.resolve(rootValue);
25
+ }
10
26
 
11
27
  // AI 文档清单
12
28
  const requiredAIDocs = [
@@ -263,6 +279,41 @@ function checkDecisionTrees(failures) {
263
279
  }
264
280
  }
265
281
 
282
+ function checkAnalyzeContractConsistency(failures) {
283
+ console.log('\nChecking analyze public contract consistency...\n');
284
+
285
+ const outdatedIntents = ['overview', 'impact', 'dependency', 'search', 'complexity', 'refactor'];
286
+ const outdatedAnalyzeRegex = new RegExp(`analyze.*-i.*\\b(${outdatedIntents.join('|')})\\b`);
287
+
288
+ for (const { file } of requiredAIDocs) {
289
+ const content = readText(file);
290
+ if (!content) {
291
+ continue;
292
+ }
293
+
294
+ const offendingLines = content
295
+ .split('\n')
296
+ .map(line => line.trim())
297
+ .filter(line => {
298
+ if (!line.includes('analyze') || !line.includes('-i')) {
299
+ return false;
300
+ }
301
+
302
+ return outdatedAnalyzeRegex.test(line);
303
+ });
304
+
305
+ if (offendingLines.length > 0) {
306
+ const uniqueMatches = [...new Set(offendingLines)];
307
+ failures.push(`${file} contains outdated analyze intents: ${uniqueMatches.join(' | ')}`);
308
+ console.log(` ❌ ${file}`);
309
+ uniqueMatches.forEach(match => console.log(` - outdated: ${match}`));
310
+ continue;
311
+ }
312
+
313
+ console.log(` ✅ ${file}`);
314
+ }
315
+ }
316
+
266
317
  function validateAIDocs() {
267
318
  console.log('========================================');
268
319
  console.log('AI Documentation Guardrails Check');
@@ -275,6 +326,7 @@ function validateAIDocs() {
275
326
  checkCrossReferences(failures);
276
327
  checkPromptsLibrary(failures);
277
328
  checkDecisionTrees(failures);
329
+ checkAnalyzeContractConsistency(failures);
278
330
 
279
331
  console.log('\n========================================');
280
332
 
@@ -291,4 +343,5 @@ function validateAIDocs() {
291
343
  console.log('========================================');
292
344
  }
293
345
 
346
+ rootDir = parseRootDir(process.argv.slice(2));
294
347
  validateAIDocs();