autosnippet 3.3.6 → 3.3.8

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 (275) hide show
  1. package/README.md +1 -0
  2. package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
  3. package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
  4. package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
  5. package/dashboard/dist/index.html +3 -3
  6. package/dist/bin/cli.js +8 -4
  7. package/dist/lib/agent/AgentRuntime.d.ts +2 -2
  8. package/dist/lib/agent/AgentRuntime.js +26 -18
  9. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  10. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  11. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  12. package/dist/lib/agent/domain/ChatAgentTasks.js +4 -0
  13. package/dist/lib/agent/forced-summary.js +7 -2
  14. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  15. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  16. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  17. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  18. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  19. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  20. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  21. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  22. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  23. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  24. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  25. package/dist/lib/agent/memory/SessionStore.js +0 -2
  26. package/dist/lib/agent/tools/ast-graph.js +21 -19
  27. package/dist/lib/agent/tools/infrastructure.js +3 -2
  28. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  29. package/dist/lib/agent/tools/project-access.js +5 -4
  30. package/dist/lib/bootstrap.js +2 -1
  31. package/dist/lib/cli/AiScanService.js +8 -21
  32. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  33. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  34. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  35. package/dist/lib/core/discovery/ConfigWatcher.d.ts +64 -0
  36. package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
  37. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +28 -0
  38. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1303 -0
  39. package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
  40. package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
  41. package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
  42. package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
  43. package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
  44. package/dist/lib/core/discovery/index.d.ts +2 -0
  45. package/dist/lib/core/discovery/index.js +4 -0
  46. package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
  47. package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
  48. package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
  49. package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
  50. package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
  51. package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
  52. package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
  53. package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
  54. package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
  55. package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
  56. package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
  57. package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
  58. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  59. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  60. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  61. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  62. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  63. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +7 -1
  64. package/dist/lib/domain/knowledge/KnowledgeEntry.js +17 -3
  65. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  66. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  67. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  68. package/dist/lib/domain/knowledge/index.js +1 -1
  69. package/dist/lib/external/ai/AiProvider.d.ts +12 -0
  70. package/dist/lib/external/ai/AiProvider.js +24 -0
  71. package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
  72. package/dist/lib/external/ai/AiProviderManager.js +193 -0
  73. package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
  74. package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
  75. package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
  76. package/dist/lib/external/ai/providers/MockProvider.js +290 -14
  77. package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
  78. package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
  79. package/dist/lib/external/lark/LarkTransport.js +10 -2
  80. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  81. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  82. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.d.ts +20 -0
  83. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
  84. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -24
  85. package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
  86. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  87. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  88. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +9 -0
  89. package/dist/lib/external/mcp/handlers/bootstrap-external.js +3 -1
  90. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
  91. package/dist/lib/external/mcp/handlers/consolidated.js +2 -1
  92. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +9 -4
  93. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  94. package/dist/lib/external/mcp/handlers/evolve-external.js +18 -18
  95. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  96. package/dist/lib/external/mcp/handlers/knowledge.js +5 -4
  97. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  98. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  99. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  100. package/dist/lib/external/mcp/handlers/search.js +3 -1
  101. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  102. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  103. package/dist/lib/external/mcp/handlers/system.js +10 -34
  104. package/dist/lib/http/routes/ai.js +109 -30
  105. package/dist/lib/http/routes/candidates.js +11 -4
  106. package/dist/lib/http/routes/commands.js +10 -1
  107. package/dist/lib/http/routes/guardReport.js +3 -5
  108. package/dist/lib/http/routes/health.js +11 -0
  109. package/dist/lib/http/routes/modules.js +27 -0
  110. package/dist/lib/http/routes/panorama.js +12 -12
  111. package/dist/lib/http/routes/recipes.js +66 -8
  112. package/dist/lib/http/routes/remote.js +3 -13
  113. package/dist/lib/http/routes/search.js +11 -8
  114. package/dist/lib/http/utils/routeHelpers.js +2 -1
  115. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  116. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  117. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  118. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  119. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  120. package/dist/lib/injection/ServiceContainer.d.ts +6 -5
  121. package/dist/lib/injection/ServiceContainer.js +18 -31
  122. package/dist/lib/injection/ServiceMap.d.ts +22 -0
  123. package/dist/lib/injection/modules/AiModule.d.ts +6 -9
  124. package/dist/lib/injection/modules/AiModule.js +82 -39
  125. package/dist/lib/injection/modules/AppModule.js +2 -1
  126. package/dist/lib/injection/modules/GuardModule.js +5 -5
  127. package/dist/lib/injection/modules/InfraModule.js +60 -0
  128. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  129. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  130. package/dist/lib/injection/modules/VectorModule.js +3 -0
  131. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  132. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  133. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  134. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  135. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  136. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  137. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  138. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  139. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  140. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  141. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  142. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  143. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  144. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  145. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  146. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  147. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  148. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  149. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  150. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  151. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  152. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  153. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  154. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  155. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  156. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  157. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  158. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  159. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  160. package/dist/lib/repository/session/SessionRepository.js +110 -0
  161. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  162. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  163. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  164. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  165. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  166. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  167. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  168. package/dist/lib/service/cleanup/CleanupService.d.ts +54 -7
  169. package/dist/lib/service/cleanup/CleanupService.js +291 -40
  170. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
  171. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  172. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  173. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  174. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  175. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  176. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  177. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  178. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  179. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  180. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  181. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  182. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  183. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  184. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  185. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  186. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  187. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  188. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  189. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  190. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  191. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  192. package/dist/lib/service/evolution/StagingManager.js +37 -95
  193. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  194. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  195. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  196. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  197. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  198. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  199. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  200. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  201. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  202. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  203. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +45 -63
  204. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -496
  205. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  206. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  207. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  208. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  209. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  210. package/dist/lib/service/knowledge/KnowledgeService.js +97 -46
  211. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  212. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  213. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  214. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  215. package/dist/lib/service/module/ModuleService.js +10 -19
  216. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +14 -3
  217. package/dist/lib/service/panorama/CouplingAnalyzer.js +137 -32
  218. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  219. package/dist/lib/service/panorama/DimensionAnalyzer.js +94 -33
  220. package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
  221. package/dist/lib/service/panorama/LayerInferrer.js +118 -1
  222. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +14 -4
  223. package/dist/lib/service/panorama/ModuleDiscoverer.js +209 -61
  224. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +15 -4
  225. package/dist/lib/service/panorama/PanoramaAggregator.js +128 -62
  226. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  227. package/dist/lib/service/panorama/PanoramaScanner.js +60 -31
  228. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  229. package/dist/lib/service/panorama/PanoramaService.js +49 -69
  230. package/dist/lib/service/panorama/PanoramaTypes.d.ts +41 -0
  231. package/dist/lib/service/panorama/RoleRefiner.d.ts +10 -5
  232. package/dist/lib/service/panorama/RoleRefiner.js +92 -282
  233. package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
  234. package/dist/lib/service/panorama/TechStackProfiler.js +79 -0
  235. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  236. package/dist/lib/service/quality/QualityScorer.js +157 -83
  237. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  238. package/dist/lib/service/search/SearchEngine.js +32 -37
  239. package/dist/lib/service/signal/HitRecorder.js +5 -5
  240. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  241. package/dist/lib/service/skills/SignalCollector.d.ts +6 -8
  242. package/dist/lib/service/skills/SignalCollector.js +34 -60
  243. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  244. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  245. package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
  246. package/dist/lib/service/vector/ContextualEnricher.js +4 -0
  247. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  248. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  249. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  250. package/dist/lib/service/vector/VectorService.js +3 -0
  251. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  252. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  253. package/dist/lib/shared/LanguageProfiles.js +939 -0
  254. package/dist/lib/shared/LanguageService.d.ts +6 -0
  255. package/dist/lib/shared/LanguageService.js +19 -0
  256. package/dist/lib/shared/constants.d.ts +19 -19
  257. package/dist/lib/shared/constants.js +10 -10
  258. package/dist/lib/shared/developer-identity.d.ts +18 -0
  259. package/dist/lib/shared/developer-identity.js +62 -0
  260. package/dist/lib/shared/schemas/http-requests.d.ts +8 -17
  261. package/dist/lib/shared/schemas/http-requests.js +9 -6
  262. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  263. package/dist/lib/types/knowledge-wire.d.ts +1 -0
  264. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  265. package/dist/lib/types/project-snapshot-builder.js +0 -1
  266. package/dist/lib/types/project-snapshot.d.ts +0 -1
  267. package/dist/lib/types/project-snapshot.js +0 -1
  268. package/dist/lib/types/snapshot-views.d.ts +0 -2
  269. package/dist/lib/types/snapshot-views.js +0 -1
  270. package/package.json +2 -1
  271. package/dashboard/dist/assets/icons-D1aVZYFW.js +0 -1
  272. package/dashboard/dist/assets/index-CxHOu8Hd.css +0 -1
  273. package/dashboard/dist/assets/index-DDdAOpYT.js +0 -128
  274. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  275. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -0,0 +1,432 @@
1
+ /**
2
+ * mock-pipeline.ts — Mock AI Bootstrap 轻量管线
3
+ *
4
+ * 当 AI Provider 为 mock 时,利用 Phase 1-4 已收集的真实数据
5
+ * (AST、依赖图、文件列表、Panorama) 为每个维度生成模板化候选知识。
6
+ *
7
+ * 不调用 AI,但走完完整的 submit → dimension_complete 流程,
8
+ * 使 Dashboard 能正常展示知识库、健康雷达等 UI。
9
+ *
10
+ * @module pipeline/mock-pipeline
11
+ */
12
+ import path from 'node:path';
13
+ import Logger from '#infra/logging/Logger.js';
14
+ import { BootstrapEventEmitter } from '#service/bootstrap/BootstrapEventEmitter.js';
15
+ const logger = Logger.getInstance();
16
+ // ── 模板生成器 ────────────────────────────────────────────
17
+ /** 从 AST 指标提取代码统计 */
18
+ function extractAstStats(ast) {
19
+ if (!ast) {
20
+ return { classes: 0, protocols: 0, functions: 0 };
21
+ }
22
+ const pm = (ast.projectMetrics ?? ast);
23
+ return {
24
+ classes: pm.totalClasses ?? 0,
25
+ protocols: pm.totalProtocols ?? 0,
26
+ functions: pm.totalFunctions ?? 0,
27
+ };
28
+ }
29
+ /** 从文件列表中按 target 分组并提取代表性文件 */
30
+ function getRepresentativeFiles(files, targetFileMap) {
31
+ const result = new Map();
32
+ if (targetFileMap) {
33
+ for (const [target, paths] of Object.entries(targetFileMap)) {
34
+ result.set(target, paths.slice(0, 5));
35
+ }
36
+ }
37
+ else if (files) {
38
+ const grouped = new Map();
39
+ for (const f of files) {
40
+ const target = f.targetName || 'default';
41
+ const list = grouped.get(target) || [];
42
+ list.push(f.relativePath || f.name);
43
+ grouped.set(target, list);
44
+ }
45
+ for (const [target, paths] of grouped) {
46
+ result.set(target, paths.slice(0, 5));
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+ /** 从文件内容中提取 import 语句(作为 headers)*/
52
+ function extractImports(content, lang) {
53
+ const imports = [];
54
+ const lines = content.split('\n').slice(0, 30);
55
+ for (const line of lines) {
56
+ const trimmed = line.trim();
57
+ if (lang === 'swift' && trimmed.startsWith('import ')) {
58
+ imports.push(trimmed);
59
+ }
60
+ else if ((lang === 'typescript' || lang === 'javascript') && trimmed.startsWith('import ')) {
61
+ imports.push(trimmed);
62
+ }
63
+ }
64
+ return [...new Set(imports)].slice(0, 5);
65
+ }
66
+ /** 从文件内容中提取类/结构体/协议名 */
67
+ function extractTypes(content) {
68
+ const types = [];
69
+ for (const m of content.matchAll(/(?:class|struct|protocol|enum|interface|type)\s+(\w+)/g)) {
70
+ types.push(m[1]);
71
+ }
72
+ return [...new Set(types)].slice(0, 10);
73
+ }
74
+ /** 生成 kebab-case trigger */
75
+ function toKebab(text) {
76
+ return text
77
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
78
+ .replace(/[\s_]+/g, '-')
79
+ .toLowerCase()
80
+ .replace(/[^a-z0-9-]/g, '')
81
+ .slice(0, 40);
82
+ }
83
+ // ── 维度级候选生成 ────────────────────────────────────────
84
+ /** 为单个维度生成 Mock 候选 */
85
+ function generateDimensionCandidates(dimId, dimLabel, files, lang, projectName, astStats, targetFiles) {
86
+ const candidates = [];
87
+ // 从文件中收集有代表性的类型和源文件
88
+ const allTypes = [];
89
+ const allSources = [];
90
+ const allImports = [];
91
+ const dimFiles = files?.filter((f) => {
92
+ const p = f.relativePath?.toLowerCase() || f.name.toLowerCase();
93
+ // 根据维度 ID 做简单相关性匹配
94
+ switch (dimId) {
95
+ case 'architecture':
96
+ return (p.includes('coordinator') ||
97
+ p.includes('delegate') ||
98
+ p.includes('service') ||
99
+ p.includes('manager'));
100
+ case 'code-pattern':
101
+ return p.includes('extension') || p.includes('helper') || p.includes('util');
102
+ case 'naming-style':
103
+ return true; // 全局适用
104
+ case 'error-handling':
105
+ return p.includes('error') || p.includes('result') || p.includes('handler');
106
+ case 'networking':
107
+ return (p.includes('network') ||
108
+ p.includes('api') ||
109
+ p.includes('request') ||
110
+ p.includes('http'));
111
+ case 'data-model':
112
+ return p.includes('model') || p.includes('entity') || p.includes('dto');
113
+ case 'testing-quality':
114
+ return p.includes('test') || p.includes('spec') || p.includes('mock');
115
+ case 'ui-patterns':
116
+ return (p.includes('view') ||
117
+ p.includes('controller') ||
118
+ p.includes('cell') ||
119
+ p.includes('component'));
120
+ case 'concurrency':
121
+ return (p.includes('actor') ||
122
+ p.includes('async') ||
123
+ p.includes('queue') ||
124
+ p.includes('dispatch'));
125
+ case 'storage':
126
+ return (p.includes('store') ||
127
+ p.includes('cache') ||
128
+ p.includes('database') ||
129
+ p.includes('persist'));
130
+ default:
131
+ return true;
132
+ }
133
+ }) || [];
134
+ // 提取文件中的类型和导入
135
+ for (const f of dimFiles.slice(0, 10)) {
136
+ allTypes.push(...extractTypes(f.content || ''));
137
+ allSources.push(f.relativePath || f.name);
138
+ allImports.push(...extractImports(f.content || '', lang));
139
+ }
140
+ // 如果没找到相关文件,用全部文件兜底
141
+ if (allTypes.length === 0 && files) {
142
+ for (const f of files.slice(0, 5)) {
143
+ allTypes.push(...extractTypes(f.content || ''));
144
+ allSources.push(f.relativePath || f.name);
145
+ }
146
+ }
147
+ const uniqueTypes = [...new Set(allTypes)].slice(0, 8);
148
+ const uniqueSources = [...new Set(allSources)].slice(0, 5);
149
+ const uniqueImports = [...new Set(allImports)].slice(0, 5);
150
+ // 为每个维度生成 3 个候选
151
+ const templates = getDimensionTemplates(dimId, dimLabel, uniqueTypes, uniqueSources, lang, projectName, astStats);
152
+ for (const tpl of templates.slice(0, 3)) {
153
+ candidates.push({
154
+ ...tpl,
155
+ headers: uniqueImports,
156
+ sourceRefs: uniqueSources.slice(0, 3),
157
+ reasoning: {
158
+ whyStandard: `基于 ${projectName} 项目 ${dimFiles.length} 个相关文件的代码分析(Mock 模式自动生成)`,
159
+ sources: uniqueSources.slice(0, 3),
160
+ confidence: 0.7,
161
+ },
162
+ tags: ['mock-generated', dimId, lang],
163
+ });
164
+ }
165
+ return candidates;
166
+ }
167
+ /** 根据维度 ID 返回候选模板 */
168
+ function getDimensionTemplates(dimId, dimLabel, types, sources, lang, projectName, ast) {
169
+ const typeList = types.length > 0 ? types.slice(0, 3).join('、') : '核心模块';
170
+ const typeFirst = types[0] || 'AppModule';
171
+ const srcFirst = sources[0] || 'Sources/Main.swift';
172
+ const base = {
173
+ language: lang,
174
+ knowledgeType: dimId,
175
+ };
176
+ switch (dimId) {
177
+ case 'architecture':
178
+ return [
179
+ {
180
+ ...base,
181
+ title: `${projectName} 分层架构模式`,
182
+ description: `项目采用分层架构,包含 ${ast.classes} 个类、${ast.protocols} 个协议`,
183
+ trigger: `@${toKebab(projectName)}-layered-arch`,
184
+ kind: 'pattern',
185
+ category: 'Architecture',
186
+ topicHint: 'architecture',
187
+ content: {
188
+ markdown: `### ${projectName} 分层架构\n\n项目基于分层架构设计,核心类型包括 ${typeList}。\n\n**层次结构**:\n- 表现层: View/Controller\n- 业务层: Service/Manager\n- 数据层: Repository/Store\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ 此条目由 Mock AI 基于代码结构自动生成`,
189
+ rationale: `分层架构是 ${projectName} 的核心设计决策,确保模块间关注点分离`,
190
+ },
191
+ coreCode: `// ${lang === 'swift' ? 'protocol' : 'interface'} ${typeFirst}Service { ... }`,
192
+ doClause: `Follow the layered architecture with ${typeFirst} as the core service boundary`,
193
+ dontClause: 'Do not bypass service layer to access data layer directly',
194
+ whenClause: 'When adding new features or modules to the project',
195
+ usageGuide: `### 使用指南\n\n遵循 ${projectName} 的分层架构进行模块设计。`,
196
+ },
197
+ {
198
+ ...base,
199
+ title: `${typeFirst} 依赖注入约定`,
200
+ description: `${typeFirst} 等核心类型通过依赖注入管理生命周期`,
201
+ trigger: `@${toKebab(typeFirst)}-di-pattern`,
202
+ kind: 'pattern',
203
+ category: 'Architecture',
204
+ topicHint: 'architecture',
205
+ content: {
206
+ markdown: `### 依赖注入约定\n\n${projectName} 使用依赖注入管理 ${typeList} 等组件的生命周期。\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ Mock AI 自动生成`,
207
+ rationale: '依赖注入提高可测试性和模块解耦',
208
+ },
209
+ coreCode: `${lang === 'swift' ? `class ${typeFirst} {\n init(service: Service) { }\n}` : `class ${typeFirst} {\n constructor(private service: Service) {}\n}`}`,
210
+ doClause: `Use constructor injection for ${typeFirst} dependencies`,
211
+ dontClause: 'Do not use service locator or global singletons',
212
+ whenClause: `When creating or modifying ${typeFirst} and its dependencies`,
213
+ usageGuide: `### 使用指南\n\n通过构造器注入依赖项。`,
214
+ },
215
+ {
216
+ ...base,
217
+ title: `${projectName} 模块通信约定`,
218
+ description: `模块间通过协议/接口进行通信,避免直接耦合`,
219
+ trigger: `@${toKebab(projectName)}-module-comm`,
220
+ kind: 'rule',
221
+ category: 'Architecture',
222
+ topicHint: 'architecture',
223
+ content: {
224
+ markdown: `### 模块通信\n\n${projectName} 的模块通信遵循接口隔离原则,${ast.protocols} 个协议定义了清晰的边界。\n\n> ⚠️ Mock AI 自动生成`,
225
+ rationale: '接口隔离确保模块可独立演进和测试',
226
+ },
227
+ coreCode: `${lang === 'swift' ? `protocol ${typeFirst}Protocol {\n func execute() async\n}` : `interface I${typeFirst} {\n execute(): Promise<void>\n}`}`,
228
+ doClause: 'Define protocols/interfaces for all cross-module communication',
229
+ dontClause: 'Do not import concrete implementations across module boundaries',
230
+ whenClause: 'When modules need to communicate or share data',
231
+ usageGuide: `### 使用指南\n\n定义协议作为模块间通信契约。`,
232
+ },
233
+ ];
234
+ case 'code-pattern':
235
+ return [
236
+ {
237
+ ...base,
238
+ title: `${typeFirst} 扩展方法约定`,
239
+ description: `使用扩展方法为 ${typeFirst} 添加功能,保持核心类型精简`,
240
+ trigger: `@${toKebab(typeFirst)}-extension-pattern`,
241
+ kind: 'pattern',
242
+ category: 'Tool',
243
+ topicHint: 'conventions',
244
+ content: {
245
+ markdown: `### 扩展方法约定\n\n${projectName} 广泛使用扩展方法组织代码,${typeList} 等类型均采用此模式。\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ Mock AI 自动生成`,
246
+ rationale: '扩展方法使核心类型保持精简,增强可读性',
247
+ },
248
+ coreCode: `${lang === 'swift' ? `extension ${typeFirst} {\n func helper() { }\n}` : `// ${typeFirst}.extensions.ts`}`,
249
+ doClause: `Group related functionality in ${lang === 'swift' ? 'extensions' : 'utility modules'}`,
250
+ dontClause: 'Do not bloat core types with unrelated methods',
251
+ whenClause: `When adding utility or convenience methods to ${typeFirst}`,
252
+ usageGuide: `### 使用指南\n\n按功能分组创建扩展文件。`,
253
+ },
254
+ {
255
+ ...base,
256
+ title: `${projectName} 类型安全惯例`,
257
+ description: `项目统一使用强类型和类型守卫确保安全`,
258
+ trigger: `@${toKebab(projectName)}-type-safety`,
259
+ kind: 'rule',
260
+ category: 'Tool',
261
+ topicHint: 'conventions',
262
+ content: {
263
+ markdown: `### 类型安全\n\n${projectName} 强制类型安全,包含 ${ast.classes} 个类和 ${ast.protocols} 个协议定义。\n\n> ⚠️ Mock AI 自动生成`,
264
+ rationale: '类型安全减少运行时错误',
265
+ },
266
+ coreCode: `${lang === 'swift' ? 'guard let value = optional else { return }' : 'if (value === undefined) { return; }'}`,
267
+ doClause: 'Use type guards and optional binding for safe access',
268
+ dontClause: 'Do not use force unwrapping or type casting without checks',
269
+ whenClause: 'When handling optional values or type conversions',
270
+ usageGuide: `### 使用指南\n\n始终使用安全的类型转换。`,
271
+ },
272
+ {
273
+ ...base,
274
+ title: `${projectName} 命名约定`,
275
+ description: `文件和类型命名遵循一致的约定`,
276
+ trigger: `@${toKebab(projectName)}-naming-conventions`,
277
+ kind: 'rule',
278
+ category: 'Tool',
279
+ topicHint: 'conventions',
280
+ content: {
281
+ markdown: `### 命名约定\n\n${projectName} 使用一致的命名风格。类型: PascalCase, 方法/属性: camelCase。\n\n> ⚠️ Mock AI 自动生成`,
282
+ rationale: '统一命名提高代码可读性',
283
+ },
284
+ coreCode: `// ${typeFirst}.swift / ${typeFirst}.ts`,
285
+ doClause: 'Follow PascalCase for types and camelCase for members',
286
+ dontClause: 'Do not use abbreviations or inconsistent casing',
287
+ whenClause: 'When naming new types, methods, or properties',
288
+ usageGuide: `### 使用指南\n\n遵循项目既有命名风格。`,
289
+ },
290
+ ];
291
+ default:
292
+ return [
293
+ {
294
+ ...base,
295
+ title: `${projectName} ${dimLabel}实践`,
296
+ description: `${dimLabel}维度的最佳实践,基于 ${typeList} 等代码分析`,
297
+ trigger: `@${toKebab(projectName)}-${toKebab(dimLabel)}-practice`,
298
+ kind: 'pattern',
299
+ category: 'Tool',
300
+ topicHint: dimId.includes('network')
301
+ ? 'networking'
302
+ : dimId.includes('ui')
303
+ ? 'ui'
304
+ : 'conventions',
305
+ content: {
306
+ markdown: `### ${dimLabel}\n\n${projectName} 在 ${dimLabel} 方面的实践,涉及 ${typeList} 等核心类型。\n\n**文件统计**: ${ast.classes} 类, ${ast.protocols} 协议, ${ast.functions} 函数\n\n**来源**: \`${srcFirst}\`\n\n> ⚠️ Mock AI 自动生成`,
307
+ rationale: `${dimLabel}是项目质量的重要维度`,
308
+ },
309
+ coreCode: `// See ${srcFirst}`,
310
+ doClause: `Follow established ${dimLabel} patterns in the project`,
311
+ dontClause: `Do not deviate from the project's ${dimLabel} conventions`,
312
+ whenClause: `When working on ${dimLabel}-related code`,
313
+ usageGuide: `### 使用指南\n\n遵循项目的 ${dimLabel} 约定。`,
314
+ },
315
+ {
316
+ ...base,
317
+ title: `${typeFirst} ${dimLabel}约定`,
318
+ description: `${typeFirst} 相关的 ${dimLabel} 约定`,
319
+ trigger: `@${toKebab(typeFirst)}-${toKebab(dimLabel)}`,
320
+ kind: 'rule',
321
+ category: 'Tool',
322
+ topicHint: dimId.includes('network') ? 'networking' : 'conventions',
323
+ content: {
324
+ markdown: `### ${typeFirst} ${dimLabel}\n\n${typeFirst} 遵循的 ${dimLabel} 约定。\n\n> ⚠️ Mock AI 自动生成`,
325
+ rationale: `基于 ${typeFirst} 的实际代码模式`,
326
+ },
327
+ coreCode: `// ${typeFirst} — ${dimLabel}`,
328
+ doClause: `Apply ${dimLabel} patterns consistent with ${typeFirst}`,
329
+ dontClause: `Do not introduce inconsistent ${dimLabel} approaches`,
330
+ whenClause: `When modifying ${typeFirst} or related components`,
331
+ usageGuide: `### 使用指南\n\n参考 ${typeFirst} 的既有实现。`,
332
+ },
333
+ {
334
+ ...base,
335
+ title: `${projectName} ${dimLabel}检查清单`,
336
+ description: `${dimLabel}方面的代码审查清单`,
337
+ trigger: `@${toKebab(projectName)}-${toKebab(dimLabel)}-checklist`,
338
+ kind: 'fact',
339
+ category: 'Tool',
340
+ topicHint: 'conventions',
341
+ content: {
342
+ markdown: `### ${dimLabel} 检查清单\n\n1. 遵循项目既有模式\n2. 确保类型安全\n3. 添加适当的错误处理\n4. 保持代码一致性\n\n> ⚠️ Mock AI 自动生成`,
343
+ rationale: `${dimLabel}检查清单帮助保持代码质量`,
344
+ },
345
+ coreCode: `// ${dimLabel} checklist applied`,
346
+ doClause: `Review code against the ${dimLabel} checklist before committing`,
347
+ dontClause: `Do not skip ${dimLabel} review for shortcuts`,
348
+ whenClause: `During code review for ${dimLabel}-related changes`,
349
+ usageGuide: `### 使用指南\n\n在代码审查时参考此清单。`,
350
+ },
351
+ ];
352
+ }
353
+ }
354
+ // ── Mock Pipeline 入口 ────────────────────────────────────────
355
+ /**
356
+ * fillDimensionsMock — Mock AI 轻量管线
357
+ *
358
+ * 利用 Phase 1-4 的真实数据(AST、文件列表、Panorama)自动生成候选知识,
359
+ * 不调用任何 AI API,但走完 submit → dimension_complete 的完整流程。
360
+ */
361
+ export async function fillDimensionsMock(view, dimensions) {
362
+ const { snapshot, projectRoot } = view;
363
+ const ctx = view.ctx;
364
+ const emitter = new BootstrapEventEmitter(ctx.container);
365
+ const projectName = path.basename(projectRoot);
366
+ const primaryLang = snapshot.language.primaryLang ?? 'unknown';
367
+ const astStats = extractAstStats(snapshot.ast);
368
+ const allFiles = snapshot.allFiles;
369
+ const targetFileMap = view.targetFileMap;
370
+ const repFiles = getRepresentativeFiles(allFiles, targetFileMap);
371
+ logger.info(`[MockPipeline] ═══ Starting Mock bootstrap — ${dimensions.length} dimensions, ` +
372
+ `${allFiles?.length || 0} files, lang=${primaryLang}`);
373
+ emitter.emitProgress('bootstrap:mock-mode', {
374
+ message: '🧪 Mock AI 模式 — 基于代码结构自动生成知识候选(非 AI 深度分析)',
375
+ mockMode: true,
376
+ });
377
+ const knowledgeService = ctx.container.get('knowledgeService');
378
+ let totalCreated = 0;
379
+ for (const dim of dimensions) {
380
+ const dimStartTime = Date.now();
381
+ const dimLabel = dim.label ?? dim.id;
382
+ emitter.emitProgress('bootstrap:dimension-start', {
383
+ dimensionId: dim.id,
384
+ dimensionLabel: dimLabel,
385
+ mockMode: true,
386
+ });
387
+ logger.info(`[MockPipeline] ── Dimension "${dim.id}" (${dimLabel}) ──`);
388
+ // 生成候选
389
+ const candidates = generateDimensionCandidates(dim.id, dimLabel, allFiles, primaryLang, projectName, astStats, repFiles);
390
+ const createdIds = [];
391
+ for (const candidate of candidates) {
392
+ try {
393
+ const entry = await knowledgeService.create({
394
+ ...candidate,
395
+ source: 'mock-bootstrap',
396
+ }, { userId: 'mock-ai' });
397
+ createdIds.push(entry.id);
398
+ totalCreated++;
399
+ // 尝试自动评分(非关键路径)
400
+ try {
401
+ await knowledgeService.updateQuality?.(entry.id, { userId: 'mock-ai' });
402
+ }
403
+ catch {
404
+ /* best effort */
405
+ }
406
+ logger.info(`[MockPipeline] ✅ Created: "${candidate.title}" → ${entry.id}`);
407
+ }
408
+ catch (err) {
409
+ const msg = err instanceof Error ? err.message : String(err);
410
+ logger.warn(`[MockPipeline] ⚠️ Failed to create "${candidate.title}": ${msg}`);
411
+ }
412
+ }
413
+ const durationMs = Date.now() - dimStartTime;
414
+ emitter.emitDimensionComplete(dim.id, {
415
+ type: 'candidate',
416
+ extracted: candidates.length,
417
+ created: createdIds.length,
418
+ status: 'mock-pipeline-complete',
419
+ degraded: false,
420
+ durationMs,
421
+ toolCallCount: 0,
422
+ source: 'mock-pipeline',
423
+ });
424
+ logger.info(`[MockPipeline] ✅ "${dim.id}": ${createdIds.length}/${candidates.length} candidates, ${durationMs}ms`);
425
+ }
426
+ emitter.emitProgress('bootstrap:mock-complete', {
427
+ message: `🧪 Mock Bootstrap 完成: ${totalCreated} 个候选知识已生成`,
428
+ totalCreated,
429
+ mockMode: true,
430
+ });
431
+ logger.info(`[MockPipeline] ═══ Mock bootstrap complete — ${totalCreated} candidates from ${dimensions.length} dimensions`);
432
+ }
@@ -20,6 +20,7 @@ import { ExplorationTracker } from '#agent/context/ExplorationTracker.js';
20
20
  import { EpisodicConsolidator } from '#agent/domain/EpisodicConsolidator.js';
21
21
  import { ANALYST_BUDGET } from '#agent/domain/insight-analyst.js';
22
22
  import { MemoryCoordinator } from '#agent/memory/MemoryCoordinator.js';
23
+ import { MemoryEmbeddingStore } from '#agent/memory/MemoryEmbeddingStore.js';
23
24
  import { PersistentMemory } from '#agent/memory/PersistentMemory.js';
24
25
  import { SessionStore } from '#agent/memory/SessionStore.js';
25
26
  import { PRESETS } from '#agent/presets.js';
@@ -32,6 +33,7 @@ import { clearCheckpoints, loadCheckpoints, saveDimensionCheckpoint } from './ch
32
33
  import { buildTierReflection, DIMENSION_CONFIGS_V3, getFullDimensionConfig, } from './dimension-configs.js';
33
34
  import { DimensionContext, parseDimensionDigest } from './dimension-context.js';
34
35
  import { IncrementalBootstrap } from './IncrementalBootstrap.js';
36
+ import { fillDimensionsMock } from './mock-pipeline.js';
35
37
  import { TierScheduler } from './tier-scheduler.js';
36
38
  const logger = Logger.getInstance();
37
39
  // ──────────────────────────────────────────────────────────────────
@@ -116,21 +118,22 @@ export async function fillDimensionsV3(view, dimensions) {
116
118
  logger.info(`[Insight-v3] ═══ fillDimensionsV3 entered — ${isIncremental ? 'INCREMENTAL' : 'FULL'} pipeline`);
117
119
  let allFiles = snapshot.allFiles;
118
120
  // ═══════════════════════════════════════════════════════════
119
- // Step 0: AI 可用性检查 (v7.2: 使用 AgentFactory)
121
+ // Step 0: AI 可用性检查 (v7.2: 使用 AgentFactory + AiProviderManager)
120
122
  // ═══════════════════════════════════════════════════════════
121
123
  let agentFactory = null;
124
+ let isMockMode = false;
122
125
  try {
123
- agentFactory = ctx.container.get('agentFactory');
124
- // 检查 AI Provider 是否可用
125
- const aiProvider = ctx.container.singletons?.aiProvider;
126
- if (!aiProvider || aiProvider.name === 'mock') {
127
- agentFactory = null;
126
+ // 通过 AiProviderManager 统一检查 mock 模式
127
+ const manager = ctx.container.singletons?._aiProviderManager;
128
+ isMockMode = manager?.isMock ?? false;
129
+ if (!isMockMode) {
130
+ agentFactory = ctx.container.get('agentFactory');
128
131
  }
129
132
  }
130
133
  catch {
131
134
  /* not available */
132
135
  }
133
- if (!agentFactory) {
136
+ if (!agentFactory && !isMockMode) {
134
137
  logger.error('[Insight-v3] AI Provider not available — bootstrap requires AI');
135
138
  emitter.emitProgress('bootstrap:ai-unavailable', {
136
139
  message: 'AI Provider 不可用,Bootstrap 需要 AI 才能运行。请先配置 AI Provider(如 OpenAI、Anthropic 等)后重试。',
@@ -140,6 +143,12 @@ export async function fillDimensionsV3(view, dimensions) {
140
143
  }
141
144
  return;
142
145
  }
146
+ // Mock AI: 走 mock-pipeline 轻量管线
147
+ if (isMockMode) {
148
+ logger.info('[Insight-v3] Mock AI detected — routing to mock-pipeline');
149
+ await fillDimensionsMock(view, dimensions);
150
+ return;
151
+ }
143
152
  // ═══════════════════════════════════════════════════════════
144
153
  // Step 0.5: 构建 ProjectGraph
145
154
  // ═══════════════════════════════════════════════════════════
@@ -151,7 +160,7 @@ export async function fillDimensionsV3(view, dimensions) {
151
160
  timeoutMs: 15_000,
152
161
  })) ?? null;
153
162
  if (projectGraph) {
154
- const overview = projectGraph.getOverview();
163
+ const overview = await projectGraph.getOverview();
155
164
  logger.info(`[Insight-v3] ProjectGraph: ${overview.totalClasses} classes, ${overview.totalProtocols} protocols (${overview.buildTimeMs}ms)`);
156
165
  }
157
166
  }
@@ -225,7 +234,11 @@ export async function fillDimensionsV3(view, dimensions) {
225
234
  catch {
226
235
  // EmbedProvider 不可用时 fallback 到无向量模式
227
236
  }
228
- semanticMemory = new PersistentMemory(db, { logger, embeddingFn });
237
+ semanticMemory = new PersistentMemory(db, {
238
+ logger,
239
+ embeddingFn,
240
+ embeddingStore: new MemoryEmbeddingStore(projectRoot),
241
+ });
229
242
  const smStats = semanticMemory.getStats();
230
243
  if (smStats.total > 0) {
231
244
  logger.info(`[Insight-v3] Loaded ${smStats.total} semantic memories from previous bootstrap ` +
@@ -240,10 +253,11 @@ export async function fillDimensionsV3(view, dimensions) {
240
253
  let codeEntityGraphInst = null;
241
254
  try {
242
255
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
243
- const db = ctx.container.get('database');
244
- if (db) {
245
- codeEntityGraphInst = new CodeEntityGraph(db, { projectRoot, logger });
246
- const topo = codeEntityGraphInst.getTopology();
256
+ const entityRepo = ctx.container.get('codeEntityRepository');
257
+ const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
258
+ if (entityRepo && edgeRepo) {
259
+ codeEntityGraphInst = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
260
+ const topo = await codeEntityGraphInst.getTopology();
247
261
  if (topo.totalEntities > 0) {
248
262
  logger.info(`[Insight-v3] CodeEntityGraph: ${topo.totalEntities} entities, ${topo.totalEdges} edges`);
249
263
  }
@@ -311,6 +325,7 @@ export async function fillDimensionsV3(view, dimensions) {
311
325
  // ── 跨维度去重集合 (实例级持久化,等效旧 ChatAgent.#globalSubmittedTitles/Patterns) ──
312
326
  const globalSubmittedTitles = new Set();
313
327
  const globalSubmittedPatterns = new Set();
328
+ const globalSubmittedTriggers = new Set();
314
329
  // ── Rescan 模式: 预种已有 recipe 标题到去重集合,防止重复创建 ──
315
330
  const existingRecipesList = existingRecipes;
316
331
  if (existingRecipesList && existingRecipesList.length > 0) {
@@ -319,8 +334,12 @@ export async function fillDimensionsV3(view, dimensions) {
319
334
  if (r.title && r.status !== 'decaying') {
320
335
  globalSubmittedTitles.add(r.title.toLowerCase().trim());
321
336
  }
337
+ // ★ trigger 全部预种(含 decaying),防止 trigger 冲突
338
+ if (r.trigger) {
339
+ globalSubmittedTriggers.add(r.trigger.toLowerCase().trim());
340
+ }
322
341
  }
323
- logger.info(`[Insight-v3] Rescan mode: seeded ${globalSubmittedTitles.size} existing recipe titles into dedup set`);
342
+ logger.info(`[Insight-v3] Rescan mode: seeded ${globalSubmittedTitles.size} titles + ${globalSubmittedTriggers.size} triggers into dedup set`);
324
343
  }
325
344
  // 构建 rescanContext 供 Analyst/Producer prompt 使用(区分 healthy/decaying)
326
345
  const rescanContext = existingRecipesList
@@ -579,7 +598,7 @@ export async function fillDimensionsV3(view, dimensions) {
579
598
  modules: Object.keys(targetFileMap || {}),
580
599
  },
581
600
  // ── 引擎增强参数 (PipelineStrategy → reactLoop 透传) ──
582
- contextWindow: agentFactory.createContextWindow({ isSystem: true }),
601
+ contextWindow: agentFactory?.createContextWindow({ isSystem: true }),
583
602
  // B1 fix: 分析阶段使用 analyst 策略 (SCAN→EXPLORE→VERIFY→SUMMARIZE)
584
603
  // 而非 bootstrap (EXPLORE→PRODUCE→SUMMARIZE),避免 PRODUCE nudge 浪费轮次
585
604
  // B3 fix: 透传完整 ANALYST_BUDGET (searchBudget/maxSubmits/softSubmitLimit/idleRoundsToExit)
@@ -589,6 +608,7 @@ export async function fillDimensionsV3(view, dimensions) {
589
608
  sharedState: {
590
609
  submittedTitles: globalSubmittedTitles,
591
610
  submittedPatterns: globalSubmittedPatterns,
611
+ submittedTriggers: globalSubmittedTriggers,
592
612
  _dimensionMeta: {
593
613
  id: dimId,
594
614
  outputType: dimConfig.outputType || 'candidate',
@@ -986,9 +1006,10 @@ export async function fillDimensionsV3(view, dimensions) {
986
1006
  // ═══════════════════════════════════════════════════════════
987
1007
  try {
988
1008
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
989
- const db = ctx.container.get('database');
990
- if (db) {
991
- const ceg = new CodeEntityGraph(db, { projectRoot, logger });
1009
+ const entityRepo = ctx.container.get('codeEntityRepository');
1010
+ const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
1011
+ if (entityRepo && edgeRepo) {
1012
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
992
1013
  // 收集所有维度产出的候选 (从 Producer toolCalls 中提取)
993
1014
  const allCandidates = [];
994
1015
  for (const dimData of Object.values(dimensionCandidates)) {
@@ -1007,7 +1028,7 @@ export async function fillDimensionsV3(view, dimensions) {
1007
1028
  }
1008
1029
  }
1009
1030
  if (allCandidates.length > 0) {
1010
- const relResult = ceg.populateFromCandidateRelations(allCandidates);
1031
+ const relResult = await ceg.populateFromCandidateRelations(allCandidates);
1011
1032
  logger.info(`[Insight-v3] Code Entity Graph relations: ${relResult.edgesCreated} edges from ${allCandidates.length} candidates (${relResult.durationMs}ms)`);
1012
1033
  }
1013
1034
  }
@@ -1025,7 +1046,10 @@ export async function fillDimensionsV3(view, dimensions) {
1025
1046
  try {
1026
1047
  const db = ctx.container.get('database');
1027
1048
  if (db) {
1028
- const semanticMemory = new PersistentMemory(db, { logger });
1049
+ const semanticMemory = new PersistentMemory(db, {
1050
+ logger,
1051
+ embeddingStore: new MemoryEmbeddingStore(projectRoot),
1052
+ });
1029
1053
  const consolidator = new EpisodicConsolidator(semanticMemory, { logger });
1030
1054
  consolidationResult = consolidator.consolidate(sessionStore, {
1031
1055
  bootstrapSession: sessionId,
@@ -1144,10 +1168,11 @@ export async function fillDimensionsV3(view, dimensions) {
1144
1168
  // Phase E: 附加 Code Entity Graph 拓扑到报告
1145
1169
  try {
1146
1170
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
1147
- const db = ctx.container.get('database');
1148
- if (db) {
1149
- const ceg = new CodeEntityGraph(db, { projectRoot, logger });
1150
- const topo = ceg.getTopology();
1171
+ const entityRepo = ctx.container.get('codeEntityRepository');
1172
+ const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
1173
+ if (entityRepo && edgeRepo) {
1174
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
1175
+ const topo = await ceg.getTopology();
1151
1176
  report.codeEntityGraph = {
1152
1177
  entities: topo.entities,
1153
1178
  edges: topo.edges,
@@ -21,6 +21,14 @@ export async function bootstrapRefine(ctx, args) {
21
21
  errorCode: 'MISSING_AI_PROVIDER',
22
22
  });
23
23
  }
24
+ // Mock 模式下跳过 AI 润色
25
+ if (aiProvider.name === 'mock') {
26
+ return envelope({
27
+ success: false,
28
+ message: 'AI Provider 未配置,当前为 Mock 模式。请先配置 API Key。',
29
+ errorCode: 'MOCK_MODE',
30
+ });
31
+ }
24
32
  // 接入 BootstrapTaskManager 双通道推送 refine:* 事件
25
33
  let onProgress = null;
26
34
  try {
@@ -9,7 +9,7 @@
9
9
  * Phase 1 → 文件收集(DiscovererRegistry → 多语言项目类型检测)
10
10
  * Phase 1.5 → AST 代码结构分析(tree-sitter + SFC 预处理)
11
11
  * Phase 1.6 → Code Entity Graph(代码实体关系图谱)
12
- * Phase 1.8 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
12
+ * Phase 2.2 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
13
13
  * Phase 2 → 依赖关系 → knowledge_edges
14
14
  * Phase 2.1 → Module 实体写入 Entity Graph
15
15
  * Phase 3 → Guard 规则审计