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,384 @@
1
+ /**
2
+ * RecipeProductionGateway — 统一 Recipe 生产入口
3
+ *
4
+ * 所有 Recipe 创建(Agent Tool / MCP / IDE Agent / Batch Import)
5
+ * 通过此 Gateway 的统一管道,保证前置校验一致:
6
+ *
7
+ * 1. Schema Validation (UnifiedValidator)
8
+ * 2. Similarity Check — 去重检测(可选跳过)
9
+ * 3. Consolidation Scan — 融合/重组建议(可选)
10
+ * 4. KnowledgeService.create() — 包含 ConfidenceRouter → staging / pending
11
+ * 5. Quality Scoring — 质量评分
12
+ * 6. Supersede Proposal — 创建替代提案
13
+ * 7. Audit — 统一审计
14
+ *
15
+ * @see docs/copilot/recipe-lifecycle-management.md §6
16
+ */
17
+ import { UnifiedValidator } from '#domain/knowledge/UnifiedValidator.js';
18
+ /* ═══════════════════ Gateway ═══════════════════ */
19
+ export class RecipeProductionGateway {
20
+ #knowledgeService;
21
+ #projectRoot;
22
+ #logger;
23
+ #consolidationAdvisor;
24
+ #proposalRepo;
25
+ #findSimilarRecipes;
26
+ constructor(deps) {
27
+ this.#knowledgeService = deps.knowledgeService;
28
+ this.#projectRoot = deps.projectRoot;
29
+ this.#logger = deps.logger;
30
+ this.#consolidationAdvisor = deps.consolidationAdvisor ?? null;
31
+ this.#proposalRepo = deps.proposalRepository ?? null;
32
+ this.#findSimilarRecipes = deps.findSimilarRecipes ?? null;
33
+ }
34
+ /**
35
+ * 统一创建入口
36
+ *
37
+ * Pipeline:
38
+ * 1. Schema Validation (UnifiedValidator)
39
+ * 2. Similarity Check (除非 skipSimilarityCheck)
40
+ * 3. Consolidation Scan (除非 skipConsolidation)
41
+ * 4. KnowledgeService.create() — ConfidenceRouter → staging / pending
42
+ * 5. Quality Scoring
43
+ * 6. Supersede Proposal 创建 (if supersedes)
44
+ */
45
+ async create(request) {
46
+ const { source, items, options = {} } = request;
47
+ const userId = options.userId || this.#sourceToUserId(source);
48
+ const result = {
49
+ created: [],
50
+ rejected: [],
51
+ merged: [],
52
+ blocked: [],
53
+ duplicates: [],
54
+ supersedeProposal: null,
55
+ };
56
+ if (items.length === 0) {
57
+ return result;
58
+ }
59
+ // ── Step 1: Schema Validation ──
60
+ const validator = new UnifiedValidator({
61
+ existingTitles: options.existingTitles,
62
+ existingFingerprints: options.existingFingerprints,
63
+ });
64
+ const validItems = [];
65
+ for (let i = 0; i < items.length; i++) {
66
+ const item = items[i];
67
+ const validation = validator.validate(item, {
68
+ systemInjectedFields: options.systemInjectedFields,
69
+ skipUniqueness: options.skipUniqueness,
70
+ });
71
+ if (!validation.pass) {
72
+ result.rejected.push({
73
+ index: i,
74
+ title: item.title || '(untitled)',
75
+ reason: 'validation_failed',
76
+ errors: validation.errors,
77
+ warnings: validation.warnings,
78
+ });
79
+ this.#logger?.info(`[Gateway] ✗ validation rejected item ${i}: ${validation.errors.join('; ')}`);
80
+ }
81
+ else {
82
+ validItems.push({ index: i, item });
83
+ // 记录已提交标题/指纹以防批量内重复
84
+ validator.recordSubmission(item.title, item.content?.pattern);
85
+ }
86
+ }
87
+ // ── Step 2: Similarity Check ──
88
+ let afterSimilarityItems = validItems;
89
+ if (!options.skipSimilarityCheck && this.#findSimilarRecipes) {
90
+ const threshold = options.similarityThreshold ?? 0.7;
91
+ afterSimilarityItems = [];
92
+ for (const entry of validItems) {
93
+ const { item, index } = entry;
94
+ const contentObj = item.content && typeof item.content === 'object' ? item.content : { markdown: '' };
95
+ const cand = {
96
+ title: item.title || '',
97
+ summary: item.description || '',
98
+ code: contentObj.markdown || contentObj.pattern || '',
99
+ };
100
+ const similar = this.#findSimilarRecipes(this.#projectRoot, cand, {
101
+ threshold: 0.5,
102
+ topK: 5,
103
+ });
104
+ const hasDuplicate = similar.some((s) => s.similarity >= threshold);
105
+ if (hasDuplicate) {
106
+ result.duplicates.push({
107
+ index,
108
+ title: item.title || '(untitled)',
109
+ similarTo: similar,
110
+ });
111
+ this.#logger?.info(`[Gateway] ✗ duplicate blocked item ${index}: similarity ${similar[0]?.similarity}`);
112
+ }
113
+ else {
114
+ afterSimilarityItems.push(entry);
115
+ }
116
+ }
117
+ }
118
+ // ── Step 3: Consolidation Scan ──
119
+ let submittableItems = afterSimilarityItems;
120
+ if (!options.skipConsolidation &&
121
+ this.#consolidationAdvisor &&
122
+ afterSimilarityItems.length > 0) {
123
+ submittableItems = [];
124
+ try {
125
+ const candidates = afterSimilarityItems.map((e) => ({
126
+ title: e.item.title || '',
127
+ category: e.item.category || e.item._category || '',
128
+ ...e.item,
129
+ }));
130
+ const batchAdvice = this.#consolidationAdvisor.analyzeBatch(candidates);
131
+ for (let ai = 0; ai < batchAdvice.items.length; ai++) {
132
+ const { advice } = batchAdvice.items[ai];
133
+ const validEntry = afterSimilarityItems[ai];
134
+ if (!validEntry) {
135
+ continue;
136
+ }
137
+ if (advice.action === 'create') {
138
+ submittableItems.push(validEntry);
139
+ }
140
+ else if (this.#proposalRepo) {
141
+ const proposal = this.#createProposalFromAdvice(advice, validEntry.item);
142
+ if (proposal) {
143
+ result.merged.push({
144
+ index: validEntry.index,
145
+ proposalId: proposal.proposalId,
146
+ type: proposal.type,
147
+ targetRecipeId: proposal.targetRecipeId,
148
+ targetTitle: proposal.targetTitle,
149
+ status: proposal.status,
150
+ expiresAt: proposal.expiresAt,
151
+ message: proposal.message,
152
+ });
153
+ }
154
+ else {
155
+ // Proposal 创建失败 → blocked
156
+ result.blocked.push({
157
+ index: validEntry.index,
158
+ title: validEntry.item.title || '(untitled)',
159
+ consolidation: advice,
160
+ });
161
+ }
162
+ }
163
+ else {
164
+ // 无 ProposalRepository → blocked
165
+ result.blocked.push({
166
+ index: validEntry.index,
167
+ title: validEntry.item.title || '(untitled)',
168
+ consolidation: advice,
169
+ });
170
+ }
171
+ }
172
+ }
173
+ catch (err) {
174
+ this.#logger?.warn(`[Gateway] ConsolidationAdvisor error, falling back to direct submit: ${err instanceof Error ? err.message : String(err)}`);
175
+ submittableItems = afterSimilarityItems;
176
+ }
177
+ }
178
+ // ── Step 4: Create via KnowledgeService ──
179
+ const createdIds = [];
180
+ for (const { item } of submittableItems) {
181
+ try {
182
+ const data = this.#prepareCreateData(item, source, userId);
183
+ const saved = await this.#knowledgeService.create(data, { userId });
184
+ result.created.push({
185
+ id: saved.id,
186
+ title: saved.title,
187
+ lifecycle: saved.lifecycle,
188
+ raw: saved,
189
+ });
190
+ createdIds.push(saved.id);
191
+ // ── Step 5: Quality Scoring (best effort) ──
192
+ try {
193
+ await this.#knowledgeService.updateQuality(saved.id, { userId });
194
+ }
195
+ catch {
196
+ /* best effort — 不阻塞创建流程 */
197
+ }
198
+ }
199
+ catch (err) {
200
+ result.rejected.push({
201
+ index: items.indexOf(item),
202
+ title: item.title || '(untitled)',
203
+ reason: 'create_failed',
204
+ errors: [err instanceof Error ? err.message : String(err)],
205
+ warnings: [],
206
+ });
207
+ this.#logger?.warn(`[Gateway] ✗ create failed for "${item.title}": ${err instanceof Error ? err.message : String(err)}`);
208
+ }
209
+ }
210
+ // ── Step 6: Supersede Proposal ──
211
+ if (options.supersedes && createdIds.length > 0) {
212
+ try {
213
+ // 直接使用 ProposalRepository(Gateway 不依赖 ServiceContainer)
214
+ if (this.#proposalRepo) {
215
+ const proposal = this.#proposalRepo.create({
216
+ type: 'supersede',
217
+ targetRecipeId: options.supersedes,
218
+ relatedRecipeIds: createdIds,
219
+ confidence: 0.9,
220
+ source: source === 'mcp-external' ? 'ide-agent' : 'ide-agent',
221
+ description: `Supersede proposal: ${createdIds.length} new recipe(s) replace ${options.supersedes}`,
222
+ evidence: [{ snapshotAt: Date.now(), newRecipeIds: createdIds }],
223
+ });
224
+ if (proposal) {
225
+ result.supersedeProposal = { proposalId: proposal.id };
226
+ }
227
+ }
228
+ }
229
+ catch (err) {
230
+ this.#logger?.warn(`[Gateway] Supersede proposal creation failed: ${err instanceof Error ? err.message : String(err)}`);
231
+ }
232
+ }
233
+ this.#logger?.info(`[Gateway] create complete: ${result.created.length} created, ${result.rejected.length} rejected, ${result.merged.length} merged, ${result.duplicates.length} duplicates | source=${source}`);
234
+ return result;
235
+ }
236
+ /* ═══════════════════ Private ═══════════════════ */
237
+ #sourceToUserId(source) {
238
+ switch (source) {
239
+ case 'agent-tool':
240
+ return 'agent';
241
+ case 'mcp-external':
242
+ return 'mcp';
243
+ case 'ide-agent':
244
+ return 'ide-agent';
245
+ case 'batch-import':
246
+ return 'batch-import';
247
+ }
248
+ }
249
+ #prepareCreateData(item, source, _userId) {
250
+ const contentObj = item.content && typeof item.content === 'object'
251
+ ? item.content
252
+ : { markdown: '', pattern: '' };
253
+ const reasoning = item.reasoning || {
254
+ whyStandard: '',
255
+ sources: ['agent'],
256
+ confidence: 0.7,
257
+ };
258
+ if (Array.isArray(reasoning.sources) && reasoning.sources.length === 0) {
259
+ reasoning.sources = ['agent'];
260
+ }
261
+ return {
262
+ language: item.language || '',
263
+ category: item.category || item._category || 'general',
264
+ knowledgeType: item.knowledgeType || 'code-pattern',
265
+ source: item.source || this.#sourceLabel(source),
266
+ title: item.title || '',
267
+ description: item.description || '',
268
+ tags: item.tags || [],
269
+ trigger: item.trigger || '',
270
+ kind: item.kind || 'pattern',
271
+ topicHint: item.topicHint || '',
272
+ whenClause: item.whenClause || '',
273
+ doClause: item.doClause || '',
274
+ dontClause: item.dontClause || '',
275
+ coreCode: item.coreCode || contentObj.pattern || '',
276
+ sourceRefs: item.sourceRefs || [],
277
+ content: contentObj,
278
+ reasoning,
279
+ headers: item.headers || [],
280
+ usageGuide: item.usageGuide || '',
281
+ scope: item.scope || '',
282
+ complexity: item.complexity || '',
283
+ sourceFile: '',
284
+ agentNotes: item.agentNotes || null,
285
+ aiInsight: reasoning.whyStandard || item.description || null,
286
+ };
287
+ }
288
+ #sourceLabel(source) {
289
+ switch (source) {
290
+ case 'agent-tool':
291
+ return 'agent';
292
+ case 'mcp-external':
293
+ return 'mcp';
294
+ case 'ide-agent':
295
+ return 'ide-agent';
296
+ case 'batch-import':
297
+ return 'batch-import';
298
+ }
299
+ }
300
+ #createProposalFromAdvice(advice, item) {
301
+ if (!this.#proposalRepo) {
302
+ return null;
303
+ }
304
+ const evidence = [
305
+ {
306
+ snapshotAt: Date.now(),
307
+ candidateTitle: item.title,
308
+ candidateCategory: item.category,
309
+ analysisReason: advice.reason,
310
+ mergeDirection: advice.mergeDirection,
311
+ },
312
+ ];
313
+ if (advice.action === 'merge' && advice.targetRecipe) {
314
+ const proposal = this.#proposalRepo.create({
315
+ type: 'merge',
316
+ targetRecipeId: advice.targetRecipe.id,
317
+ confidence: advice.confidence,
318
+ source: 'ide-agent',
319
+ description: advice.reason,
320
+ evidence,
321
+ });
322
+ if (!proposal) {
323
+ return null;
324
+ }
325
+ return {
326
+ proposalId: proposal.id,
327
+ type: 'merge',
328
+ targetRecipeId: advice.targetRecipe.id,
329
+ targetTitle: advice.targetRecipe.title,
330
+ status: proposal.status,
331
+ expiresAt: proposal.expiresAt,
332
+ message: `已为「${advice.targetRecipe.title}」创建融合提案,${proposal.status === 'observing' ? '观察窗口 72h 后自动执行' : '等待开发者确认'}。`,
333
+ };
334
+ }
335
+ if (advice.action === 'reorganize' && advice.reorganizeTargets?.length) {
336
+ const target = advice.reorganizeTargets[0];
337
+ const proposal = this.#proposalRepo.create({
338
+ type: 'reorganize',
339
+ targetRecipeId: target.id,
340
+ relatedRecipeIds: advice.reorganizeTargets.slice(1).map((t) => t.id),
341
+ confidence: advice.confidence,
342
+ source: 'ide-agent',
343
+ description: advice.reason,
344
+ evidence,
345
+ });
346
+ if (!proposal) {
347
+ return null;
348
+ }
349
+ return {
350
+ proposalId: proposal.id,
351
+ type: 'reorganize',
352
+ targetRecipeId: target.id,
353
+ targetTitle: target.title,
354
+ status: proposal.status,
355
+ expiresAt: proposal.expiresAt,
356
+ message: `已为 ${advice.reorganizeTargets.length} 条 Recipe 创建重组提案,需开发者在 Dashboard 确认。`,
357
+ };
358
+ }
359
+ if (advice.action === 'insufficient' && advice.coveredBy?.length) {
360
+ const target = advice.coveredBy[0];
361
+ const proposal = this.#proposalRepo.create({
362
+ type: 'enhance',
363
+ targetRecipeId: target.id,
364
+ confidence: advice.confidence,
365
+ source: 'ide-agent',
366
+ description: advice.reason,
367
+ evidence,
368
+ });
369
+ if (!proposal) {
370
+ return null;
371
+ }
372
+ return {
373
+ proposalId: proposal.id,
374
+ type: 'enhance',
375
+ targetRecipeId: target.id,
376
+ targetTitle: target.title,
377
+ status: proposal.status,
378
+ expiresAt: proposal.expiresAt,
379
+ message: `候选独立价值不足,已创建增强提案建议补充到「${target.title}」。`,
380
+ };
381
+ }
382
+ return null;
383
+ }
384
+ }
@@ -352,8 +352,10 @@ export class ModuleService {
352
352
  }
353
353
  const scannedFiles = files.map((f) => ({ name: f.name, path: f.relativePath }));
354
354
  this.#logger.info(`[ModuleService] scanTarget: ${targetName}, ${files.length} files`);
355
- // 3. AI 提取
356
- if (!this.#agentFactory) {
355
+ // 3. AI 提取 — mock 模式或无 agentFactory 时直接跳过
356
+ const aiManager = this.#container?.singletons
357
+ ?._aiProviderManager;
358
+ if (!this.#agentFactory || aiManager?.isMock) {
357
359
  return {
358
360
  recipes: [],
359
361
  scannedFiles,
@@ -375,21 +377,7 @@ export class ModuleService {
375
377
  this.#enrichRecipes(recipes);
376
378
  const result = { recipes, scannedFiles };
377
379
  if (recipes.length === 0) {
378
- // 检查是否因为 AI Provider mock 导致空结果
379
- try {
380
- const singletons = this.#container?.singletons;
381
- const aiProvider = singletons?.aiProvider;
382
- if (!aiProvider || aiProvider.name === 'mock') {
383
- result.noAi = true;
384
- result.message = 'AI 未配置,已跳过智能提取。请在 .env 中设置 API Key 后重试。';
385
- }
386
- else {
387
- result.message = `AI 提取完成,但未发现可复用的代码模式(${targetName}, ${files.length} 个文件)`;
388
- }
389
- }
390
- catch {
391
- result.message = `AI 提取完成,但未发现可复用的代码模式(${targetName}, ${files.length} 个文件)`;
392
- }
380
+ result.message = `AI 提取完成,但未发现可复用的代码模式(${targetName}, ${files.length} 个文件)`;
393
381
  }
394
382
  onProgress?.({
395
383
  type: 'scan:completed',
@@ -464,13 +452,15 @@ export class ModuleService {
464
452
  path: f.relativePath,
465
453
  targetName: f.targetName,
466
454
  }));
467
- // 3. AI 提取 Recipes
455
+ // 3. AI 提取 Recipes — mock 模式跳过
468
456
  const allRecipes = [];
469
457
  const PER_BATCH_TIMEOUT = options.batchTimeout || 90000;
470
458
  const startTime = Date.now();
471
459
  const TOTAL_TIMEOUT = options.totalTimeout || 540000;
472
460
  let timedOut = false;
473
- if (this.#agentFactory) {
461
+ const scanAiMgr = this.#container?.singletons
462
+ ?._aiProviderManager;
463
+ if (this.#agentFactory && !scanAiMgr?.isMock) {
474
464
  const BATCH_SIZE = options.batchSize || 20;
475
465
  for (let i = 0; i < allFiles.length; i += BATCH_SIZE) {
476
466
  if (Date.now() - startTime > TOTAL_TIMEOUT) {
@@ -613,6 +603,7 @@ export class ModuleService {
613
603
  go: 'go',
614
604
  jvm: 'java',
615
605
  python: 'python',
606
+ customConfig: 'swift',
616
607
  generic: 'unknown',
617
608
  };
618
609
  return map[id] || 'unknown';
@@ -11,10 +11,18 @@ export interface CouplingMetrics {
11
11
  fanIn: number;
12
12
  fanOut: number;
13
13
  }
14
+ export interface ExternalDepMetrics {
15
+ name: string;
16
+ fanIn: number;
17
+ /** 依赖此外部库的本地模块列表 */
18
+ dependedBy: string[];
19
+ }
14
20
  export interface CouplingResult {
15
21
  cycles: CyclicDependency[];
16
22
  metrics: Map<string, CouplingMetrics>;
17
23
  edges: Edge[];
24
+ /** 外部依赖 fan-in 统计(按 fan-in 降序排列) */
25
+ externalDeps: ExternalDepMetrics[];
18
26
  }
19
27
  export declare class CouplingAnalyzer {
20
28
  #private;
@@ -22,6 +30,7 @@ export declare class CouplingAnalyzer {
22
30
  /**
23
31
  * 分析模块间耦合关系
24
32
  * @param moduleFiles - Map<moduleName, filePaths[]>
33
+ * @param externalModules - 外部模块名集合(无源码但参与依赖图)
25
34
  */
26
- analyze(moduleFiles: Map<string, string[]>): CouplingResult;
35
+ analyze(moduleFiles: Map<string, string[]>, externalModules?: Set<string>): CouplingResult;
27
36
  }
@@ -23,8 +23,9 @@ export class CouplingAnalyzer {
23
23
  /**
24
24
  * 分析模块间耦合关系
25
25
  * @param moduleFiles - Map<moduleName, filePaths[]>
26
+ * @param externalModules - 外部模块名集合(无源码但参与依赖图)
26
27
  */
27
- analyze(moduleFiles) {
28
+ analyze(moduleFiles, externalModules) {
28
29
  // 1. 构建 file → module 反向索引
29
30
  const fileToModule = new Map();
30
31
  for (const [mod, files] of moduleFiles) {
@@ -66,9 +67,11 @@ export class CouplingAnalyzer {
66
67
  toM.fanIn++;
67
68
  }
68
69
  }
70
+ // 5.5 外部依赖 fan-in 统计
71
+ const externalDeps = this.#computeExternalFanIn(moduleFiles, externalModules);
69
72
  // 去重边 (同 from→to 聚合)
70
73
  const dedupEdges = this.#deduplicateEdges(edges);
71
- return { cycles, metrics, edges: dedupEdges };
74
+ return { cycles, metrics, edges: dedupEdges, externalDeps };
72
75
  }
73
76
  /* ─── Internal helpers ──────────────────────────── */
74
77
  #buildModuleEdges(moduleFiles, fileToModule) {
@@ -174,6 +177,45 @@ export class CouplingAnalyzer {
174
177
  severity: cycle.length > 3 ? 'error' : 'warning',
175
178
  }));
176
179
  }
180
+ /**
181
+ * 统计外部依赖的 fan-in(被多少本地模块依赖)
182
+ * 数据来源:knowledge_edges 中 from_type='module' AND to_type='module' 且 to 不在 moduleFiles 中
183
+ */
184
+ #computeExternalFanIn(moduleFiles, externalModules) {
185
+ const fanInMap = new Map();
186
+ // 从 DB 查询 module-to-module depends_on 边
187
+ const rows = this.#db
188
+ .prepare(`SELECT from_id, to_id FROM knowledge_edges
189
+ WHERE relation = 'depends_on' AND from_type = 'module' AND to_type = 'module'`)
190
+ .all();
191
+ for (const row of rows) {
192
+ const fromId = row.from_id;
193
+ const toId = row.to_id;
194
+ // from 必须是本地模块, to 必须是外部模块
195
+ if (!moduleFiles.has(fromId)) {
196
+ continue;
197
+ }
198
+ if (moduleFiles.has(toId)) {
199
+ continue;
200
+ }
201
+ // 如果提供了 externalModules 集合,检查 toId 是否在其中
202
+ if (externalModules && !externalModules.has(toId)) {
203
+ continue;
204
+ }
205
+ if (!fanInMap.has(toId)) {
206
+ fanInMap.set(toId, new Set());
207
+ }
208
+ fanInMap.get(toId).add(fromId);
209
+ }
210
+ // 转换为排序数组(按 fan-in 降序)
211
+ return [...fanInMap.entries()]
212
+ .map(([name, deps]) => ({
213
+ name,
214
+ fanIn: deps.size,
215
+ dependedBy: [...deps].sort(),
216
+ }))
217
+ .sort((a, b) => b.fanIn - a.fanIn);
218
+ }
177
219
  #deduplicateEdges(edges) {
178
220
  const key = (e) => `${e.from}→${e.to}`;
179
221
  const map = new Map();
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * DimensionAnalyzer — 多维度知识健康分析
3
3
  *
4
+ * **v2: 从统一维度注册表 (DimensionRegistry) 派生维度**
5
+ *
4
6
  * 灵感来源:
5
7
  * - ISO/IEC 25010 质量模型 (8 大特性: 可靠性、安全性、可维护性…)
6
8
  * - ThoughtWorks Tech Radar (Adopt/Trial/Assess/Hold 四环)
7
9
  * - 雷达图/蛛网图可视化模型
8
10
  *
9
- * 核心思路: 不再按「模块 × 文件数」衡量覆盖,
10
- * 而是按「知识维度」衡量项目在各工程方向上的规范成熟度。
11
+ * 核心思路: 按「知识维度」衡量项目在各工程方向上的规范成熟度。
11
12
  * 某维度 Recipe 为 0 → 该方向完全空白,标示为 gap。
12
13
  *
13
14
  * @module DimensionAnalyzer
@@ -15,7 +16,7 @@
15
16
  import type { CeDbLike, HealthRadar, KnowledgeGap } from './PanoramaTypes.js';
16
17
  export declare class DimensionAnalyzer {
17
18
  #private;
18
- constructor(db: CeDbLike);
19
+ constructor(db: CeDbLike, projectRoot: string);
19
20
  /**
20
21
  * 分析项目知识健康雷达
21
22
  *