@chongyan/autospec 1.0.1

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 (243) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +472 -0
  3. package/README.md +476 -0
  4. package/bin/autospec.js +3 -0
  5. package/knowledge/README.md +144 -0
  6. package/knowledge/checklists/code.md +182 -0
  7. package/knowledge/checklists/design.md +196 -0
  8. package/knowledge/checklists/release.md +70 -0
  9. package/knowledge/checklists/requirement.md +169 -0
  10. package/knowledge/checklists/test.md +46 -0
  11. package/knowledge/config/README.en.md +44 -0
  12. package/knowledge/config/README.md +44 -0
  13. package/knowledge/config/role-composition.yaml +98 -0
  14. package/knowledge/config/role-extensions.yaml +140 -0
  15. package/knowledge/config/skill-compositions.yaml +142 -0
  16. package/knowledge/config/team-stage.yaml +95 -0
  17. package/knowledge/config/team-tasks.yaml +139 -0
  18. package/knowledge/config/team-triggers.yaml +198 -0
  19. package/knowledge/config/validation-patterns.yaml +137 -0
  20. package/knowledge/domain/README.md +115 -0
  21. package/knowledge/domain/flows/README.md +194 -0
  22. package/knowledge/domain/glossary.md +143 -0
  23. package/knowledge/domain/rules.md +138 -0
  24. package/knowledge/environment/README.en.md +36 -0
  25. package/knowledge/environment/README.md +87 -0
  26. package/knowledge/environment/component-knowledge.md +316 -0
  27. package/knowledge/environment/detection-patterns.yaml +502 -0
  28. package/knowledge/environment/middleware-knowledge.md +237 -0
  29. package/knowledge/environment/template-registry.md +321 -0
  30. package/knowledge/guides/domain-driven-design.md +345 -0
  31. package/knowledge/guides/knowledge-management.md +369 -0
  32. package/knowledge/guides/requirement-engineering.md +329 -0
  33. package/knowledge/guides/stages/ai-effect-evaluator.md +93 -0
  34. package/knowledge/guides/stages/code-implementer.md +205 -0
  35. package/knowledge/guides/stages/code-reviewer.md +111 -0
  36. package/knowledge/guides/stages/consistency-checker.md +177 -0
  37. package/knowledge/guides/stages/design-planner.md +401 -0
  38. package/knowledge/guides/stages/design-reviewer.md +83 -0
  39. package/knowledge/guides/stages/integration-test-runner.md +105 -0
  40. package/knowledge/guides/stages/release-checker.md +205 -0
  41. package/knowledge/guides/stages/requirement-analyzer.md +195 -0
  42. package/knowledge/guides/stages/requirement-reviewer.md +83 -0
  43. package/knowledge/guides/stages/security-reviewer.md +89 -0
  44. package/knowledge/guides/stages/test-context-analyzer.md +250 -0
  45. package/knowledge/guides/stages/test-generator.md +241 -0
  46. package/knowledge/guides/stages/test-planner.md +183 -0
  47. package/knowledge/guides/stages/test-reviewer.md +76 -0
  48. package/knowledge/guides/stages/unit-test-runner.md +83 -0
  49. package/knowledge/guides/support/ai-agent-analyzer.md +362 -0
  50. package/knowledge/guides/support/ai-anomaly-analyzer.md +213 -0
  51. package/knowledge/guides/support/ai-artifact-evaluator.md +192 -0
  52. package/knowledge/guides/support/ai-capability-analyzer.md +193 -0
  53. package/knowledge/guides/support/ai-component-analyzer.md +169 -0
  54. package/knowledge/guides/support/ai-data-validator.md +276 -0
  55. package/knowledge/guides/support/ai-evaluation-planner.md +374 -0
  56. package/knowledge/guides/support/ai-path-evaluator.md +274 -0
  57. package/knowledge/guides/support/ai-pipeline-evaluator.md +219 -0
  58. package/knowledge/guides/support/ai-rag-analyzer.md +339 -0
  59. package/knowledge/guides/support/ai-task-assessor.md +418 -0
  60. package/knowledge/guides/support/ai-test-diagnostics.md +133 -0
  61. package/knowledge/guides/support/complexity-assessor.md +268 -0
  62. package/knowledge/guides/support/component-discovery.md +183 -0
  63. package/knowledge/guides/support/environment-scanner.md +207 -0
  64. package/knowledge/guides/support/environment-validator.md +207 -0
  65. package/knowledge/guides/support/knowledge-generator.md +234 -0
  66. package/knowledge/guides/support/methodology-extractor.md +55 -0
  67. package/knowledge/guides/support/pipeline-protocol.md +438 -0
  68. package/knowledge/guides/support/practice-logger.md +359 -0
  69. package/knowledge/guides/support/scope-inference.md +174 -0
  70. package/knowledge/guides/support/skill-distiller.md +91 -0
  71. package/knowledge/guides/support/skill-updater.md +45 -0
  72. package/knowledge/guides/support/skill-validator.md +72 -0
  73. package/knowledge/guides/support/team-orchestrator.md +323 -0
  74. package/knowledge/guides/support/tech-stack-analyzer.md +139 -0
  75. package/knowledge/guides/support/test-runner.md +254 -0
  76. package/knowledge/guides/system-design.md +352 -0
  77. package/knowledge/organization/ai-native-team.md +318 -0
  78. package/knowledge/organization/team-metrics.md +228 -0
  79. package/knowledge/principles/constitution.md +134 -0
  80. package/knowledge/principles/core-principles.md +368 -0
  81. package/knowledge/principles/design-philosophy.md +877 -0
  82. package/knowledge/principles/evolution.md +553 -0
  83. package/knowledge/process/01-requirement.md +113 -0
  84. package/knowledge/process/02-design.md +123 -0
  85. package/knowledge/process/03-implementation.md +90 -0
  86. package/knowledge/process/04-review.md +80 -0
  87. package/knowledge/process/05-testing.md +90 -0
  88. package/knowledge/process/06-delivery.md +88 -0
  89. package/knowledge/process/README.en.md +38 -0
  90. package/knowledge/process/README.md +48 -0
  91. package/knowledge/process/ai-sdlc.md +475 -0
  92. package/knowledge/process/overview.md +319 -0
  93. package/knowledge/standards/code-review.md +876 -0
  94. package/knowledge/standards/coding-style.md +940 -0
  95. package/knowledge/standards/data-consistency.md +1085 -0
  96. package/knowledge/standards/document-versioning.md +210 -0
  97. package/knowledge/standards/risk-detection.md +186 -0
  98. package/knowledge/templates/ai-evaluation.md +150 -0
  99. package/knowledge/templates/api-design.md +117 -0
  100. package/knowledge/templates/database-design.md +132 -0
  101. package/knowledge/templates/domain-driven-design.md +321 -0
  102. package/knowledge/templates/product-proposal.md +201 -0
  103. package/knowledge/templates/system-design.md +227 -0
  104. package/knowledge/templates/task-breakdown.md +107 -0
  105. package/knowledge/templates/test-case.md +170 -0
  106. package/package.json +53 -0
  107. package/plugins/.claude-plugin/plugin.json +134 -0
  108. package/plugins/agents/roles/ai-engineer.md +129 -0
  109. package/plugins/agents/roles/backend-engineer.md +165 -0
  110. package/plugins/agents/roles/ceo.md +94 -0
  111. package/plugins/agents/roles/data-engineer.md +135 -0
  112. package/plugins/agents/roles/devops-engineer.md +181 -0
  113. package/plugins/agents/roles/frontend-engineer.md +129 -0
  114. package/plugins/agents/roles/product-owner.md +98 -0
  115. package/plugins/agents/roles/quality-engineer.md +129 -0
  116. package/plugins/agents/roles/security-engineer.md +180 -0
  117. package/plugins/agents/roles/tech-lead.md +97 -0
  118. package/plugins/agents/support/blind-comparator.md +88 -0
  119. package/plugins/agents/support/consistency-checker.md +103 -0
  120. package/plugins/agents/support/failure-diagnostician.md +141 -0
  121. package/plugins/agents/support/independent-reviewer.md +80 -0
  122. package/plugins/agents/support/safety-auditor.md +121 -0
  123. package/plugins/agents/support/skill-benchmarker.md +86 -0
  124. package/plugins/agents/support/skill-forger.md +105 -0
  125. package/plugins/agents/support/stage-gate-evaluator.md +121 -0
  126. package/plugins/agents/support/test-coverage-reviewer.md +73 -0
  127. package/plugins/benchmarks/templates/README.md +44 -0
  128. package/plugins/benchmarks/templates/commands/explore-template.yaml +48 -0
  129. package/plugins/benchmarks/templates/pipeline/agile-template.yaml +84 -0
  130. package/plugins/benchmarks/templates/pipeline/waterfall-template.yaml +106 -0
  131. package/plugins/benchmarks/templates/skills/requirement-analyzer-template.yaml +48 -0
  132. package/plugins/commands/README.en.md +96 -0
  133. package/plugins/commands/README.md +96 -0
  134. package/plugins/commands/apply.md +191 -0
  135. package/plugins/commands/archive.md +76 -0
  136. package/plugins/commands/env-export.md +79 -0
  137. package/plugins/commands/env-sync.md +640 -0
  138. package/plugins/commands/env-template.md +223 -0
  139. package/plugins/commands/env-update.md +264 -0
  140. package/plugins/commands/env-validate.md +176 -0
  141. package/plugins/commands/env.md +79 -0
  142. package/plugins/commands/explore.md +76 -0
  143. package/plugins/commands/field-evolve.md +536 -0
  144. package/plugins/commands/memory.md +249 -0
  145. package/plugins/commands/project-evolve.md +821 -0
  146. package/plugins/commands/propose.md +93 -0
  147. package/plugins/commands/review.md +140 -0
  148. package/plugins/commands/run.md +224 -0
  149. package/plugins/commands/status.md +62 -0
  150. package/plugins/commands/validate.md +108 -0
  151. package/plugins/hooks/README.en.md +56 -0
  152. package/plugins/hooks/README.md +56 -0
  153. package/plugins/hooks/ai-project-guard.js +329 -0
  154. package/plugins/hooks/artifact-evaluation-hook.js +237 -0
  155. package/plugins/hooks/constitution-guard.js +211 -0
  156. package/plugins/hooks/environment-autocommit.js +264 -0
  157. package/plugins/hooks/environment-manager.js +778 -0
  158. package/plugins/hooks/execution-tracker.js +354 -0
  159. package/plugins/hooks/frozen-zone-guard.js +140 -0
  160. package/plugins/hooks/layer1-validator.js +423 -0
  161. package/plugins/hooks/lib/artifact-evaluator.js +414 -0
  162. package/plugins/hooks/lib/benchmarks/change-detector.js +390 -0
  163. package/plugins/hooks/lib/benchmarks/evaluator.js +605 -0
  164. package/plugins/hooks/lib/benchmarks/integration-example.js +169 -0
  165. package/plugins/hooks/lib/data-and-ai-detector.js +275 -0
  166. package/plugins/hooks/lib/detection-pattern-loader.js +865 -0
  167. package/plugins/hooks/lib/directory-discovery.js +395 -0
  168. package/plugins/hooks/lib/environment-config-loader.js +341 -0
  169. package/plugins/hooks/lib/environment-detector.js +553 -0
  170. package/plugins/hooks/lib/environment-evolver.js +564 -0
  171. package/plugins/hooks/lib/environment-registry.js +813 -0
  172. package/plugins/hooks/lib/execution-path.js +427 -0
  173. package/plugins/hooks/lib/hook-error-recorder.js +245 -0
  174. package/plugins/hooks/lib/hook-logger.js +538 -0
  175. package/plugins/hooks/lib/hook-runner.js +97 -0
  176. package/plugins/hooks/lib/hook-runner.sh +44 -0
  177. package/plugins/hooks/lib/hook-state-manager.js +480 -0
  178. package/plugins/hooks/lib/memory-extractor.js +377 -0
  179. package/plugins/hooks/lib/memory-manager.js +673 -0
  180. package/plugins/hooks/lib/metrics-analyzer.js +489 -0
  181. package/plugins/hooks/lib/project-evolution/auto-fixer.js +511 -0
  182. package/plugins/hooks/lib/project-evolution/memory-manager.js +346 -0
  183. package/plugins/hooks/lib/project-evolution/pattern-detector.js +476 -0
  184. package/plugins/hooks/lib/project-evolution/semantic-indexer.js +480 -0
  185. package/plugins/hooks/lib/project-structure-detector.js +326 -0
  186. package/plugins/hooks/lib/rollback-tracker.js +346 -0
  187. package/plugins/hooks/lib/source-code-scanner.js +596 -0
  188. package/plugins/hooks/lib/technology-stack-detector.js +374 -0
  189. package/plugins/hooks/lib/test-failure-analyzer.js +375 -0
  190. package/plugins/hooks/lib/test-failure-fixer.js +268 -0
  191. package/plugins/hooks/lib/trace-context.js +277 -0
  192. package/plugins/hooks/lib/validation-patterns.js +415 -0
  193. package/plugins/hooks/memory-sync.js +171 -0
  194. package/plugins/hooks/pipeline-observer.js +413 -0
  195. package/plugins/hooks/scope-sentinel.js +204 -0
  196. package/plugins/hooks/trace-initialization.js +169 -0
  197. package/plugins/memory/templates/code-quality.yaml +149 -0
  198. package/plugins/memory/templates/multi-system.yaml +155 -0
  199. package/plugins/memory/templates/team-habits.yaml +119 -0
  200. package/plugins/memory/templates/testing.yaml +121 -0
  201. package/plugins/skills/README.en.md +47 -0
  202. package/plugins/skills/README.md +104 -0
  203. package/plugins/skills/benchmark-executor/README.md +93 -0
  204. package/plugins/skills/benchmark-executor/SKILL.md +647 -0
  205. package/plugins/skills/benchmark-generator/SKILL.md +349 -0
  206. package/plugins/skills/delivery-stage/SKILL.md +203 -0
  207. package/plugins/skills/design-stage/SKILL.md +216 -0
  208. package/plugins/skills/evolution-process/SKILL.md +291 -0
  209. package/plugins/skills/exploration-phase/SKILL.md +133 -0
  210. package/plugins/skills/implementation-stage/SKILL.md +179 -0
  211. package/plugins/skills/layer1-validation/SKILL.md +79 -0
  212. package/plugins/skills/pending-dashboard/SKILL.md +109 -0
  213. package/plugins/skills/project-evolution/SKILL.md +847 -0
  214. package/plugins/skills/requirement-stage/SKILL.md +183 -0
  215. package/plugins/skills/skill-forge/SKILL.md +223 -0
  216. package/plugins/skills/skill-forge/references/description-guide.md +92 -0
  217. package/plugins/skills/skill-forge/references/quality-rubric.md +104 -0
  218. package/plugins/skills/skill-forge/references/skill-template.md +106 -0
  219. package/plugins/skills/startup-guard/SKILL.md +38 -0
  220. package/plugins/skills/testing-stage/SKILL.md +195 -0
  221. package/scripts/cli/global-init.js +288 -0
  222. package/scripts/cli/global.js +324 -0
  223. package/scripts/cli/index.js +55 -0
  224. package/scripts/cli/init.js +382 -0
  225. package/scripts/cli/list.js +69 -0
  226. package/scripts/cli/org.js +340 -0
  227. package/scripts/cli/update.js +44 -0
  228. package/scripts/config/commands.config.js +145 -0
  229. package/scripts/config/hooks.config.js +197 -0
  230. package/scripts/evolution/evolution-router.js +273 -0
  231. package/scripts/evolution/evolution-signal-collector.js +307 -0
  232. package/scripts/evolution/knowledge-loader.js +346 -0
  233. package/scripts/evolution/marketplace.js +317 -0
  234. package/scripts/evolution/version-manager.js +371 -0
  235. package/scripts/install/agents.js +106 -0
  236. package/scripts/install/commands.js +133 -0
  237. package/scripts/install/constants.js +424 -0
  238. package/scripts/install/hook-logger.js +536 -0
  239. package/scripts/install/hooks.js +110 -0
  240. package/scripts/install/index.js +39 -0
  241. package/scripts/install/skills.js +95 -0
  242. package/scripts/postinstall.js +25 -0
  243. package/scripts/state.js +376 -0
@@ -0,0 +1,326 @@
1
+ /**
2
+ * 项目结构检测模块(确定性规则)
3
+ *
4
+ * 通过目录扫描和构建文件检测识别项目结构,不依赖固定目录名。
5
+ */
6
+
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { detectTechStacks } from './technology-stack-detector.js';
10
+ import { detectDataAIComponents } from './data-and-ai-detector.js';
11
+
12
+ /**
13
+ * 检测项目结构
14
+ * @param {string} projectDir - 项目根目录
15
+ * @returns {Object} 项目结构分析结果
16
+ */
17
+ export function detectProjectStructure(projectDir) {
18
+ const structure = {
19
+ // 项目类型
20
+ projectType: null, // monorepo | single-app | microservices | library
21
+
22
+ // 技术栈列表
23
+ techStacks: [],
24
+
25
+ // 模块/子系统列表
26
+ modules: [],
27
+
28
+ // 入口文件
29
+ entryPoints: [],
30
+
31
+ // 数据/AI 组件
32
+ dataAIComponents: null,
33
+
34
+ // 目录结构概览
35
+ directoryOverview: []
36
+ };
37
+
38
+ // Step 1: 扫描目录结构
39
+ structure.directoryOverview = scanDirectories(projectDir);
40
+
41
+ // Step 2: 检测技术栈
42
+ structure.techStacks = detectTechStacks(projectDir);
43
+
44
+ // Step 3: 识别模块
45
+ structure.modules = identifyModules(projectDir, structure.techStacks);
46
+
47
+ // Step 4: 检测入口文件
48
+ structure.entryPoints = detectEntryPoints(projectDir, structure.techStacks);
49
+
50
+ // Step 5: 检测数据/AI 组件
51
+ structure.dataAIComponents = detectDataAIComponents(projectDir, structure.techStacks);
52
+
53
+ // Step 6: 推断项目类型
54
+ structure.projectType = inferProjectType(structure);
55
+
56
+ return structure;
57
+ }
58
+
59
+ /**
60
+ * 扫描目录结构
61
+ */
62
+ function scanDirectories(projectDir, maxDepth = 2) {
63
+ const result = [];
64
+
65
+ function scan(dir, depth) {
66
+ if (depth > maxDepth) return;
67
+
68
+ try {
69
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
70
+
71
+ for (const entry of entries) {
72
+ if (entry.isDirectory() && !shouldIgnore(entry.name)) {
73
+ const fullPath = path.join(dir, entry.name);
74
+ const relativePath = path.relative(projectDir, fullPath);
75
+
76
+ result.push({
77
+ name: entry.name,
78
+ path: relativePath,
79
+ depth: depth
80
+ });
81
+
82
+ scan(fullPath, depth + 1);
83
+ }
84
+ }
85
+ } catch (e) {
86
+ // 忽略无权限目录
87
+ }
88
+ }
89
+
90
+ scan(projectDir, 0);
91
+ return result;
92
+ }
93
+
94
+ /**
95
+ * 判断是否应该忽略的目录
96
+ */
97
+ function shouldIgnore(name) {
98
+ const ignorePatterns = [
99
+ 'node_modules', '.git', '.svn', '.hg',
100
+ 'dist', 'build', 'out', 'target',
101
+ '__pycache__', '.pytest_cache', '.mypy_cache',
102
+ 'venv', 'env', '.venv', '.env',
103
+ '.idea', '.vscode', '.claude',
104
+ '.autospec', 'docs', 'tests', 'test'
105
+ ];
106
+
107
+ return ignorePatterns.includes(name) || name.startsWith('.');
108
+ }
109
+
110
+ /**
111
+ * 识别模块
112
+ */
113
+ function identifyModules(projectDir, techStacks) {
114
+ const modules = [];
115
+
116
+ // 基于技术栈路径识别模块
117
+ const pathSet = new Set();
118
+ for (const tech of techStacks) {
119
+ const modulePath = tech.path;
120
+ if (modulePath && modulePath !== '.' && !pathSet.has(modulePath)) {
121
+ pathSet.add(modulePath);
122
+
123
+ modules.push({
124
+ name: path.basename(modulePath),
125
+ path: modulePath,
126
+ type: tech.type,
127
+ techStack: tech,
128
+ inferredFrom: 'build-file'
129
+ });
130
+ }
131
+ }
132
+
133
+ // 如果没有识别到模块,检查是否是单模块项目
134
+ if (modules.length === 0 && techStacks.length > 0) {
135
+ modules.push({
136
+ name: 'main',
137
+ path: '.',
138
+ type: techStacks[0].type,
139
+ techStack: techStacks[0],
140
+ inferredFrom: 'single-module'
141
+ });
142
+ }
143
+
144
+ return modules;
145
+ }
146
+
147
+ /**
148
+ * 检测入口文件
149
+ */
150
+ function detectEntryPoints(projectDir, techStacks) {
151
+ const entryPoints = [];
152
+
153
+ // 入口文件模式(确定性规则)
154
+ const entryPatterns = {
155
+ python: [
156
+ 'main.py', 'app.py', 'manage.py', 'run.py', 'wsgi.py', 'asgi.py',
157
+ 'src/main.py', 'app/main.py'
158
+ ],
159
+ javascript: [
160
+ 'index.js', 'app.js', 'server.js', 'main.js',
161
+ 'src/index.js', 'src/app.js', 'src/server.js',
162
+ 'index.ts', 'main.ts', 'app.ts',
163
+ 'src/index.ts', 'src/main.ts', 'src/app.ts'
164
+ ],
165
+ java: [
166
+ 'src/main/java/**/Application.java',
167
+ 'src/main/java/**/Main.java',
168
+ 'app/src/main/java/**/Application.java'
169
+ ],
170
+ go: [
171
+ 'main.go', 'cmd/main.go', 'cmd/server/main.go'
172
+ ],
173
+ rust: [
174
+ 'src/main.rs', 'src/lib.rs'
175
+ ],
176
+ dart: [
177
+ 'lib/main.dart'
178
+ ]
179
+ };
180
+
181
+ for (const tech of techStacks) {
182
+ const lang = tech.lang;
183
+ const patterns = entryPatterns[lang] || [];
184
+
185
+ for (const pattern of patterns) {
186
+ // 简单的文件存在检查
187
+ const searchPath = tech.path === '.' ? pattern : `${tech.path}/${pattern}`;
188
+
189
+ // 处理通配符
190
+ if (pattern.includes('**')) {
191
+ const baseDir = path.dirname(searchPath.replace('**', ''));
192
+ const fileName = path.basename(pattern);
193
+ const fullBaseDir = path.join(projectDir, baseDir);
194
+
195
+ if (fs.existsSync(fullBaseDir)) {
196
+ const found = findFileRecursive(fullBaseDir, fileName.replace('.java', ''));
197
+ if (found) {
198
+ entryPoints.push({
199
+ path: path.relative(projectDir, found),
200
+ lang: lang,
201
+ module: tech.path
202
+ });
203
+ }
204
+ }
205
+ } else {
206
+ const fullPath = path.join(projectDir, searchPath);
207
+ if (fs.existsSync(fullPath)) {
208
+ entryPoints.push({
209
+ path: searchPath,
210
+ lang: lang,
211
+ module: tech.path
212
+ });
213
+ }
214
+ }
215
+ }
216
+ }
217
+
218
+ return entryPoints;
219
+ }
220
+
221
+ /**
222
+ * 递归查找文件
223
+ */
224
+ function findFileRecursive(dir, namePart) {
225
+ try {
226
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
227
+
228
+ for (const entry of entries) {
229
+ if (entry.isDirectory()) {
230
+ const found = findFileRecursive(path.join(dir, entry.name), namePart);
231
+ if (found) return found;
232
+ } else if (entry.name.includes(namePart)) {
233
+ return path.join(dir, entry.name);
234
+ }
235
+ }
236
+ } catch (e) {
237
+ // 忽略
238
+ }
239
+
240
+ return null;
241
+ }
242
+
243
+ /**
244
+ * 推断项目类型
245
+ */
246
+ function inferProjectType(structure) {
247
+ const { techStacks, modules, directoryOverview } = structure;
248
+
249
+ // 多模块且有明确路径 → monorepo
250
+ if (modules.length > 1) {
251
+ // 检查是否有典型的 monorepo 目录
252
+ const hasPackages = directoryOverview.some(d => d.name === 'packages');
253
+ const hasApps = directoryOverview.some(d => d.name === 'apps');
254
+ const hasServices = directoryOverview.some(d => d.name === 'services');
255
+
256
+ if (hasPackages || hasApps) {
257
+ return 'monorepo';
258
+ }
259
+
260
+ if (modules.some(m => m.type === 'backend') &&
261
+ modules.some(m => m.type === 'frontend' || m.type === 'mobile')) {
262
+ return 'monorepo';
263
+ }
264
+
265
+ // 多个独立服务 → microservices
266
+ if (modules.filter(m => m.type === 'backend').length > 1) {
267
+ return 'microservices';
268
+ }
269
+
270
+ return 'monorepo';
271
+ }
272
+
273
+ // 单模块 → single-app 或 library
274
+ if (modules.length === 1) {
275
+ // 检查是否是库
276
+ const hasLibDir = directoryOverview.some(d => d.name === 'lib' || d.name === 'src');
277
+ const hasIndexFile = structure.entryPoints.some(e => e.path.includes('index.'));
278
+ const hasNoApp = !structure.entryPoints.some(e =>
279
+ e.path.includes('app.') || e.path.includes('server.') || e.path.includes('main.')
280
+ );
281
+
282
+ if (hasLibDir && hasIndexFile && hasNoApp) {
283
+ return 'library';
284
+ }
285
+
286
+ return 'single-app';
287
+ }
288
+
289
+ return 'unknown';
290
+ }
291
+
292
+ /**
293
+ * 获取项目结构摘要(用于展示)
294
+ */
295
+ export function getStructureSummary(structure) {
296
+ const lines = [];
297
+
298
+ lines.push(`项目类型:${structure.projectType}`);
299
+ lines.push('');
300
+
301
+ if (structure.techStacks.length > 0) {
302
+ lines.push('技术栈:');
303
+ for (const tech of structure.techStacks) {
304
+ const typeLabel = tech.type ? ` (${tech.type})` : '';
305
+ lines.push(` - ${tech.framework || tech.lang}${typeLabel} [${tech.path}]`);
306
+ }
307
+ lines.push('');
308
+ }
309
+
310
+ if (structure.modules.length > 0) {
311
+ lines.push('模块:');
312
+ for (const mod of structure.modules) {
313
+ lines.push(` - ${mod.name} [${mod.path}] (${mod.type})`);
314
+ }
315
+ lines.push('');
316
+ }
317
+
318
+ if (structure.entryPoints.length > 0) {
319
+ lines.push('入口文件:');
320
+ for (const entry of structure.entryPoints) {
321
+ lines.push(` - ${entry.path}`);
322
+ }
323
+ }
324
+
325
+ return lines.join('\n');
326
+ }
@@ -0,0 +1,346 @@
1
+ /**
2
+ * Rollback Tracker - 回退原因追踪模块
3
+ *
4
+ * 记录和分析回退事件,支持精准回退机制(DP6)
5
+ */
6
+
7
+ import { getMetrics, updateMetrics } from './hook-state-manager.js';
8
+ import { getTraceId, recordEvent } from './trace-context.js';
9
+ import { recordRollback } from './execution-path.js';
10
+
11
+ /**
12
+ * 回退级别
13
+ */
14
+ export const ROLLBACK_LEVELS = {
15
+ LEVEL_1: 1, // 内联重试
16
+ LEVEL_2: 2, // 修正循环(最多 3 次)
17
+ LEVEL_2_5: 2.5, // 3-Strike 假设验证
18
+ LEVEL_3: 3 // 升级人工
19
+ };
20
+
21
+ /**
22
+ * 回退触发原因
23
+ */
24
+ export const ROLLBACK_TRIGGERS = {
25
+ VALIDATION_FAIL: 'validation_fail', // Layer1/Layer2 验证失败
26
+ SAFETY_CHECK: 'safety_check', // 安全检查触发
27
+ HUMAN_INTERVENTION: 'human_intervention', // 人工干预
28
+ SCOPE_DRIFT: 'scope_drift', // 范围漂移
29
+ DESIGN_GAP: 'design_gap', // 设计缺陷
30
+ ENV_ISSUE: 'env_issue' // 环境问题
31
+ };
32
+
33
+ /**
34
+ * 回退结果
35
+ */
36
+ export const ROLLBACK_OUTCOMES = {
37
+ SUCCESS: 'success', // 回退成功,继续执行
38
+ ESCALATE: 'escalate', // 需要升级
39
+ BLOCKED: 'blocked', // 被阻塞
40
+ RETRY: 'retry' // 需要重试
41
+ };
42
+
43
+ /**
44
+ * 记录回退事件
45
+ * @param {string} projectRoot - 项目根目录
46
+ * @param {Object} rollbackInfo - 回退信息
47
+ * @returns {Object} 记录结果
48
+ */
49
+ export function trackRollback(projectRoot, rollbackInfo) {
50
+ const {
51
+ level,
52
+ trigger,
53
+ stage,
54
+ rootCause,
55
+ attemptedFix,
56
+ outcome,
57
+ context = {}
58
+ } = rollbackInfo;
59
+
60
+ const traceId = getTraceId(projectRoot);
61
+
62
+ // 创建回退记录
63
+ const entry = {
64
+ timestamp: new Date().toISOString(),
65
+ traceId,
66
+ level,
67
+ trigger,
68
+ stage,
69
+ rootCause,
70
+ attemptedFix,
71
+ outcome,
72
+ context,
73
+ retryCount: context.retryCount || 0
74
+ };
75
+
76
+ // 更新 metrics.json
77
+ const metrics = getMetrics(projectRoot, false);
78
+
79
+ if (!metrics.rollbacks) {
80
+ metrics.rollbacks = [];
81
+ }
82
+
83
+ metrics.rollbacks.push(entry);
84
+
85
+ // 更新汇总统计
86
+ if (!metrics.rollbackSummary) {
87
+ metrics.rollbackSummary = {
88
+ total: 0,
89
+ byLevel: {},
90
+ byTrigger: {},
91
+ byOutcome: {},
92
+ successRate: 0
93
+ };
94
+ }
95
+
96
+ metrics.rollbackSummary.total++;
97
+ metrics.rollbackSummary.byLevel[level] = (metrics.rollbackSummary.byLevel[level] || 0) + 1;
98
+ metrics.rollbackSummary.byTrigger[trigger] = (metrics.rollbackSummary.byTrigger[trigger] || 0) + 1;
99
+ metrics.rollbackSummary.byOutcome[outcome] = (metrics.rollbackSummary.byOutcome[outcome] || 0) + 1;
100
+
101
+ // 计算成功率
102
+ const successCount = metrics.rollbacks.filter(r => r.outcome === ROLLBACK_OUTCOMES.SUCCESS).length;
103
+ metrics.rollbackSummary.successRate = successCount / metrics.rollbacks.length;
104
+
105
+ updateMetrics(projectRoot, metrics);
106
+
107
+ // 记录到执行路径
108
+ recordRollback(projectRoot, level, trigger, outcome, {
109
+ stage,
110
+ rootCause
111
+ });
112
+
113
+ // 记录到 trace 日志
114
+ if (traceId) {
115
+ recordEvent(projectRoot, 'rollback', {
116
+ source: 'rollback-tracker',
117
+ stage,
118
+ action: 'rollback',
119
+ data: {
120
+ level,
121
+ trigger,
122
+ outcome,
123
+ rootCause
124
+ }
125
+ });
126
+ }
127
+
128
+ return entry;
129
+ }
130
+
131
+ /**
132
+ * 获取回退历史
133
+ * @param {string} projectRoot - 项目根目录
134
+ * @param {Object} filters - 过滤条件
135
+ * @returns {Array} 回退历史
136
+ */
137
+ export function getRollbackHistory(projectRoot, filters = {}) {
138
+ const metrics = getMetrics(projectRoot, true);
139
+ let rollbacks = metrics?.rollbacks || [];
140
+
141
+ if (filters.stage) {
142
+ rollbacks = rollbacks.filter(r => r.stage === filters.stage);
143
+ }
144
+
145
+ if (filters.trigger) {
146
+ rollbacks = rollbacks.filter(r => r.trigger === filters.trigger);
147
+ }
148
+
149
+ if (filters.level) {
150
+ rollbacks = rollbacks.filter(r => r.level === filters.level);
151
+ }
152
+
153
+ if (filters.traceId) {
154
+ rollbacks = rollbacks.filter(r => r.traceId === filters.traceId);
155
+ }
156
+
157
+ return rollbacks;
158
+ }
159
+
160
+ /**
161
+ * 分析回退模式
162
+ * @param {string} projectRoot - 项目根目录
163
+ * @returns {Object} 回退模式分析
164
+ */
165
+ export function analyzeRollbackPatterns(projectRoot) {
166
+ const metrics = getMetrics(projectRoot, true);
167
+ const rollbacks = metrics?.rollbacks || [];
168
+
169
+ if (rollbacks.length === 0) {
170
+ return {
171
+ hasPatterns: false,
172
+ patterns: [],
173
+ recommendations: []
174
+ };
175
+ }
176
+
177
+ const patterns = [];
178
+
179
+ // 检测重复触发模式
180
+ const triggerCounts = {};
181
+ for (const rollback of rollbacks) {
182
+ triggerCounts[rollback.trigger] = (triggerCounts[rollback.trigger] || 0) + 1;
183
+ }
184
+
185
+ for (const [trigger, count] of Object.entries(triggerCounts)) {
186
+ if (count >= 3) {
187
+ patterns.push({
188
+ type: 'repeated_trigger',
189
+ trigger,
190
+ count,
191
+ severity: 'high',
192
+ message: `${trigger} 触发回退 ${count} 次,建议检查根本原因`
193
+ });
194
+ }
195
+ }
196
+
197
+ // 检测阶段回退模式
198
+ const stageCounts = {};
199
+ for (const rollback of rollbacks) {
200
+ stageCounts[rollback.stage] = (stageCounts[rollback.stage] || 0) + 1;
201
+ }
202
+
203
+ for (const [stage, count] of Object.entries(stageCounts)) {
204
+ if (count >= 3) {
205
+ patterns.push({
206
+ type: 'stage_issue',
207
+ stage,
208
+ count,
209
+ severity: 'medium',
210
+ message: `${stage} 阶段回退 ${count} 次,可能需要改进该阶段的 skill`
211
+ });
212
+ }
213
+ }
214
+
215
+ // 检测升级模式
216
+ const escalatedRollbacks = rollbacks.filter(r => r.outcome === ROLLBACK_OUTCOMES.ESCALATE);
217
+ if (escalatedRollbacks.length >= 2) {
218
+ patterns.push({
219
+ type: 'escalation_pattern',
220
+ count: escalatedRollbacks.length,
221
+ severity: 'high',
222
+ message: `${escalatedRollbacks.length} 次回退升级到人工,建议分析是否可自动化`
223
+ });
224
+ }
225
+
226
+ // 生成建议
227
+ const recommendations = [];
228
+ for (const pattern of patterns) {
229
+ if (pattern.type === 'repeated_trigger') {
230
+ recommendations.push({
231
+ priority: 'high',
232
+ area: pattern.trigger,
233
+ suggestion: `针对 ${pattern.trigger} 创建专门的 skill 或更新现有 skill`
234
+ });
235
+ } else if (pattern.type === 'stage_issue') {
236
+ recommendations.push({
237
+ priority: 'medium',
238
+ area: pattern.stage,
239
+ suggestion: `改进 ${pattern.stage} 阶段的执行策略`
240
+ });
241
+ } else if (pattern.type === 'escalation_pattern') {
242
+ recommendations.push({
243
+ priority: 'high',
244
+ area: 'automation',
245
+ suggestion: '分析升级原因,考虑自动化解决方案'
246
+ });
247
+ }
248
+ }
249
+
250
+ return {
251
+ hasPatterns: patterns.length > 0,
252
+ patterns,
253
+ recommendations,
254
+ summary: metrics?.rollbackSummary || {}
255
+ };
256
+ }
257
+
258
+ /**
259
+ * 检查是否需要升级人工
260
+ * @param {string} projectRoot - 项目根目录
261
+ * @param {string} stage - 当前阶段
262
+ * @param {string} trigger - 触发原因
263
+ * @returns {Object} { shouldEscalate: boolean, reason: string }
264
+ */
265
+ export function shouldEscalateToHuman(projectRoot, stage, trigger) {
266
+ const metrics = getMetrics(projectRoot, true);
267
+ const rollbacks = metrics?.rollbacks || [];
268
+
269
+ // 检查同一阶段同一触发原因的回退次数
270
+ const recentRollbacks = rollbacks.filter(r =>
271
+ r.stage === stage &&
272
+ r.trigger === trigger &&
273
+ Date.now() - new Date(r.timestamp).getTime() < 30 * 60 * 1000 // 30 分钟内
274
+ );
275
+
276
+ if (recentRollbacks.length >= 3) {
277
+ return {
278
+ shouldEscalate: true,
279
+ reason: `同一问题在 30 分钟内回退 ${recentRollbacks.length} 次,建议升级人工处理`
280
+ };
281
+ }
282
+
283
+ // 检查 Level 2 回退次数
284
+ const level2Rollbacks = rollbacks.filter(r =>
285
+ r.level === ROLLBACK_LEVELS.LEVEL_2 &&
286
+ r.stage === stage
287
+ );
288
+
289
+ if (level2Rollbacks.length >= 3) {
290
+ return {
291
+ shouldEscalate: true,
292
+ reason: `Level 2 修正循环已达 ${level2Rollbacks.length} 次,需要人工介入`
293
+ };
294
+ }
295
+
296
+ return {
297
+ shouldEscalate: false,
298
+ reason: '回退次数在可接受范围内'
299
+ };
300
+ }
301
+
302
+ /**
303
+ * 生成回退报告
304
+ * @param {string} projectRoot - 项目根目录
305
+ * @returns {Object} 回退报告
306
+ */
307
+ export function generateRollbackReport(projectRoot) {
308
+ const history = getRollbackHistory(projectRoot);
309
+ const patterns = analyzeRollbackPatterns(projectRoot);
310
+ const metrics = getMetrics(projectRoot, true);
311
+
312
+ return {
313
+ summary: {
314
+ totalRollbacks: history.length,
315
+ successRate: metrics?.rollbackSummary?.successRate || 0,
316
+ mostCommonTrigger: getMostCommon(metrics?.rollbackSummary?.byTrigger),
317
+ mostProblematicStage: getMostCommon(metrics?.rollbackSummary?.byStage)
318
+ },
319
+ patterns,
320
+ recentRollbacks: history.slice(-10),
321
+ recommendations: patterns.recommendations
322
+ };
323
+ }
324
+
325
+ /**
326
+ * 获取最常见的项
327
+ */
328
+ function getMostCommon(counts) {
329
+ if (!counts || Object.keys(counts).length === 0) {
330
+ return null;
331
+ }
332
+
333
+ return Object.entries(counts)
334
+ .sort((a, b) => b[1] - a[1])[0][0];
335
+ }
336
+
337
+ export default {
338
+ ROLLBACK_LEVELS,
339
+ ROLLBACK_TRIGGERS,
340
+ ROLLBACK_OUTCOMES,
341
+ trackRollback,
342
+ getRollbackHistory,
343
+ analyzeRollbackPatterns,
344
+ shouldEscalateToHuman,
345
+ generateRollbackReport
346
+ };