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
@@ -0,0 +1,41 @@
1
+ /**
2
+ * CacheCoordinator — 跨进程缓存失效协调器
3
+ *
4
+ * 利用 SQLite 内置的 `PRAGMA data_version` 检测其他进程的 DB 写入。
5
+ * 当检测到 data_version 变化时,通知所有注册的订阅者清除内存缓存。
6
+ *
7
+ * 原理:
8
+ * - SQLite 的 data_version 是一个连接级别的计数器
9
+ * - 当 *其他* 连接(包括其他进程)提交写事务后,当前连接的下次读操作
10
+ * 会看到递增的 data_version
11
+ * - 通过定期轮询(默认 2s),实现近实时的跨进程缓存失效
12
+ * - 开销极低:一次 pragma 读取 < 0.01ms
13
+ *
14
+ * 典型场景:
15
+ * - MCP Server 冷启动写入 33 条 Recipe → HTTP Server 的 data_version 变化
16
+ * - 用户 CLI 执行 `asd embed` → Dashboard API 的缓存自动失效
17
+ *
18
+ * @module infrastructure/cache/CacheCoordinator
19
+ */
20
+ import type { SqliteDatabase } from '../database/DatabaseConnection.js';
21
+ export type InvalidateHandler = () => void;
22
+ export declare class CacheCoordinator {
23
+ #private;
24
+ constructor(db: SqliteDatabase, pollIntervalMs?: number);
25
+ /** 启动轮询(仅长驻进程需要:HTTP server / MCP server) */
26
+ start(): void;
27
+ /** 停止轮询 */
28
+ stop(): void;
29
+ /**
30
+ * 注册缓存失效回调
31
+ *
32
+ * @param name 标识名(用于日志,如 'panoramaService')
33
+ * @param handler 失效时调用的清除函数
34
+ * @returns 取消注册函数
35
+ */
36
+ subscribe(name: string, handler: InvalidateHandler): () => void;
37
+ /** 当前订阅者数量(诊断用) */
38
+ get subscriberCount(): number;
39
+ /** 手动触发一次检查(测试用) */
40
+ check(): boolean;
41
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * CacheCoordinator — 跨进程缓存失效协调器
3
+ *
4
+ * 利用 SQLite 内置的 `PRAGMA data_version` 检测其他进程的 DB 写入。
5
+ * 当检测到 data_version 变化时,通知所有注册的订阅者清除内存缓存。
6
+ *
7
+ * 原理:
8
+ * - SQLite 的 data_version 是一个连接级别的计数器
9
+ * - 当 *其他* 连接(包括其他进程)提交写事务后,当前连接的下次读操作
10
+ * 会看到递增的 data_version
11
+ * - 通过定期轮询(默认 2s),实现近实时的跨进程缓存失效
12
+ * - 开销极低:一次 pragma 读取 < 0.01ms
13
+ *
14
+ * 典型场景:
15
+ * - MCP Server 冷启动写入 33 条 Recipe → HTTP Server 的 data_version 变化
16
+ * - 用户 CLI 执行 `asd embed` → Dashboard API 的缓存自动失效
17
+ *
18
+ * @module infrastructure/cache/CacheCoordinator
19
+ */
20
+ import Logger from '../logging/Logger.js';
21
+ export class CacheCoordinator {
22
+ #db;
23
+ #lastVersion;
24
+ #interval = null;
25
+ #subscribers = new Map();
26
+ #pollMs;
27
+ constructor(db, pollIntervalMs = 2000) {
28
+ this.#db = db;
29
+ this.#pollMs = pollIntervalMs;
30
+ this.#lastVersion = this.#readVersion();
31
+ }
32
+ /** 启动轮询(仅长驻进程需要:HTTP server / MCP server) */
33
+ start() {
34
+ if (this.#interval) {
35
+ return;
36
+ }
37
+ this.#interval = setInterval(() => this.#check(), this.#pollMs);
38
+ // unref 避免阻止进程正常退出
39
+ if (this.#interval.unref) {
40
+ this.#interval.unref();
41
+ }
42
+ Logger.info('[CacheCoordinator] Started', {
43
+ pollMs: this.#pollMs,
44
+ subscribers: this.#subscribers.size,
45
+ });
46
+ }
47
+ /** 停止轮询 */
48
+ stop() {
49
+ if (this.#interval) {
50
+ clearInterval(this.#interval);
51
+ this.#interval = null;
52
+ }
53
+ }
54
+ /**
55
+ * 注册缓存失效回调
56
+ *
57
+ * @param name 标识名(用于日志,如 'panoramaService')
58
+ * @param handler 失效时调用的清除函数
59
+ * @returns 取消注册函数
60
+ */
61
+ subscribe(name, handler) {
62
+ this.#subscribers.set(name, handler);
63
+ return () => {
64
+ this.#subscribers.delete(name);
65
+ };
66
+ }
67
+ /** 当前订阅者数量(诊断用) */
68
+ get subscriberCount() {
69
+ return this.#subscribers.size;
70
+ }
71
+ /** 手动触发一次检查(测试用) */
72
+ check() {
73
+ return this.#check();
74
+ }
75
+ // ── 内部方法 ──────────────────────────────────────
76
+ #readVersion() {
77
+ return this.#db.pragma('data_version', { simple: true });
78
+ }
79
+ /** @returns true 如果版本变化并触发了失效 */
80
+ #check() {
81
+ const current = this.#readVersion();
82
+ if (current === this.#lastVersion) {
83
+ return false;
84
+ }
85
+ const prev = this.#lastVersion;
86
+ this.#lastVersion = current;
87
+ const names = [...this.#subscribers.keys()];
88
+ Logger.info('[CacheCoordinator] DB changed by another process, invalidating caches', {
89
+ prevVersion: prev,
90
+ newVersion: current,
91
+ targets: names,
92
+ });
93
+ for (const [name, handler] of this.#subscribers) {
94
+ try {
95
+ handler();
96
+ }
97
+ catch (err) {
98
+ Logger.warn(`[CacheCoordinator] Invalidation handler "${name}" threw`, {
99
+ error: err.message,
100
+ });
101
+ }
102
+ }
103
+ return true;
104
+ }
105
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Migration 006 — Lifecycle Transition Events
3
+ *
4
+ * Recipe 生命周期状态转移事件日志表(Event Sourcing 模式)。
5
+ * 记录每次状态转移的完整审计信息,支持回溯与监控。
6
+ */
7
+ export default function migrate(db: import('better-sqlite3').Database): void;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Migration 006 — Lifecycle Transition Events
3
+ *
4
+ * Recipe 生命周期状态转移事件日志表(Event Sourcing 模式)。
5
+ * 记录每次状态转移的完整审计信息,支持回溯与监控。
6
+ */
7
+ export default function migrate(db) {
8
+ db.exec(`
9
+ CREATE TABLE IF NOT EXISTS lifecycle_transition_events (
10
+ id TEXT PRIMARY KEY,
11
+ recipe_id TEXT NOT NULL,
12
+ from_state TEXT NOT NULL,
13
+ to_state TEXT NOT NULL,
14
+ trigger TEXT NOT NULL,
15
+ operator_id TEXT NOT NULL DEFAULT 'system',
16
+ evidence_json TEXT,
17
+ proposal_id TEXT,
18
+ created_at INTEGER NOT NULL,
19
+
20
+ FOREIGN KEY (recipe_id) REFERENCES knowledge_entries(id),
21
+ FOREIGN KEY (proposal_id) REFERENCES evolution_proposals(id)
22
+ );
23
+
24
+ CREATE INDEX IF NOT EXISTS idx_lte_recipe_id ON lifecycle_transition_events(recipe_id);
25
+ CREATE INDEX IF NOT EXISTS idx_lte_created_at ON lifecycle_transition_events(created_at);
26
+ CREATE INDEX IF NOT EXISTS idx_lte_trigger ON lifecycle_transition_events(trigger);
27
+ `);
28
+ }
@@ -468,7 +468,7 @@ export class HnswVectorAdapter extends VectorStore {
468
468
  }));
469
469
  }
470
470
  /**
471
- * 关键词搜索 (BM25 简化版: token 匹配 + IDF 近似)
471
+ * 关键词搜索 (token 匹配 + IDF 近似)
472
472
  * @returns >}
473
473
  */
474
474
  #keywordSearch(queryText, limit, filter) {
@@ -32,11 +32,12 @@ export declare class ServiceContainer {
32
32
  /**
33
33
  * 热重载 AI Provider(API Key 变更后调用,无需重启进程)
34
34
  *
35
- * 流程:
36
- * 1. 替换 singletons.aiProvider
37
- * 2. 重新创建 _embedProvider(如果主 provider 不支持 embedding)
38
- * 3. 清除已缓存的依赖 AI 的 singleton(SearchEngine 等),
39
- * 下次 get() 时会用新 provider 重新创建
35
+ * 委托给 AiProviderManager.switchProvider() — 原子操作:
36
+ * 1. 替换 provider 引用 + DI 数据管道同步
37
+ * 2. Token 追踪 AOP 重新挂载
38
+ * 3. Embedding fallback 重建
39
+ * 4. 清除已缓存的依赖 AI singleton(SearchEngine 等)
40
+ * 5. 监听器回调通知
40
41
  */
41
42
  reloadAiProvider(newProvider: Record<string, unknown> | null): void;
42
43
  /** 获取当前默认 UI 语言偏好 */
@@ -5,6 +5,7 @@ import { resolveProjectRoot } from '#shared/resolveProjectRoot.js';
5
5
  import ProjectGraph from '../core/ast/ProjectGraph.js';
6
6
  // ─── v3.1: Multi-Language Discovery + Enhancement ────────
7
7
  import { initEnhancementRegistry } from '../core/enhancement/index.js';
8
+ import { CacheCoordinator } from '../infrastructure/cache/CacheCoordinator.js';
8
9
  import { GraphCache } from '../infrastructure/cache/GraphCache.js';
9
10
  // ─── P3: Infrastructure ──────────────────────────────
10
11
  import Logger from '../infrastructure/logging/Logger.js';
@@ -132,6 +133,8 @@ export class ServiceContainer {
132
133
  await VectorModule.initializeVectorService(this);
133
134
  // v3.4: 初始化 Knowledge 服务(绑定 EventBus → SearchEngine.refreshIndex + sourceRefs)
134
135
  KnowledgeModule.initializeKnowledgeServices(this);
136
+ // v3.5: 跨进程缓存协调器(利用 SQLite PRAGMA data_version 检测其他进程写入)
137
+ this.#initCacheCoordinator();
135
138
  this.logger.info('Service container initialized successfully');
136
139
  }
137
140
  catch (error) {
@@ -144,36 +147,72 @@ export class ServiceContainer {
144
147
  /**
145
148
  * 热重载 AI Provider(API Key 变更后调用,无需重启进程)
146
149
  *
147
- * 流程:
148
- * 1. 替换 singletons.aiProvider
149
- * 2. 重新创建 _embedProvider(如果主 provider 不支持 embedding)
150
- * 3. 清除已缓存的依赖 AI 的 singleton(SearchEngine 等),
151
- * 下次 get() 时会用新 provider 重新创建
150
+ * 委托给 AiProviderManager.switchProvider() — 原子操作:
151
+ * 1. 替换 provider 引用 + DI 数据管道同步
152
+ * 2. Token 追踪 AOP 重新挂载
153
+ * 3. Embedding fallback 重建
154
+ * 4. 清除已缓存的依赖 AI singleton(SearchEngine 等)
155
+ * 5. 监听器回调通知
152
156
  */
153
157
  reloadAiProvider(newProvider) {
154
- const old = this.singletons.aiProvider;
155
- this.singletons.aiProvider = newProvider;
156
- // 重新创建 embedding fallback provider(委托 AiModule)
157
- this.singletons._embedProvider = null;
158
- if (newProvider &&
159
- typeof newProvider.supportsEmbedding === 'function' &&
160
- !newProvider.supportsEmbedding()) {
161
- AiModule.initEmbeddingFallback(this);
158
+ if (!newProvider) {
159
+ this.logger.warn('[ServiceContainer] reloadAiProvider called with null — ignored');
160
+ return;
162
161
  }
163
- // 清除持有旧 aiProvider 引用的 singleton 缓存
164
- // 下次调用 container.get() 时会使用新 provider 重建
165
- const cleared = [];
166
- for (const key of this._aiDependentSingletons || []) {
167
- if (this.singletons[key]) {
168
- this.singletons[key] = null;
169
- cleared.push(key);
162
+ const manager = this.singletons._aiProviderManager;
163
+ manager.switchProvider(newProvider);
164
+ }
165
+ // ─── 跨进程缓存协调 ─────
166
+ /**
167
+ * 初始化 CacheCoordinator:当其他进程写入 DB 后,自动清除本进程的内存缓存。
168
+ *
169
+ * 订阅的服务:
170
+ * - panoramaService: invalidate() — 模块图 + 全景分析
171
+ * - guardCheckEngine: clearCache() — 规则缓存
172
+ * - searchEngine: buildIndex() — 搜索索引
173
+ *
174
+ * 仅在长驻进程(HTTP server / MCP server)中自动启动轮询。
175
+ * CLI 场景无需启动(进程生命周期短,缓存不会过时)。
176
+ */
177
+ #initCacheCoordinator() {
178
+ try {
179
+ const db = this.singletons.database;
180
+ const rawDb = db?.getDb ? db.getDb() : null;
181
+ if (!rawDb) {
182
+ return;
183
+ }
184
+ const coordinator = new CacheCoordinator(rawDb);
185
+ this.singletons.cacheCoordinator = coordinator;
186
+ this.register('cacheCoordinator', () => coordinator);
187
+ // 懒订阅:仅在对应服务已初始化时绑定
188
+ coordinator.subscribe('panoramaService', () => {
189
+ const svc = this.singletons.panoramaService;
190
+ svc?.invalidate?.();
191
+ });
192
+ coordinator.subscribe('guardCheckEngine', () => {
193
+ const svc = this.singletons.guardCheckEngine;
194
+ svc?.clearCache?.();
195
+ });
196
+ coordinator.subscribe('searchEngine', () => {
197
+ const svc = this.singletons.searchEngine;
198
+ svc?.buildIndex?.();
199
+ });
200
+ // 长驻进程自动启动轮询(CLI 不启动)
201
+ const isMcp = process.env.ASD_MCP_MODE === '1';
202
+ const isApiServer = process.env.ASD_API_SERVER === '1';
203
+ if (isMcp || isApiServer) {
204
+ coordinator.start();
170
205
  }
206
+ this.logger.info('CacheCoordinator initialized', {
207
+ subscribers: coordinator.subscriberCount,
208
+ polling: isMcp || isApiServer,
209
+ });
210
+ }
211
+ catch (err) {
212
+ this.logger.warn('CacheCoordinator init failed (non-blocking)', {
213
+ error: err.message,
214
+ });
171
215
  }
172
- this.logger.info('AI provider hot-reloaded', {
173
- old: old?.constructor?.name || 'none',
174
- new: newProvider?.constructor?.name || 'none',
175
- clearedSingletons: cleared,
176
- });
177
216
  }
178
217
  // ─── 容器级语言偏好 ─────
179
218
  /** 获取当前默认 UI 语言偏好 */
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * @module ServiceMap
8
8
  */
9
+ import type DimensionCopy from '#domain/dimension/DimensionCopy.js';
9
10
  import type { AgentFactory } from '../agent/AgentFactory.js';
10
11
  import type { ToolRegistry } from '../agent/tools/ToolRegistry.js';
11
12
  import type { KnowledgeSyncService } from '../cli/KnowledgeSyncService.js';
@@ -13,8 +14,10 @@ import type ProjectGraph from '../core/ast/ProjectGraph.js';
13
14
  import type Constitution from '../core/constitution/Constitution.js';
14
15
  import type Gateway from '../core/gateway/Gateway.js';
15
16
  import type { AiProvider } from '../external/ai/AiProvider.js';
17
+ import type { AiProviderManager } from '../external/ai/AiProviderManager.js';
16
18
  import type AuditLogger from '../infrastructure/audit/AuditLogger.js';
17
19
  import type AuditStore from '../infrastructure/audit/AuditStore.js';
20
+ import type { CacheCoordinator } from '../infrastructure/cache/CacheCoordinator.js';
18
21
  import type DatabaseConnection from '../infrastructure/database/DatabaseConnection.js';
19
22
  import type { EventBus } from '../infrastructure/event/EventBus.js';
20
23
  import type Logger from '../infrastructure/logging/Logger.js';
@@ -24,7 +27,6 @@ import type { VectorStore } from '../infrastructure/vector/VectorStore.js';
24
27
  import type { KnowledgeRepositoryImpl } from '../repository/knowledge/KnowledgeRepository.impl.js';
25
28
  import type { TokenUsageStore } from '../repository/token/TokenUsageStore.js';
26
29
  import type { BootstrapTaskManager } from '../service/bootstrap/BootstrapTaskManager.js';
27
- import type DimensionCopy from '../service/bootstrap/DimensionCopyRegistry.js';
28
30
  import type { CursorDeliveryPipeline } from '../service/delivery/CursorDeliveryPipeline.js';
29
31
  import type { ComplianceReporter } from '../service/guard/ComplianceReporter.js';
30
32
  import type { ExclusionManager } from '../service/guard/ExclusionManager.js';
@@ -97,6 +99,7 @@ export interface ServiceMap {
97
99
  dimensionCopy: typeof DimensionCopy;
98
100
  constitution: Constitution | null;
99
101
  aiProvider: AiProvider | null;
102
+ aiProviderManager: AiProviderManager;
100
103
  projectGraph: ProjectGraph | null;
101
104
  vectorService: VectorService;
102
105
  contextualEnricher: ContextualEnricher | null;
@@ -117,4 +120,10 @@ export interface ServiceMap {
117
120
  layerInferrer: LayerInferrer;
118
121
  panoramaAggregator: PanoramaAggregator;
119
122
  panoramaService: PanoramaService;
123
+ cacheCoordinator: CacheCoordinator;
124
+ _projectRoot: string;
125
+ _config: Record<string, unknown>;
126
+ _lang: string | null;
127
+ _fileCache: unknown[] | null;
128
+ _embedProvider: unknown;
120
129
  }
@@ -6,6 +6,7 @@
6
6
  *
7
7
  * 职责:
8
8
  * - AI Provider 自动探测与创建
9
+ * - AiProviderManager 统一管理层
9
10
  * - Embedding fallback provider 管理
10
11
  * - AiFactory 实例注入
11
12
  *
@@ -17,19 +18,15 @@ import type { ServiceContainer } from '../ServiceContainer.js';
17
18
  *
18
19
  * 1. 动态导入 AiFactory
19
20
  * 2. 自动探测可用 AI Provider
20
- * 3. 创建 Embedding fallback(若主 provider 不支持 embedding)
21
+ * 3. 创建 AiProviderManager(统一管理层)
22
+ * 4. 绑定 Token 追踪、Embedding fallback、DI 级联清理
21
23
  */
22
24
  export declare function initialize(c: ServiceContainer): Promise<void>;
23
- /**
24
- * 创建/刷新 Embedding fallback provider
25
- *
26
- * 若主 provider 不支持 embedding(如 Claude),尝试从其他可用 provider 创建备用。
27
- */
28
- export declare function initEmbeddingFallback(c: ServiceContainer): void;
29
25
  /**
30
26
  * 注册 AI 相关的服务到容器
31
27
  *
32
- * 当前 AI Provider 和 AiFactory 通过 singletons 直接管理,
33
- * 此方法注册便于其他模块通过 container.get() 获取的快捷服务。
28
+ * - 标记 AI 模块就绪
29
+ * - 注册 aiProviderManager 服务
30
+ * - 延迟注入 TokenRecorder(tokenUsageStore 此时已可用)
34
31
  */
35
32
  export declare function register(c: ServiceContainer): void;
@@ -6,17 +6,20 @@
6
6
  *
7
7
  * 职责:
8
8
  * - AI Provider 自动探测与创建
9
+ * - AiProviderManager 统一管理层
9
10
  * - Embedding fallback provider 管理
10
11
  * - AiFactory 实例注入
11
12
  *
12
13
  * @module AiModule
13
14
  */
15
+ import { AiProviderManager } from '../../external/ai/AiProviderManager.js';
14
16
  /**
15
17
  * 初始化 AI Provider(在模块注册前调用)
16
18
  *
17
19
  * 1. 动态导入 AiFactory
18
20
  * 2. 自动探测可用 AI Provider
19
- * 3. 创建 Embedding fallback(若主 provider 不支持 embedding)
21
+ * 3. 创建 AiProviderManager(统一管理层)
22
+ * 4. 绑定 Token 追踪、Embedding fallback、DI 级联清理
20
23
  */
21
24
  export async function initialize(c) {
22
25
  const logger = c.logger;
@@ -43,56 +46,96 @@ export async function initialize(c) {
43
46
  c.singletons.aiProvider = null;
44
47
  }
45
48
  }
46
- // Embedding fallback provider
47
- initEmbeddingFallback(c);
49
+ // ── 创建 AiProviderManager(统一管理层)──
50
+ const manager = new AiProviderManager(c.singletons.aiProvider || { name: 'mock', model: 'mock-fallback' });
51
+ c.singletons._aiProviderManager = manager;
52
+ // 绑定: DI 数据管道同步(切换时更新 singletons 中的 provider 引用,供工厂函数读取)
53
+ manager._bindDiSync((provider, embed) => {
54
+ c.singletons.aiProvider = provider;
55
+ c.singletons._embedProvider = embed;
56
+ });
57
+ // 绑定: DI 级联清理回调
58
+ manager._bindDependentClearer(() => {
59
+ const cleared = [];
60
+ for (const key of c._aiDependentSingletons || []) {
61
+ if (c.singletons[key]) {
62
+ c.singletons[key] = null;
63
+ cleared.push(key);
64
+ }
65
+ }
66
+ return cleared;
67
+ });
68
+ // 绑定: Embedding fallback 初始化器
69
+ manager._bindEmbedFallbackInit((currentProvider) => {
70
+ return createEmbedFallback(c, currentProvider);
71
+ });
72
+ // Token 追踪 AOP(manager 自身已在构造时 wire,此处延迟注入 recorder)
73
+ // recorder 注入放到 register() 之后(tokenUsageStore 需先注册)
74
+ // Embedding fallback: manager 的 embedFallbackInit 回调已绑定,初始化时主动触发一次
75
+ const initialEmbed = createEmbedFallback(c, c.singletons.aiProvider);
76
+ if (initialEmbed) {
77
+ manager.setEmbedProvider(initialEmbed);
78
+ c.singletons._embedProvider = initialEmbed;
79
+ }
48
80
  }
49
81
  /**
50
- * 创建/刷新 Embedding fallback provider
51
- *
52
- * 若主 provider 不支持 embedding(如 Claude),尝试从其他可用 provider 创建备用。
82
+ * 纯函数: 尝试为给定 provider 创建 Embedding fallback
83
+ * 被 initEmbeddingFallback() 和 AiProviderManager 的 embedFallbackInit 回调共用
53
84
  */
54
- export function initEmbeddingFallback(c) {
55
- const currentProvider = c.singletons.aiProvider;
56
- if ((currentProvider &&
57
- typeof currentProvider
58
- .supportsEmbedding !== 'function') ||
59
- (currentProvider &&
60
- !currentProvider.supportsEmbedding?.())) {
61
- try {
62
- const aiFactory = (c.singletons._aiFactory || {});
63
- const providerName = (currentProvider?.name || '').replace('-', '');
64
- const fbCandidates = typeof aiFactory.getAvailableFallbacks === 'function'
65
- ? aiFactory.getAvailableFallbacks(providerName)
66
- : [];
67
- for (const fb of fbCandidates) {
68
- try {
69
- const fbProvider = aiFactory.createProvider({ provider: fb });
70
- if (typeof fbProvider.supportsEmbedding === 'function' &&
71
- fbProvider.supportsEmbedding()) {
72
- c.singletons._embedProvider = fbProvider;
73
- c.logger.info('Embedding fallback provider created', { provider: fb });
74
- break;
75
- }
76
- }
77
- catch {
78
- /* skip */
85
+ function createEmbedFallback(c, currentProvider) {
86
+ if (!currentProvider ||
87
+ (typeof currentProvider.supportsEmbedding === 'function' && currentProvider.supportsEmbedding())) {
88
+ return null; // 主 provider 已支持 embedding,无需 fallback
89
+ }
90
+ try {
91
+ const aiFactory = (c.singletons._aiFactory || {});
92
+ const providerName = (currentProvider.name || '').replace('-', '');
93
+ const fbCandidates = typeof aiFactory.getAvailableFallbacks === 'function'
94
+ ? aiFactory.getAvailableFallbacks(providerName)
95
+ : [];
96
+ for (const fb of fbCandidates) {
97
+ try {
98
+ const fbProvider = aiFactory.createProvider?.({ provider: fb });
99
+ if (fbProvider &&
100
+ typeof fbProvider.supportsEmbedding === 'function' &&
101
+ fbProvider.supportsEmbedding()) {
102
+ c.logger.info('Embedding fallback provider created', { provider: fb });
103
+ return fbProvider;
79
104
  }
80
105
  }
81
- }
82
- catch {
83
- /* no embed fallback available */
106
+ catch {
107
+ /* skip */
108
+ }
84
109
  }
85
110
  }
111
+ catch {
112
+ /* no embed fallback available */
113
+ }
114
+ return null;
86
115
  }
87
116
  /**
88
117
  * 注册 AI 相关的服务到容器
89
118
  *
90
- * 当前 AI Provider 和 AiFactory 通过 singletons 直接管理,
91
- * 此方法注册便于其他模块通过 container.get() 获取的快捷服务。
119
+ * - 标记 AI 模块就绪
120
+ * - 注册 aiProviderManager 服务
121
+ * - 延迟注入 TokenRecorder(tokenUsageStore 此时已可用)
92
122
  */
93
123
  export function register(c) {
94
- // aiProvider 和 _aiFactory 已通过 initialize() 写入 singletons
95
- // KnowledgeModule 中已注册 'aiProvider' 的 register 工厂
96
- // 此处仅标记 AI 模块已就绪
97
124
  c.singletons._aiModuleReady = true;
125
+ // 注册 aiProviderManager(消费者通过 container.get('aiProviderManager') 获取)
126
+ c.register('aiProviderManager', () => c.singletons._aiProviderManager);
127
+ // 延迟注入 TokenRecorder 到 manager(tokenUsageStore 在 AppModule 中注册)
128
+ const manager = c.singletons._aiProviderManager;
129
+ const containerRef = c;
130
+ manager.setTokenRecorder({
131
+ record(r) {
132
+ try {
133
+ const store = containerRef.get('tokenUsageStore');
134
+ store.record(r);
135
+ }
136
+ catch {
137
+ /* tokenUsageStore not available yet */
138
+ }
139
+ },
140
+ });
98
141
  }
@@ -7,6 +7,7 @@
7
7
  * - discovererRegistry, enhancementRegistry, languageService, dimensionCopy
8
8
  * - constitution, aiProvider, projectGraph
9
9
  */
10
+ import { DimensionCopy } from '#domain/dimension/DimensionCopy.js';
10
11
  import { resolveProjectRoot } from '#shared/resolveProjectRoot.js';
11
12
  import { getDiscovererRegistry } from '../../core/discovery/index.js';
12
13
  import { getEnhancementRegistry } from '../../core/enhancement/index.js';
@@ -14,13 +15,14 @@ import { HnswVectorAdapter } from '../../infrastructure/vector/HnswVectorAdapter
14
15
  import { IndexingPipeline } from '../../infrastructure/vector/IndexingPipeline.js';
15
16
  import { JsonVectorAdapter } from '../../infrastructure/vector/JsonVectorAdapter.js';
16
17
  import { ProposalRepository } from '../../repository/evolution/ProposalRepository.js';
17
- import { DimensionCopy } from '../../service/bootstrap/DimensionCopyRegistry.js';
18
18
  import { ConsolidationAdvisor } from '../../service/evolution/ConsolidationAdvisor.js';
19
+ import { ContentPatcher } from '../../service/evolution/ContentPatcher.js';
19
20
  import { ContradictionDetector } from '../../service/evolution/ContradictionDetector.js';
20
21
  import { DecayDetector } from '../../service/evolution/DecayDetector.js';
21
22
  import { EnhancementSuggester } from '../../service/evolution/EnhancementSuggester.js';
22
23
  import { KnowledgeMetabolism } from '../../service/evolution/KnowledgeMetabolism.js';
23
24
  import { ProposalExecutor } from '../../service/evolution/ProposalExecutor.js';
25
+ import { RecipeLifecycleSupervisor } from '../../service/evolution/RecipeLifecycleSupervisor.js';
24
26
  import { RedundancyAnalyzer } from '../../service/evolution/RedundancyAnalyzer.js';
25
27
  import { StagingManager } from '../../service/evolution/StagingManager.js';
26
28
  import { CodeEntityGraph } from '../../service/knowledge/CodeEntityGraph.js';
@@ -184,10 +186,22 @@ export function register(c) {
184
186
  const db = ct.get('database');
185
187
  return new ProposalRepository(db.getDb());
186
188
  });
189
+ c.singleton('contentPatcher', (ct) => {
190
+ const db = ct.get('database');
191
+ return new ContentPatcher(db.getDb());
192
+ });
193
+ c.singleton('lifecycleSupervisor', (ct) => {
194
+ const db = ct.get('database');
195
+ return new RecipeLifecycleSupervisor(db.getDb(), {
196
+ signalBus: ct.singletons.signalBus || undefined,
197
+ });
198
+ });
187
199
  c.singleton('proposalExecutor', (ct) => {
188
200
  const db = ct.get('database');
189
201
  return new ProposalExecutor(db.getDb(), ct.get('proposalRepository'), {
190
202
  signalBus: ct.singletons.signalBus || undefined,
203
+ contentPatcher: ct.get('contentPatcher'),
204
+ supervisor: ct.get('lifecycleSupervisor'),
191
205
  });
192
206
  });
193
207
  c.singleton('consolidationAdvisor', (ct) => {
@@ -32,7 +32,7 @@ export const PanoramaModule = {
32
32
  ct.singleton('roleRefiner', () => new RoleRefiner(getDb(), getProjectRoot()));
33
33
  ct.singleton('couplingAnalyzer', () => new CouplingAnalyzer(getDb(), getProjectRoot()));
34
34
  ct.singleton('layerInferrer', () => new LayerInferrer());
35
- ct.singleton('dimensionAnalyzer', () => new DimensionAnalyzer(getDb()));
35
+ ct.singleton('dimensionAnalyzer', () => new DimensionAnalyzer(getDb(), getProjectRoot()));
36
36
  ct.singleton('panoramaAggregator', (c) => {
37
37
  const sc = c;
38
38
  const roleRefiner = sc.get('roleRefiner');
@@ -40,6 +40,10 @@ export declare class KnowledgeRepositoryImpl extends BaseRepository {
40
40
  * ★ Drizzle 类型安全 INSERT — 列名拼写编译期检查
41
41
  */
42
42
  create(entry: KnowledgeEntry): Promise<unknown>;
43
+ /**
44
+ * 按标题精确查找(大小写不敏感)
45
+ */
46
+ findByTitle(title: string): Promise<KnowledgeEntry | null>;
43
47
  /**
44
48
  * 更新 KnowledgeEntry(接受完整实体或部分数据)
45
49
  * ★ Drizzle 类型安全 UPDATE