autosnippet 3.3.5 → 3.3.7

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 (279) hide show
  1. package/dashboard/dist/assets/icons-FHns2ypa.js +1 -0
  2. package/dashboard/dist/assets/index-BRJv5Y3r.js +135 -0
  3. package/dashboard/dist/assets/index-DzoB7kxK.css +1 -0
  4. package/dashboard/dist/index.html +3 -3
  5. package/dist/bin/api-server.js +1 -0
  6. package/dist/bin/cli.d.ts +1 -0
  7. package/dist/bin/cli.js +137 -9
  8. package/dist/lib/agent/AgentFactory.d.ts +0 -17
  9. package/dist/lib/agent/AgentFactory.js +1 -25
  10. package/dist/lib/agent/AgentRuntime.d.ts +2 -2
  11. package/dist/lib/agent/AgentRuntime.js +26 -18
  12. package/dist/lib/agent/capabilities.d.ts +11 -0
  13. package/dist/lib/agent/capabilities.js +29 -5
  14. package/dist/lib/agent/context/ExplorationTracker.js +10 -1
  15. package/dist/lib/agent/context/exploration/ExplorationStrategies.d.ts +2 -0
  16. package/dist/lib/agent/context/exploration/ExplorationStrategies.js +2 -2
  17. package/dist/lib/agent/domain/ChatAgentTasks.js +4 -0
  18. package/dist/lib/agent/domain/insight-analyst.d.ts +47 -3
  19. package/dist/lib/agent/domain/insight-analyst.js +111 -11
  20. package/dist/lib/agent/domain/insight-evolver.d.ts +69 -0
  21. package/dist/lib/agent/domain/insight-evolver.js +230 -0
  22. package/dist/lib/agent/domain/insight-gate.d.ts +42 -0
  23. package/dist/lib/agent/domain/insight-gate.js +41 -0
  24. package/dist/lib/agent/domain/insight-producer.d.ts +27 -2
  25. package/dist/lib/agent/domain/insight-producer.js +60 -5
  26. package/dist/lib/agent/domain/scan-prompts.js +10 -7
  27. package/dist/lib/agent/forced-summary.js +7 -2
  28. package/dist/lib/agent/memory/ActiveContext.d.ts +2 -28
  29. package/dist/lib/agent/memory/MemoryCoordinator.d.ts +2 -2
  30. package/dist/lib/agent/memory/SessionStore.d.ts +6 -12
  31. package/dist/lib/agent/memory/SessionStore.js +9 -15
  32. package/dist/lib/agent/memory/memory-flush-contract.d.ts +49 -0
  33. package/dist/lib/agent/memory/memory-flush-contract.js +16 -0
  34. package/dist/lib/agent/memory/session-store-schema.d.ts +20 -0
  35. package/dist/lib/agent/memory/session-store-schema.js +41 -0
  36. package/dist/lib/agent/presets.d.ts +89 -1
  37. package/dist/lib/agent/presets.js +53 -5
  38. package/dist/lib/agent/tools/_shared.d.ts +7 -15
  39. package/dist/lib/agent/tools/_shared.js +20 -21
  40. package/dist/lib/agent/tools/composite.d.ts +25 -22
  41. package/dist/lib/agent/tools/composite.js +108 -109
  42. package/dist/lib/agent/tools/evolution-tools.d.ts +145 -0
  43. package/dist/lib/agent/tools/evolution-tools.js +161 -0
  44. package/dist/lib/agent/tools/index.d.ts +163 -92
  45. package/dist/lib/agent/tools/index.js +9 -1
  46. package/dist/lib/agent/tools/lifecycle.d.ts +7 -1
  47. package/dist/lib/agent/tools/lifecycle.js +59 -75
  48. package/dist/lib/cli/AiScanService.js +5 -5
  49. package/dist/lib/cli/KnowledgeSyncService.js +1 -1
  50. package/dist/lib/core/AstAnalyzer.d.ts +1 -0
  51. package/dist/lib/core/discovery/ConfigWatcher.d.ts +64 -0
  52. package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
  53. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +30 -0
  54. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1305 -0
  55. package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
  56. package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
  57. package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
  58. package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
  59. package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
  60. package/dist/lib/core/discovery/index.d.ts +2 -0
  61. package/dist/lib/core/discovery/index.js +4 -0
  62. package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
  63. package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
  64. package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
  65. package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
  66. package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
  67. package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
  68. package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
  69. package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
  70. package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
  71. package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
  72. package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
  73. package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
  74. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.d.ts → domain/dimension/DimensionCopy.d.ts} +2 -2
  75. package/dist/lib/{service/bootstrap/DimensionCopyRegistry.js → domain/dimension/DimensionCopy.js} +22 -72
  76. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +54 -0
  77. package/dist/lib/domain/dimension/DimensionRegistry.js +620 -0
  78. package/dist/lib/domain/dimension/DimensionSop.d.ts +55 -0
  79. package/dist/lib/domain/dimension/DimensionSop.js +1604 -0
  80. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +61 -0
  81. package/dist/lib/domain/dimension/UnifiedDimension.js +53 -0
  82. package/dist/lib/domain/dimension/index.d.ts +10 -0
  83. package/dist/lib/domain/dimension/index.js +9 -0
  84. package/dist/lib/domain/knowledge/FieldSpec.d.ts +1 -1
  85. package/dist/lib/domain/knowledge/FieldSpec.js +29 -16
  86. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +40 -112
  87. package/dist/lib/domain/knowledge/KnowledgeEntry.js +44 -9
  88. package/dist/lib/domain/knowledge/KnowledgeRepository.d.ts +1 -0
  89. package/dist/lib/domain/knowledge/KnowledgeRepository.js +3 -0
  90. package/dist/lib/domain/knowledge/Lifecycle.js +1 -1
  91. package/dist/lib/domain/knowledge/StyleGuide.d.ts +1 -1
  92. package/dist/lib/domain/knowledge/StyleGuide.js +1 -1
  93. package/dist/lib/domain/knowledge/UnifiedValidator.js +15 -0
  94. package/dist/lib/external/ai/AiProvider.d.ts +12 -0
  95. package/dist/lib/external/ai/AiProvider.js +24 -0
  96. package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
  97. package/dist/lib/external/ai/AiProviderManager.js +193 -0
  98. package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
  99. package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
  100. package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
  101. package/dist/lib/external/ai/providers/MockProvider.js +290 -14
  102. package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
  103. package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
  104. package/dist/lib/external/lark/LarkTransport.js +10 -2
  105. package/dist/lib/external/mcp/McpServer.js +4 -0
  106. package/dist/lib/external/mcp/handlers/TargetClassifier.d.ts +1 -1
  107. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.d.ts +8 -16
  108. package/dist/lib/external/mcp/handlers/bootstrap/BootstrapSession.js +10 -10
  109. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.d.ts +7 -0
  110. package/dist/lib/external/mcp/handlers/bootstrap/ExternalSubmissionTracker.js +20 -0
  111. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +52 -132
  112. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +204 -17
  113. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.d.ts +11 -75
  114. package/dist/lib/external/mcp/handlers/bootstrap/base-dimensions.js +40 -191
  115. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.d.ts +13 -78
  116. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-configs.js +30 -52
  117. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.d.ts +0 -1
  118. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.d.ts +20 -0
  119. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
  120. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.d.ts +99 -12
  121. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +188 -169
  122. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +7 -17
  123. package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
  124. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.d.ts +46 -0
  125. package/dist/lib/external/mcp/handlers/bootstrap/shared/async-fill-helpers.js +58 -0
  126. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.d.ts +25 -0
  127. package/dist/lib/external/mcp/handlers/bootstrap/shared/audit-helpers.js +47 -0
  128. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +50 -12
  129. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +30 -10
  130. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-text.js +1 -1
  131. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.d.ts +24 -0
  132. package/dist/lib/external/mcp/handlers/bootstrap/shared/handler-types.js +14 -0
  133. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.d.ts +14 -0
  134. package/dist/lib/external/mcp/handlers/bootstrap/shared/panorama-utils.js +48 -0
  135. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.d.ts +21 -0
  136. package/dist/lib/external/mcp/handlers/bootstrap/shared/session-helpers.js +45 -0
  137. package/dist/lib/external/mcp/handlers/bootstrap/shared/skill-generator.d.ts +1 -1
  138. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.d.ts +27 -0
  139. package/dist/lib/external/mcp/handlers/bootstrap/shared/target-file-map.js +44 -0
  140. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +23 -10
  141. package/dist/lib/external/mcp/handlers/bootstrap-external.js +41 -51
  142. package/dist/lib/external/mcp/handlers/bootstrap-internal.d.ts +2 -0
  143. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +117 -82
  144. package/dist/lib/external/mcp/handlers/consolidated.d.ts +4 -4
  145. package/dist/lib/external/mcp/handlers/consolidated.js +108 -332
  146. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +71 -2
  147. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +54 -0
  148. package/dist/lib/external/mcp/handlers/evolve-external.js +229 -0
  149. package/dist/lib/external/mcp/handlers/knowledge.js +30 -5
  150. package/dist/lib/external/mcp/handlers/rescan-external.d.ts +76 -0
  151. package/dist/lib/external/mcp/handlers/rescan-external.js +335 -0
  152. package/dist/lib/external/mcp/handlers/rescan-internal.d.ts +120 -0
  153. package/dist/lib/external/mcp/handlers/rescan-internal.js +359 -0
  154. package/dist/lib/external/mcp/handlers/search.d.ts +6 -5
  155. package/dist/lib/external/mcp/handlers/search.js +6 -5
  156. package/dist/lib/external/mcp/handlers/types.d.ts +2 -1
  157. package/dist/lib/external/mcp/handlers/wiki-external.js +2 -2
  158. package/dist/lib/external/mcp/tools.d.ts +8 -18
  159. package/dist/lib/external/mcp/tools.js +58 -2
  160. package/dist/lib/http/routes/ai.js +111 -30
  161. package/dist/lib/http/routes/candidates.js +11 -4
  162. package/dist/lib/http/routes/commands.js +10 -1
  163. package/dist/lib/http/routes/health.js +11 -0
  164. package/dist/lib/http/routes/knowledge.js +122 -1
  165. package/dist/lib/http/routes/modules.js +52 -3
  166. package/dist/lib/http/routes/panorama.js +16 -4
  167. package/dist/lib/http/routes/recipes.js +7 -0
  168. package/dist/lib/http/utils/routeHelpers.js +2 -1
  169. package/dist/lib/infrastructure/cache/CacheCoordinator.d.ts +41 -0
  170. package/dist/lib/infrastructure/cache/CacheCoordinator.js +105 -0
  171. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.d.ts +7 -0
  172. package/dist/lib/infrastructure/database/migrations/006_lifecycle_transition_events.js +28 -0
  173. package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +1 -1
  174. package/dist/lib/injection/ServiceContainer.d.ts +6 -5
  175. package/dist/lib/injection/ServiceContainer.js +64 -25
  176. package/dist/lib/injection/ServiceMap.d.ts +10 -1
  177. package/dist/lib/injection/modules/AiModule.d.ts +6 -9
  178. package/dist/lib/injection/modules/AiModule.js +82 -39
  179. package/dist/lib/injection/modules/KnowledgeModule.js +15 -1
  180. package/dist/lib/injection/modules/PanoramaModule.js +1 -1
  181. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +4 -0
  182. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +16 -1
  183. package/dist/lib/service/bootstrap/BootstrapEventEmitter.d.ts +3 -2
  184. package/dist/lib/service/bootstrap/BootstrapEventEmitter.js +1 -1
  185. package/dist/lib/service/bootstrap/DeliveryVerifier.d.ts +51 -0
  186. package/dist/lib/service/bootstrap/DeliveryVerifier.js +163 -0
  187. package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +5 -0
  188. package/dist/lib/service/bootstrap/UiStartupTasks.js +20 -0
  189. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +54 -0
  190. package/dist/lib/service/bootstrap/bootstrap-event-types.js +10 -0
  191. package/dist/lib/service/cleanup/CleanupService.d.ts +132 -0
  192. package/dist/lib/service/cleanup/CleanupService.js +571 -0
  193. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +39 -43
  194. package/dist/lib/service/delivery/FileProtection.d.ts +20 -0
  195. package/dist/lib/service/delivery/FileProtection.js +54 -0
  196. package/dist/lib/service/delivery/SkillsSyncer.js +16 -21
  197. package/dist/lib/service/evolution/ContentPatcher.d.ts +44 -0
  198. package/dist/lib/service/evolution/ContentPatcher.js +310 -0
  199. package/dist/lib/service/evolution/ProposalExecutor.d.ts +4 -0
  200. package/dist/lib/service/evolution/ProposalExecutor.js +77 -13
  201. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +64 -0
  202. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +458 -0
  203. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +89 -0
  204. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +492 -0
  205. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +44 -0
  206. package/dist/lib/service/evolution/createSupersedeProposal.js +81 -0
  207. package/dist/lib/service/guard/ComplianceReporter.d.ts +4 -0
  208. package/dist/lib/service/guard/ComplianceReporter.js +51 -0
  209. package/dist/lib/service/guard/GuardCheckEngine.js +5 -4
  210. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +6 -0
  211. package/dist/lib/service/knowledge/CodeEntityGraph.js +16 -0
  212. package/dist/lib/service/knowledge/ConfidenceRouter.js +1 -1
  213. package/dist/lib/service/knowledge/KnowledgeService.d.ts +11 -1
  214. package/dist/lib/service/knowledge/KnowledgeService.js +67 -14
  215. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +225 -0
  216. package/dist/lib/service/knowledge/RecipeProductionGateway.js +384 -0
  217. package/dist/lib/service/module/ModuleService.js +10 -19
  218. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +10 -1
  219. package/dist/lib/service/panorama/CouplingAnalyzer.js +44 -2
  220. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +4 -3
  221. package/dist/lib/service/panorama/DimensionAnalyzer.js +40 -151
  222. package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
  223. package/dist/lib/service/panorama/LayerInferrer.js +118 -1
  224. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +9 -0
  225. package/dist/lib/service/panorama/ModuleDiscoverer.js +58 -2
  226. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +6 -2
  227. package/dist/lib/service/panorama/PanoramaAggregator.js +84 -6
  228. package/dist/lib/service/panorama/PanoramaScanner.js +28 -0
  229. package/dist/lib/service/panorama/PanoramaService.js +10 -5
  230. package/dist/lib/service/panorama/PanoramaTypes.d.ts +38 -0
  231. package/dist/lib/service/panorama/RoleRefiner.d.ts +2 -0
  232. package/dist/lib/service/panorama/RoleRefiner.js +41 -0
  233. package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
  234. package/dist/lib/service/panorama/TechStackProfiler.js +191 -0
  235. package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
  236. package/dist/lib/service/search/SearchEngine.d.ts +11 -10
  237. package/dist/lib/service/search/SearchEngine.js +38 -36
  238. package/dist/lib/service/search/SearchTypes.d.ts +14 -8
  239. package/dist/lib/service/search/SearchTypes.js +1 -1
  240. package/dist/lib/service/search/tokenizer.d.ts +1 -1
  241. package/dist/lib/service/search/tokenizer.js +2 -2
  242. package/dist/lib/service/skills/SignalCollector.d.ts +1 -0
  243. package/dist/lib/service/skills/SignalCollector.js +6 -5
  244. package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
  245. package/dist/lib/service/vector/ContextualEnricher.js +4 -0
  246. package/dist/lib/shared/LanguageService.js +3 -0
  247. package/dist/lib/shared/developer-identity.d.ts +18 -0
  248. package/dist/lib/shared/developer-identity.js +62 -0
  249. package/dist/lib/shared/schemas/common.d.ts +4 -4
  250. package/dist/lib/shared/schemas/http-requests.d.ts +20 -18
  251. package/dist/lib/shared/schemas/http-requests.js +17 -6
  252. package/dist/lib/shared/schemas/mcp-tools.d.ts +32 -2
  253. package/dist/lib/shared/schemas/mcp-tools.js +38 -0
  254. package/dist/lib/types/evolution.d.ts +135 -0
  255. package/dist/lib/types/evolution.js +6 -0
  256. package/dist/lib/types/graph-shared.d.ts +25 -0
  257. package/dist/lib/types/graph-shared.js +7 -0
  258. package/dist/lib/types/knowledge-wire.d.ts +132 -0
  259. package/dist/lib/types/knowledge-wire.js +7 -0
  260. package/dist/lib/types/project-snapshot-builder.d.ts +19 -0
  261. package/dist/lib/types/project-snapshot-builder.js +189 -0
  262. package/dist/lib/types/project-snapshot.d.ts +399 -0
  263. package/dist/lib/types/project-snapshot.js +17 -0
  264. package/dist/lib/types/search-wire.d.ts +46 -0
  265. package/dist/lib/types/search-wire.js +7 -0
  266. package/dist/lib/types/snapshot-views.d.ts +58 -0
  267. package/dist/lib/types/snapshot-views.js +103 -0
  268. package/package.json +1 -1
  269. package/skills/autosnippet-recipes/SKILL.md +1 -1
  270. package/templates/instructions/agent-static.md +2 -0
  271. package/templates/instructions/conventions.md +3 -1
  272. package/templates/recipes-setup/README.md +2 -2
  273. package/dashboard/dist/assets/icons-BJ2mUBi8.js +0 -1
  274. package/dashboard/dist/assets/index-B659K9t5.js +0 -128
  275. package/dashboard/dist/assets/index-NCm40PMD.css +0 -1
  276. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.d.ts +0 -169
  277. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/noAiFallback.js +0 -727
  278. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.d.ts +0 -370
  279. package/dist/lib/external/mcp/handlers/bootstrap/shared/dimension-sop.js +0 -821
@@ -1,727 +0,0 @@
1
- /**
2
- * noAiFallback.js — AI 不可用时的规则化降级知识提取
3
- *
4
- * 当 AgentRuntime / AI Provider 不可用时,从 Phase 1-4 的结构化数据中
5
- * 提取基础知识候选和 Project Skill,覆盖以下维度:
6
- *
7
- * ✅ project-profile — 从 langStats + depGraph + targets 构建项目技术画像
8
- * ✅ architecture — 从 depGraph + targets 推断层级/模块关系
9
- * ✅ code-standard — 从 AST 统计推断命名约定和代码风格
10
- * ✅ best-practice — 从 Guard 违规推断反模式
11
- * ✅ agent-guidelines — 从 Guard 高频违规 + 语言特性生成 Agent 注意事项
12
- *
13
- * 产出质量标注为 `source: 'rule-based-fallback'`,区别于 AI 分析产出。
14
- */
15
- import Logger from '#infra/logging/Logger.js';
16
- const logger = Logger.getInstance();
17
- /**
18
- * 主入口 — 当 AI 不可用时调用
19
- *
20
- * @param fillContext 与 fillDimensionsV3 相同的上下文
21
- * @returns >}
22
- */
23
- export async function runNoAiFallback(fillContext) {
24
- const {
25
- // ctx and projectRoot are part of fillContext API but unused in fallback path
26
- dimensions, depGraphData, guardAudit, langStats, primaryLang, astProjectSummary, taskManager, sessionId, } = fillContext;
27
- const t0 = Date.now();
28
- logger.info('[Bootstrap-fallback] Starting rule-based fallback (no AI)');
29
- const candidates = [];
30
- const skills = [];
31
- const report = {
32
- dimensionsProcessed: 0,
33
- candidatesCreated: 0,
34
- skillsCreated: 0,
35
- errors: [],
36
- };
37
- // ── 收集原始数据 ──
38
- const allFiles = fillContext.allFiles || [];
39
- const targetFileMap = fillContext.targetFileMap || {};
40
- const allTargets = Object.keys(targetFileMap);
41
- // ── 1. Project Profile ──
42
- try {
43
- const profile = _buildProjectProfile({
44
- langStats,
45
- primaryLang,
46
- depGraphData,
47
- allTargets,
48
- allFiles,
49
- astProjectSummary,
50
- });
51
- if (profile) {
52
- candidates.push(profile);
53
- skills.push(_wrapAsSkill('project-profile', '项目技术画像', profile.content.markdown));
54
- report.candidatesCreated++;
55
- report.skillsCreated++;
56
- }
57
- _markDimDone(taskManager, sessionId, 'project-profile', 'fallback');
58
- }
59
- catch (e) {
60
- report.errors.push({
61
- dim: 'project-profile',
62
- error: e instanceof Error ? e.message : String(e),
63
- });
64
- _markDimDone(taskManager, sessionId, 'project-profile', 'error');
65
- }
66
- // ── 2. Architecture ──
67
- try {
68
- const arch = _buildArchitecture({
69
- depGraphData,
70
- allTargets,
71
- targetFileMap,
72
- primaryLang,
73
- astProjectSummary,
74
- });
75
- if (arch) {
76
- candidates.push(arch);
77
- skills.push(_wrapAsSkill('architecture', '模块架构', arch.content.markdown));
78
- report.candidatesCreated++;
79
- report.skillsCreated++;
80
- }
81
- _markDimDone(taskManager, sessionId, 'architecture', 'fallback');
82
- }
83
- catch (e) {
84
- report.errors.push({ dim: 'architecture', error: e instanceof Error ? e.message : String(e) });
85
- _markDimDone(taskManager, sessionId, 'architecture', 'error');
86
- }
87
- // ── 3. Code Standard ──
88
- try {
89
- const standard = _buildCodeStandard({ astProjectSummary, primaryLang, allFiles });
90
- if (standard) {
91
- candidates.push(standard);
92
- skills.push(_wrapAsSkill('code-standard', '代码规范', standard.content.markdown));
93
- report.candidatesCreated++;
94
- report.skillsCreated++;
95
- }
96
- _markDimDone(taskManager, sessionId, 'code-standard', 'fallback');
97
- }
98
- catch (e) {
99
- report.errors.push({ dim: 'code-standard', error: e instanceof Error ? e.message : String(e) });
100
- _markDimDone(taskManager, sessionId, 'code-standard', 'error');
101
- }
102
- // ── 4. Best Practice (from Guard violations) ──
103
- try {
104
- const bp = _buildBestPractice({ guardAudit, primaryLang });
105
- if (bp) {
106
- candidates.push(bp);
107
- skills.push(_wrapAsSkill('best-practice', '最佳实践', bp.content.markdown));
108
- report.candidatesCreated++;
109
- report.skillsCreated++;
110
- }
111
- _markDimDone(taskManager, sessionId, 'best-practice', 'fallback');
112
- }
113
- catch (e) {
114
- report.errors.push({ dim: 'best-practice', error: e instanceof Error ? e.message : String(e) });
115
- _markDimDone(taskManager, sessionId, 'best-practice', 'error');
116
- }
117
- // ── 5. Agent Guidelines ──
118
- try {
119
- const guidelines = _buildAgentGuidelines({ guardAudit, primaryLang, astProjectSummary });
120
- if (guidelines) {
121
- candidates.push(guidelines);
122
- skills.push(_wrapAsSkill('agent-guidelines', '项目开发强制规范', guidelines.content.markdown));
123
- report.candidatesCreated++;
124
- report.skillsCreated++;
125
- }
126
- _markDimDone(taskManager, sessionId, 'agent-guidelines', 'fallback');
127
- }
128
- catch (e) {
129
- report.errors.push({
130
- dim: 'agent-guidelines',
131
- error: e instanceof Error ? e.message : String(e),
132
- });
133
- _markDimDone(taskManager, sessionId, 'agent-guidelines', 'error');
134
- }
135
- // ── 标记剩余未处理维度 ──
136
- const processedDims = new Set([
137
- 'project-profile',
138
- 'architecture',
139
- 'code-standard',
140
- 'best-practice',
141
- 'agent-guidelines',
142
- ]);
143
- for (const dim of dimensions) {
144
- if (!processedDims.has(dim.id)) {
145
- _markDimDone(taskManager, sessionId, dim.id, 'skipped-no-ai');
146
- }
147
- }
148
- report.dimensionsProcessed = processedDims.size;
149
- const elapsed = Date.now() - t0;
150
- logger.info(`[Bootstrap-fallback] Complete: ${report.candidatesCreated} candidates, ${report.skillsCreated} skills in ${elapsed}ms`);
151
- return { candidates, skills, report };
152
- }
153
- // ═══════════════════════════════════════════════════════════
154
- // 维度构建器
155
- // ═══════════════════════════════════════════════════════════
156
- function _buildProjectProfile({ langStats, primaryLang, depGraphData, allTargets, allFiles, astProjectSummary, }) {
157
- const lines = ['## 项目技术画像', ''];
158
- // 语言统计
159
- const sortedLangs = Object.entries(langStats || {})
160
- .sort(([, a], [, b]) => b - a)
161
- .slice(0, 8);
162
- if (sortedLangs.length > 0) {
163
- lines.push('### 语言分布', '');
164
- lines.push('| 语言 | 文件数 | 占比 |');
165
- lines.push('|------|--------|------|');
166
- const total = sortedLangs.reduce((s, [, c]) => s + c, 0);
167
- for (const [lang, count] of sortedLangs) {
168
- lines.push(`| ${lang} | ${count} | ${((count / total) * 100).toFixed(1)}% |`);
169
- }
170
- lines.push('');
171
- }
172
- // 模块结构
173
- if (allTargets.length > 0) {
174
- lines.push(`### 模块结构`, '');
175
- lines.push(`项目包含 **${allTargets.length}** 个模块/Target:`, '');
176
- for (const t of allTargets.slice(0, 15)) {
177
- const tName = t;
178
- const fileCount = Array.isArray(allFiles)
179
- ? allFiles.filter((f) => f.targetName === tName).length
180
- : 0;
181
- lines.push(`- \`${tName}\` (${fileCount} files)`);
182
- }
183
- if (allTargets.length > 15) {
184
- lines.push(`- ...及 ${allTargets.length - 15} 个其他模块`);
185
- }
186
- lines.push('');
187
- }
188
- // 依赖关系
189
- if (depGraphData && depGraphData.edges.length > 0) {
190
- lines.push('### 依赖关系', '');
191
- lines.push(`共 ${depGraphData.edges.length} 条模块间依赖关系。`, '');
192
- }
193
- // AST 统计
194
- if (astProjectSummary) {
195
- lines.push('### 代码结构统计', '');
196
- const m = astProjectSummary.projectMetrics || {};
197
- lines.push(`- 类/结构体: ${astProjectSummary.classes?.length || 0}`);
198
- lines.push(`- 协议/接口: ${astProjectSummary.protocols?.length || 0}`);
199
- lines.push(`- 方法总数: ${m.totalMethods || 0}`);
200
- if (m.maxNestingDepth) {
201
- lines.push(`- 最大嵌套深度: ${m.maxNestingDepth}`);
202
- }
203
- if (m.complexMethods && m.complexMethods.length > 0) {
204
- lines.push(`- 高复杂度方法: ${m.complexMethods.length}`);
205
- }
206
- if (m.longMethods && m.longMethods.length > 0) {
207
- lines.push(`- 过长方法 (>50 行): ${m.longMethods.length}`);
208
- }
209
- lines.push('');
210
- }
211
- // 生成 coreCode (P3): 技术栈摘要
212
- const codeParts = [];
213
- if (sortedLangs.length > 0) {
214
- codeParts.push('// 语言分布');
215
- for (const [lang, count] of sortedLangs.slice(0, 5)) {
216
- codeParts.push(`// ${lang}: ${count} files`);
217
- }
218
- }
219
- if (astProjectSummary) {
220
- codeParts.push(`// 类: ${astProjectSummary.classes?.length || 0}, 协议: ${astProjectSummary.protocols?.length || 0}, 方法: ${astProjectSummary.projectMetrics?.totalMethods || 0}`);
221
- }
222
- if (allTargets.length > 0) {
223
- codeParts.push(`// Target: ${allTargets
224
- .slice(0, 8)
225
- .map((t) => t)
226
- .join(', ')}`);
227
- }
228
- const markdown = lines.join('\n');
229
- if (markdown.length < 50) {
230
- return null;
231
- }
232
- return _makeCandidate({
233
- title: `项目技术画像 — ${primaryLang}`,
234
- knowledgeType: 'architecture',
235
- category: 'Architecture',
236
- language: primaryLang,
237
- markdown,
238
- rationale: '基于 Bootstrap 扫描的文件统计、AST 分析和依赖图谱自动生成',
239
- coreCode: codeParts.join('\n'),
240
- trigger: '项目技术画像',
241
- doClause: '了解项目技术栈和模块结构后再开始编码',
242
- dontClause: '',
243
- whenClause: '初次接触项目或需要了解全局架构时',
244
- sources: ['bootstrap-scan'],
245
- });
246
- }
247
- function _buildArchitecture({ depGraphData, allTargets, targetFileMap, primaryLang, astProjectSummary, }) {
248
- if (!(depGraphData && depGraphData.edges.length) && allTargets.length < 2) {
249
- return null;
250
- }
251
- const lines = ['## 模块架构', ''];
252
- // 依赖图
253
- if (depGraphData && depGraphData.edges.length > 0) {
254
- lines.push('### 模块依赖关系', '');
255
- lines.push('```');
256
- const seen = new Set();
257
- for (const e of depGraphData.edges.slice(0, 30)) {
258
- const from = typeof e.from === 'string' ? e.from : e.source;
259
- const to = typeof e.to === 'string' ? e.to : e.target;
260
- if (from && to) {
261
- const key = `${from} → ${to}`;
262
- if (!seen.has(key)) {
263
- lines.push(key);
264
- seen.add(key);
265
- }
266
- }
267
- }
268
- lines.push('```');
269
- lines.push('');
270
- // 入度/出度分析
271
- const inDeg = {};
272
- const outDeg = {};
273
- for (const e of depGraphData.edges) {
274
- const from = typeof e.from === 'string' ? e.from : e.source;
275
- const to = typeof e.to === 'string' ? e.to : e.target;
276
- if (from) {
277
- outDeg[from] = (outDeg[from] || 0) + 1;
278
- }
279
- if (to) {
280
- inDeg[to] = (inDeg[to] || 0) + 1;
281
- }
282
- }
283
- // 核心模块(被依赖最多)
284
- const coreModules = Object.entries(inDeg)
285
- .sort(([, a], [, b]) => b - a)
286
- .slice(0, 5);
287
- if (coreModules.length > 0) {
288
- lines.push('### 核心模块(被依赖最多)', '');
289
- for (const [mod, deg] of coreModules) {
290
- lines.push(`- \`${mod}\` — 被 ${deg} 个模块依赖`);
291
- }
292
- lines.push('');
293
- }
294
- // 叶子模块(不被任何模块依赖)
295
- const leafModules = allTargets.filter((t) => !inDeg[t] && outDeg[t]);
296
- if (leafModules.length > 0) {
297
- lines.push('### 叶子模块(仅依赖他人)', '');
298
- for (const mod of leafModules.slice(0, 8)) {
299
- lines.push(`- \`${mod}\``);
300
- }
301
- lines.push('');
302
- }
303
- }
304
- // P5: ObjC Category 信息
305
- const categories = astProjectSummary?.categories || [];
306
- if (categories.length > 0) {
307
- lines.push('### ObjC Category 扩展', '');
308
- // 按基类分组
309
- const byBase = {};
310
- for (const cat of categories) {
311
- const base = cat.className || cat.baseClass || cat.name?.split('(')[0] || 'Unknown';
312
- if (!byBase[base]) {
313
- byBase[base] = [];
314
- }
315
- byBase[base].push(cat);
316
- }
317
- const sortedBases = Object.entries(byBase).sort(([, a], [, b]) => b.length - a.length);
318
- lines.push(`共 **${categories.length}** 个 Category,分布在 **${sortedBases.length}** 个基类上:`, '');
319
- for (const [base, cats] of sortedBases.slice(0, 10)) {
320
- const catNames = cats
321
- .map((c) => c.categoryName || c.name || '')
322
- .filter(Boolean)
323
- .slice(0, 5)
324
- .join(', ');
325
- const loc = cats[0]?.file ? ` (来源: ${_basename(cats[0].file)})` : '';
326
- lines.push(`- \`${base}\` — ${cats.length} 个 Category${catNames ? `: ${catNames}` : ''}${loc}`);
327
- }
328
- if (sortedBases.length > 10) {
329
- lines.push(`- ...及 ${sortedBases.length - 10} 个其他基类`);
330
- }
331
- lines.push('');
332
- }
333
- // 生成代码块 (P3)
334
- const codeLines = [];
335
- if (depGraphData && depGraphData.edges.length > 0) {
336
- codeLines.push(`// 模块依赖关系 (共 ${depGraphData.edges.length} 条)`);
337
- const seen = new Set();
338
- for (const e of depGraphData.edges.slice(0, 15)) {
339
- const from = typeof e.from === 'string' ? e.from : e.source;
340
- const to = typeof e.to === 'string' ? e.to : e.target;
341
- if (from && to) {
342
- const key = `${from} -> ${to}`;
343
- if (!seen.has(key)) {
344
- codeLines.push(key);
345
- seen.add(key);
346
- }
347
- }
348
- }
349
- }
350
- const markdown = lines.join('\n');
351
- if (markdown.length < 80) {
352
- return null;
353
- }
354
- return _makeCandidate({
355
- title: '模块架构与依赖关系',
356
- knowledgeType: 'architecture',
357
- category: 'Architecture',
358
- language: primaryLang,
359
- markdown,
360
- rationale: '基于项目依赖图谱和模块扫描自动生成',
361
- coreCode: codeLines.length > 1 ? codeLines.join('\n') : '',
362
- trigger: '模块架构',
363
- doClause: '遵循现有模块边界,新功能放入对应模块',
364
- dontClause: '',
365
- whenClause: '新建文件或模块时',
366
- sources: ['bootstrap-scan'],
367
- });
368
- }
369
- function _buildCodeStandard({ astProjectSummary, primaryLang, allFiles, }) {
370
- if (!astProjectSummary) {
371
- return null;
372
- }
373
- const lines = ['## 代码规范发现', ''];
374
- const classes = astProjectSummary.classes || [];
375
- const methods = [];
376
- // 从 file 级聚合方法
377
- if (astProjectSummary.files) {
378
- for (const f of astProjectSummary.files) {
379
- if (f.methods) {
380
- methods.push(...f.methods);
381
- }
382
- }
383
- }
384
- // 命名模式分析
385
- let usedSuffixes = [];
386
- if (classes.length > 0) {
387
- lines.push('### 类命名模式', '');
388
- // 检测常见后缀
389
- const suffixCounts = {};
390
- const COMMON_SUFFIXES = [
391
- 'Service',
392
- 'Manager',
393
- 'Controller',
394
- 'Handler',
395
- 'Provider',
396
- 'Repository',
397
- 'Factory',
398
- 'Helper',
399
- 'Utils',
400
- 'ViewModel',
401
- 'View',
402
- 'Model',
403
- 'Store',
404
- 'Client',
405
- 'Adapter',
406
- 'Impl',
407
- ];
408
- for (const cls of classes) {
409
- for (const sfx of COMMON_SUFFIXES) {
410
- if (cls.name?.endsWith(sfx)) {
411
- suffixCounts[sfx] = (suffixCounts[sfx] || 0) + 1;
412
- }
413
- }
414
- }
415
- usedSuffixes = Object.entries(suffixCounts)
416
- .filter(([, c]) => c > 0)
417
- .sort(([, a], [, b]) => b - a);
418
- if (usedSuffixes.length > 0) {
419
- lines.push('| 后缀约定 | 类数量 | 推断角色 |');
420
- lines.push('|----------|--------|----------|');
421
- const roleMap = {
422
- Service: '业务服务',
423
- Manager: '管理器',
424
- Controller: '控制器/路由',
425
- Handler: '事件/请求处理',
426
- Provider: '数据/功能提供者',
427
- Repository: '数据访问',
428
- Factory: '工厂',
429
- Helper: '辅助工具',
430
- Utils: '工具类',
431
- ViewModel: '视图模型',
432
- View: '视图/UI',
433
- Model: '数据模型',
434
- Store: '状态存储',
435
- Client: 'API 客户端',
436
- Adapter: '适配器',
437
- Impl: '接口实现',
438
- };
439
- for (const [sfx, count] of usedSuffixes) {
440
- lines.push(`| *${sfx} | ${count} | ${roleMap[sfx] || sfx} |`);
441
- }
442
- lines.push('');
443
- }
444
- lines.push(`共发现 **${classes.length}** 个类/结构体。`, '');
445
- }
446
- // 代码质量指标
447
- const metrics = astProjectSummary.projectMetrics;
448
- if (metrics) {
449
- lines.push('### 代码质量指标', '');
450
- if (metrics.avgMethodsPerClass) {
451
- lines.push(`- 平均方法数/类: ${metrics.avgMethodsPerClass.toFixed(1)}`);
452
- }
453
- if (metrics.complexMethods && metrics.complexMethods.length > 0) {
454
- lines.push(`- 高圈复杂度方法: ${metrics.complexMethods.length} 个`);
455
- for (const m of metrics.complexMethods.slice(0, 5)) {
456
- const loc = m.file ? ` (来源: ${_basename(m.file)}${m.line ? `:${m.line}` : ''})` : '';
457
- lines.push(` - \`${m.className ? `${m.className}.` : ''}${m.name}\` — complexity ${m.complexity}${loc}`);
458
- }
459
- }
460
- if (metrics.longMethods && metrics.longMethods.length > 0) {
461
- lines.push(`- 过长方法: ${metrics.longMethods.length} 个`);
462
- for (const m of metrics.longMethods.slice(0, 5)) {
463
- const bodyLen = m.lines || m.bodyLines || '?';
464
- const loc = m.file ? ` (来源: ${_basename(m.file)}${m.line ? `:${m.line}` : ''})` : '';
465
- lines.push(` - \`${m.className ? `${m.className}.` : ''}${m.name}\` — ${bodyLen} 行${loc}`);
466
- }
467
- }
468
- lines.push('');
469
- }
470
- // 收集源文件引用 (P4)
471
- const sourceFiles = new Set();
472
- if (metrics) {
473
- for (const m of (metrics.longMethods || []).concat(metrics.complexMethods || [])) {
474
- if (m.file) {
475
- sourceFiles.add(m.file);
476
- }
477
- }
478
- }
479
- // 生成 coreCode (P3): 命名规范摘要
480
- const codeLines = [];
481
- if (usedSuffixes?.length > 0) {
482
- codeLines.push('// 命名约定示例');
483
- for (const [sfx, count] of usedSuffixes.slice(0, 6)) {
484
- codeLines.push(`// *${sfx} → ${count} 个类使用此后缀`);
485
- }
486
- }
487
- if (metrics && metrics.longMethods && metrics.longMethods.length > 0) {
488
- codeLines.push('');
489
- codeLines.push('// 过长方法示例 (应重构)');
490
- for (const m of metrics.longMethods.slice(0, 3)) {
491
- const bodyLen = m.lines || m.bodyLines || '?';
492
- codeLines.push(`// ${m.className ? `${m.className}.` : ''}${m.name} — ${bodyLen} 行`);
493
- }
494
- }
495
- const markdown = lines.join('\n');
496
- if (markdown.length < 80) {
497
- return null;
498
- }
499
- return _makeCandidate({
500
- title: '代码规范与命名约定',
501
- knowledgeType: 'code-standard',
502
- category: 'Architecture',
503
- language: primaryLang,
504
- markdown,
505
- rationale: '基于 AST 分析的类名、方法统计和代码复杂度指标自动生成',
506
- coreCode: codeLines.join('\n'),
507
- trigger: '代码规范',
508
- doClause: '遵循项目现有命名约定,新类名使用已有后缀模式',
509
- dontClause: '不要写超过 50 行的方法,不要超过 4 层嵌套',
510
- whenClause: '新建类或方法时',
511
- sources: sourceFiles.size > 0 ? [...sourceFiles].slice(0, 10) : ['bootstrap-scan'],
512
- });
513
- }
514
- function _buildBestPractice({ guardAudit, primaryLang, }) {
515
- if (!guardAudit?.files?.length) {
516
- return null;
517
- }
518
- // 聚合所有违规
519
- const ruleStats = {};
520
- for (const f of guardAudit.files) {
521
- for (const v of f.violations || []) {
522
- if (!ruleStats[v.ruleId]) {
523
- ruleStats[v.ruleId] = {
524
- count: 0,
525
- severity: v.severity,
526
- message: v.message,
527
- files: new Set(),
528
- fixSuggestion: v.fixSuggestion || null,
529
- };
530
- }
531
- ruleStats[v.ruleId].count++;
532
- ruleStats[v.ruleId].files.add(f.filePath);
533
- }
534
- }
535
- const sortedRules = Object.entries(ruleStats).sort(([, a], [, b]) => b.count - a.count);
536
- if (sortedRules.length === 0) {
537
- return null;
538
- }
539
- const lines = ['## 最佳实践(基于 Guard 审计)', ''];
540
- lines.push(`Bootstrap 扫描发现 **${guardAudit.summary?.totalViolations || 0}** 个违规,` +
541
- `涉及 **${sortedRules.length}** 条规则:`, '');
542
- lines.push('### 高频违规(应优先修复)', '');
543
- lines.push('| 规则 | 严重性 | 违规数 | 影响文件数 | 说明 |');
544
- lines.push('|------|--------|--------|-----------|------|');
545
- for (const [ruleId, stat] of sortedRules.slice(0, 15)) {
546
- lines.push(`| \`${ruleId}\` | ${stat.severity} | ${stat.count} | ${stat.files.size} | ${stat.message} |`);
547
- }
548
- lines.push('');
549
- // 修复建议
550
- const withFix = sortedRules.filter(([, s]) => s.fixSuggestion);
551
- if (withFix.length > 0) {
552
- lines.push('### 修复建议', '');
553
- for (const [ruleId, stat] of withFix.slice(0, 10)) {
554
- lines.push(`- **${ruleId}**: ${stat.fixSuggestion}`);
555
- }
556
- lines.push('');
557
- }
558
- // 收集违规文件路径 (P4)
559
- const violationFiles = new Set();
560
- for (const f of guardAudit.files) {
561
- if (f.violations?.length > 0 && f.filePath) {
562
- violationFiles.add(f.filePath);
563
- }
564
- }
565
- // 生成 coreCode (P3): Guard 规则摘要
566
- const codeLines = ['// Guard 高频违规规则'];
567
- for (const [ruleId, stat] of sortedRules.slice(0, 5)) {
568
- codeLines.push(`// ${ruleId}: ${stat.message} (${stat.count}次)`);
569
- }
570
- const markdown = lines.join('\n');
571
- return _makeCandidate({
572
- title: '最佳实践与常见问题',
573
- knowledgeType: 'best-practice',
574
- category: 'Service',
575
- language: primaryLang,
576
- markdown,
577
- rationale: '基于 Guard 静态审计发现的违规模式和修复建议自动生成',
578
- coreCode: codeLines.join('\n'),
579
- trigger: 'Guard 审计结果',
580
- doClause: '修复 Guard 标记的违规,特别是 error 级别',
581
- dontClause: '不要忽略 Guard 警告,不要引入已知反模式',
582
- whenClause: '修改现有代码或新建文件时',
583
- sources: violationFiles.size > 0 ? [...violationFiles].slice(0, 10) : ['bootstrap-scan'],
584
- });
585
- }
586
- function _buildAgentGuidelines({ guardAudit, primaryLang, astProjectSummary, }) {
587
- const lines = ['## Agent 开发注意事项', ''];
588
- lines.push('> 以下规则基于项目静态分析自动生成,AI Agent 在本项目中编写代码时应遵守。', '');
589
- // 从 Guard 高频违规推断
590
- if (guardAudit?.files?.length) {
591
- const ruleStats = {};
592
- for (const f of guardAudit.files) {
593
- for (const v of f.violations || []) {
594
- ruleStats[v.ruleId] = ruleStats[v.ruleId] || {
595
- count: 0,
596
- message: v.message,
597
- severity: v.severity,
598
- };
599
- ruleStats[v.ruleId].count++;
600
- }
601
- }
602
- const topErrors = Object.entries(ruleStats)
603
- .filter(([, s]) => s.severity === 'error')
604
- .sort(([, a], [, b]) => b.count - a.count)
605
- .slice(0, 8);
606
- const topWarnings = Object.entries(ruleStats)
607
- .filter(([, s]) => s.severity === 'warning')
608
- .sort(([, a], [, b]) => b.count - a.count)
609
- .slice(0, 8);
610
- if (topErrors.length > 0) {
611
- lines.push('### 必须(must)- 基于 error 级违规', '');
612
- for (const [ruleId, stat] of topErrors) {
613
- lines.push(`- ❌ **${ruleId}**: ${stat.message} (项目中出现 ${stat.count} 次)`);
614
- }
615
- lines.push('');
616
- }
617
- if (topWarnings.length > 0) {
618
- lines.push('### 建议(should)- 基于 warning 级违规', '');
619
- for (const [ruleId, stat] of topWarnings) {
620
- lines.push(`- ⚠️ **${ruleId}**: ${stat.message} (${stat.count} 处)`);
621
- }
622
- lines.push('');
623
- }
624
- }
625
- // 从 AST 复杂度推断
626
- if (astProjectSummary?.projectMetrics) {
627
- const m = astProjectSummary.projectMetrics;
628
- lines.push('### 代码质量约束', '');
629
- if (m.maxNestingDepth != null && m.maxNestingDepth >= 5) {
630
- lines.push(`- 当前项目最大嵌套深度 ${m.maxNestingDepth} — 新代码应避免超过 4 层嵌套`);
631
- }
632
- if (m.complexMethods && m.complexMethods.length > 0) {
633
- const avgComplexity = m.complexMethods.reduce((s, c) => s + (c.complexity ?? 0), 0) /
634
- m.complexMethods.length;
635
- lines.push(`- 已有 ${m.complexMethods.length} 个高复杂度方法 (avg ${avgComplexity.toFixed(1)}) — 新方法圈复杂度应 <10`);
636
- }
637
- if (m.longMethods && m.longMethods.length > 0) {
638
- lines.push(`- 已有 ${m.longMethods.length} 个过长方法 — 新方法建议 <50 行`);
639
- }
640
- lines.push('');
641
- }
642
- const markdown = lines.join('\n');
643
- if (markdown.length < 100) {
644
- return null;
645
- }
646
- // 生成 coreCode (P3)
647
- const codeLines = ['// Agent 强制规则'];
648
- if (astProjectSummary?.projectMetrics &&
649
- (astProjectSummary.projectMetrics.maxNestingDepth ?? 0) >= 5) {
650
- codeLines.push(`// 最大嵌套: ${astProjectSummary.projectMetrics.maxNestingDepth} → 新代码应 <4`);
651
- }
652
- if (astProjectSummary?.projectMetrics?.longMethods &&
653
- astProjectSummary.projectMetrics.longMethods.length > 0) {
654
- codeLines.push(`// 过长方法: ${astProjectSummary.projectMetrics.longMethods.length} 个 → 新方法应 <50行`);
655
- }
656
- return _makeCandidate({
657
- title: 'Agent 开发注意事项',
658
- knowledgeType: 'boundary-constraint',
659
- category: 'Architecture',
660
- language: primaryLang,
661
- markdown,
662
- rationale: '基于 Guard 错误级违规和 AST 复杂度指标自动生成的 Agent 约束',
663
- coreCode: codeLines.join('\n'),
664
- trigger: 'Agent 开发规范',
665
- doClause: '新代码嵌套不超过 4 层,方法不超过 50 行,圈复杂度 <10',
666
- dontClause: '不要引入 Guard 已标记的反模式',
667
- whenClause: '在本项目中编写任何代码时',
668
- sources: ['bootstrap-scan'],
669
- });
670
- }
671
- // ═══════════════════════════════════════════════════════════
672
- // 工具函数
673
- // ═══════════════════════════════════════════════════════════
674
- /** 从绝对/相对路径取文件名 */
675
- function _basename(fp) {
676
- if (!fp) {
677
- return '';
678
- }
679
- const idx = fp.lastIndexOf('/');
680
- return idx >= 0 ? fp.slice(idx + 1) : fp;
681
- }
682
- function _makeCandidate({ title, knowledgeType, category, language, markdown, rationale, coreCode, trigger, doClause, dontClause, whenClause, sources, }) {
683
- return {
684
- title,
685
- content: { pattern: coreCode || '', markdown, rationale },
686
- language: language || '',
687
- category,
688
- knowledgeType,
689
- source: 'bootstrap-fallback',
690
- difficulty: 'beginner',
691
- scope: 'project-specific',
692
- trigger: trigger || title,
693
- doClause: doClause || '',
694
- dontClause: dontClause || '',
695
- whenClause: whenClause || '',
696
- coreCode: coreCode || '',
697
- reasoning: {
698
- whyStandard: rationale,
699
- sources: sources || ['bootstrap-scan'],
700
- confidence: 0.6,
701
- },
702
- };
703
- }
704
- function _wrapAsSkill(dimId, label, markdown) {
705
- return {
706
- dimId,
707
- name: `project-${dimId}`,
708
- description: `Auto-generated from bootstrap scan (no-AI fallback): ${label}`,
709
- content: [
710
- `# ${label}`,
711
- '',
712
- '> Auto-generated by Bootstrap fallback (rule-based, no AI). Quality: basic.',
713
- '',
714
- markdown,
715
- ].join('\n'),
716
- };
717
- }
718
- function _markDimDone(taskManager, sessionId, dimId, type) {
719
- try {
720
- if (taskManager && sessionId) {
721
- taskManager.markTaskCompleted(dimId, { type, reason: type });
722
- }
723
- }
724
- catch {
725
- /* non-critical */
726
- }
727
- }