autosnippet 3.2.21 → 3.3.2

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 (311) hide show
  1. package/dashboard/dist/assets/icons-BJ2mUBi8.js +1 -0
  2. package/dashboard/dist/assets/index-B659K9t5.js +128 -0
  3. package/dashboard/dist/assets/index-NCm40PMD.css +1 -0
  4. package/dashboard/dist/index.html +3 -3
  5. package/dist/bin/cli.d.ts +1 -1
  6. package/dist/bin/cli.js +244 -261
  7. package/dist/lib/agent/context/ExplorationTracker.d.ts +2 -0
  8. package/dist/lib/agent/context/ExplorationTracker.js +21 -3
  9. package/dist/lib/agent/core/ToolExecutionPipeline.d.ts +3 -1
  10. package/dist/lib/agent/core/ToolExecutionPipeline.js +8 -1
  11. package/dist/lib/agent/forge/DynamicComposer.d.ts +58 -0
  12. package/dist/lib/agent/forge/DynamicComposer.js +99 -0
  13. package/dist/lib/agent/forge/SandboxRunner.d.ts +60 -0
  14. package/dist/lib/agent/forge/SandboxRunner.js +251 -0
  15. package/dist/lib/agent/forge/TemporaryToolRegistry.d.ts +76 -0
  16. package/dist/lib/agent/forge/TemporaryToolRegistry.js +154 -0
  17. package/dist/lib/agent/forge/ToolForge.d.ts +92 -0
  18. package/dist/lib/agent/forge/ToolForge.js +239 -0
  19. package/dist/lib/agent/forge/ToolRequirementAnalyzer.d.ts +44 -0
  20. package/dist/lib/agent/forge/ToolRequirementAnalyzer.js +119 -0
  21. package/dist/lib/agent/tools/ToolRegistry.d.ts +2 -0
  22. package/dist/lib/agent/tools/ToolRegistry.js +4 -0
  23. package/dist/lib/agent/tools/composite.js +0 -1
  24. package/dist/lib/agent/tools/index.d.ts +2 -50
  25. package/dist/lib/agent/tools/index.js +2 -3
  26. package/dist/lib/agent/tools/lifecycle.d.ts +1 -58
  27. package/dist/lib/agent/tools/lifecycle.js +2 -75
  28. package/dist/lib/cli/SetupService.d.ts +46 -2
  29. package/dist/lib/cli/SetupService.js +2 -27
  30. package/dist/lib/cli/deploy/FileManifest.d.ts +0 -21
  31. package/dist/lib/cli/deploy/FileManifest.js +0 -11
  32. package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.d.ts +2 -5
  33. package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.js +159 -44
  34. package/dist/lib/core/discovery/index.d.ts +1 -1
  35. package/dist/lib/core/discovery/index.js +2 -2
  36. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +10 -0
  37. package/dist/lib/domain/knowledge/KnowledgeEntry.js +2 -0
  38. package/dist/lib/domain/knowledge/Lifecycle.d.ts +19 -2
  39. package/dist/lib/domain/knowledge/Lifecycle.js +32 -6
  40. package/dist/lib/domain/knowledge/UnifiedValidator.d.ts +1 -5
  41. package/dist/lib/domain/knowledge/UnifiedValidator.js +7 -44
  42. package/dist/lib/domain/knowledge/values/Stats.d.ts +29 -0
  43. package/dist/lib/domain/knowledge/values/Stats.js +41 -0
  44. package/dist/lib/external/mcp/McpServer.d.ts +19 -38
  45. package/dist/lib/external/mcp/McpServer.js +145 -117
  46. package/dist/lib/external/mcp/autoApproveInjector.js +0 -2
  47. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +26 -1
  48. package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +41 -0
  49. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -0
  50. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +3 -0
  51. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +27 -0
  52. package/dist/lib/external/mcp/handlers/bootstrap/skills.js +1 -1
  53. package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -0
  54. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
  55. package/dist/lib/external/mcp/handlers/consolidated.d.ts +116 -6
  56. package/dist/lib/external/mcp/handlers/consolidated.js +251 -71
  57. package/dist/lib/external/mcp/handlers/guard.d.ts +150 -0
  58. package/dist/lib/external/mcp/handlers/guard.js +245 -8
  59. package/dist/lib/external/mcp/handlers/knowledge.d.ts +0 -29
  60. package/dist/lib/external/mcp/handlers/knowledge.js +1 -76
  61. package/dist/lib/external/mcp/handlers/panorama.d.ts +36 -0
  62. package/dist/lib/external/mcp/handlers/panorama.js +156 -0
  63. package/dist/lib/external/mcp/handlers/system.d.ts +2 -54
  64. package/dist/lib/external/mcp/handlers/system.js +3 -113
  65. package/dist/lib/external/mcp/handlers/task.d.ts +13 -24
  66. package/dist/lib/external/mcp/handlers/task.js +217 -557
  67. package/dist/lib/external/mcp/handlers/types.d.ts +91 -8
  68. package/dist/lib/external/mcp/handlers/types.js +18 -1
  69. package/dist/lib/external/mcp/handlers/wiki-external.d.ts +18 -1
  70. package/dist/lib/external/mcp/handlers/wiki-external.js +16 -1
  71. package/dist/lib/external/mcp/tools.d.ts +14 -20
  72. package/dist/lib/external/mcp/tools.js +62 -91
  73. package/dist/lib/http/HttpServer.js +52 -6
  74. package/dist/lib/http/routes/{snippets.d.ts → audit.d.ts} +4 -2
  75. package/dist/lib/http/routes/audit.js +51 -0
  76. package/dist/lib/http/routes/commands.d.ts +1 -1
  77. package/dist/lib/http/routes/commands.js +1 -66
  78. package/dist/lib/http/routes/guardReport.d.ts +10 -0
  79. package/dist/lib/http/routes/guardReport.js +143 -0
  80. package/dist/lib/http/routes/knowledge.js +32 -1
  81. package/dist/lib/http/routes/panorama.d.ts +11 -0
  82. package/dist/lib/http/routes/panorama.js +322 -0
  83. package/dist/lib/http/routes/remote.js +0 -5
  84. package/dist/lib/http/routes/signals.d.ts +10 -0
  85. package/dist/lib/http/routes/signals.js +104 -0
  86. package/dist/lib/http/routes/task.d.ts +2 -3
  87. package/dist/lib/http/routes/task.js +17 -347
  88. package/dist/lib/http/routes/violations.js +1 -1
  89. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +6 -1
  90. package/dist/lib/infrastructure/audit/AuditLogger.js +14 -1
  91. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +181 -583
  92. package/dist/lib/infrastructure/database/drizzle/schema.js +28 -69
  93. package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.d.ts +8 -0
  94. package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.js +43 -0
  95. package/dist/lib/infrastructure/logging/Logger.d.ts +2 -0
  96. package/dist/lib/infrastructure/logging/Logger.js +34 -7
  97. package/dist/lib/infrastructure/monitoring/ErrorTracker.js +3 -1
  98. package/dist/lib/infrastructure/monitoring/PerformanceMonitor.d.ts +2 -2
  99. package/dist/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -10
  100. package/dist/lib/infrastructure/notification/LarkNotifier.d.ts +24 -0
  101. package/dist/lib/infrastructure/notification/LarkNotifier.js +97 -0
  102. package/dist/lib/infrastructure/report/ReportStore.d.ts +45 -0
  103. package/dist/lib/infrastructure/report/ReportStore.js +133 -0
  104. package/dist/lib/infrastructure/signal/SignalAggregator.d.ts +18 -0
  105. package/dist/lib/infrastructure/signal/SignalAggregator.js +84 -0
  106. package/dist/lib/infrastructure/signal/SignalBridge.d.ts +13 -0
  107. package/dist/lib/infrastructure/signal/SignalBridge.js +20 -0
  108. package/dist/lib/infrastructure/signal/SignalBus.d.ts +63 -0
  109. package/dist/lib/infrastructure/signal/SignalBus.js +106 -0
  110. package/dist/lib/infrastructure/signal/SignalTraceWriter.d.ts +36 -0
  111. package/dist/lib/infrastructure/signal/SignalTraceWriter.js +130 -0
  112. package/dist/lib/injection/ServiceContainer.js +6 -0
  113. package/dist/lib/injection/ServiceMap.d.ts +16 -19
  114. package/dist/lib/injection/modules/AgentModule.d.ts +1 -1
  115. package/dist/lib/injection/modules/AgentModule.js +7 -1
  116. package/dist/lib/injection/modules/AppModule.d.ts +3 -4
  117. package/dist/lib/injection/modules/AppModule.js +7 -43
  118. package/dist/lib/injection/modules/GuardModule.js +59 -2
  119. package/dist/lib/injection/modules/InfraModule.d.ts +0 -1
  120. package/dist/lib/injection/modules/InfraModule.js +9 -7
  121. package/dist/lib/injection/modules/KnowledgeModule.js +51 -0
  122. package/dist/lib/injection/modules/PanoramaModule.d.ts +18 -0
  123. package/dist/lib/injection/modules/PanoramaModule.js +76 -0
  124. package/dist/lib/injection/modules/SignalModule.d.ts +10 -0
  125. package/dist/lib/injection/modules/SignalModule.js +84 -0
  126. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +1 -0
  127. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +6 -0
  128. package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +3 -1
  129. package/dist/lib/service/bootstrap/BootstrapTaskManager.js +20 -1
  130. package/dist/lib/service/delivery/AgentInstructionsGenerator.js +4 -5
  131. package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +3 -1
  132. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +13 -10
  133. package/dist/lib/service/delivery/RulesGenerator.js +3 -2
  134. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +114 -0
  135. package/dist/lib/service/evolution/ConsolidationAdvisor.js +542 -0
  136. package/dist/lib/service/evolution/ContradictionDetector.d.ts +54 -0
  137. package/dist/lib/service/evolution/ContradictionDetector.js +253 -0
  138. package/dist/lib/service/evolution/DecayDetector.d.ts +71 -0
  139. package/dist/lib/service/evolution/DecayDetector.js +244 -0
  140. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +38 -0
  141. package/dist/lib/service/evolution/EnhancementSuggester.js +220 -0
  142. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +82 -0
  143. package/dist/lib/service/evolution/KnowledgeMetabolism.js +167 -0
  144. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +53 -0
  145. package/dist/lib/service/evolution/RedundancyAnalyzer.js +210 -0
  146. package/dist/lib/service/evolution/StagingManager.d.ts +57 -0
  147. package/dist/lib/service/evolution/StagingManager.js +201 -0
  148. package/dist/lib/service/guard/ComplianceReporter.d.ts +42 -2
  149. package/dist/lib/service/guard/ComplianceReporter.js +43 -5
  150. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +54 -0
  151. package/dist/lib/service/guard/CoverageAnalyzer.js +149 -0
  152. package/dist/lib/service/guard/GuardCheckEngine.d.ts +55 -1
  153. package/dist/lib/service/guard/GuardCheckEngine.js +508 -15
  154. package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -0
  155. package/dist/lib/service/guard/GuardFeedbackLoop.js +9 -0
  156. package/dist/lib/service/guard/ReverseGuard.d.ts +73 -0
  157. package/dist/lib/service/guard/ReverseGuard.js +256 -0
  158. package/dist/lib/service/guard/RuleLearner.d.ts +12 -0
  159. package/dist/lib/service/guard/RuleLearner.js +38 -0
  160. package/dist/lib/service/guard/UncertaintyCollector.d.ts +83 -0
  161. package/dist/lib/service/guard/UncertaintyCollector.js +149 -0
  162. package/dist/lib/service/guard/ViolationsStore.d.ts +1 -0
  163. package/dist/lib/service/guard/ViolationsStore.js +33 -3
  164. package/dist/lib/service/knowledge/ConfidenceRouter.d.ts +13 -0
  165. package/dist/lib/service/knowledge/ConfidenceRouter.js +14 -0
  166. package/dist/lib/service/knowledge/KnowledgeService.js +22 -4
  167. package/dist/lib/service/module/ModuleService.js +3 -13
  168. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +27 -0
  169. package/dist/lib/service/panorama/CouplingAnalyzer.js +192 -0
  170. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +28 -0
  171. package/dist/lib/service/panorama/DimensionAnalyzer.js +320 -0
  172. package/dist/lib/service/panorama/LayerInferrer.d.ts +19 -0
  173. package/dist/lib/service/panorama/LayerInferrer.js +182 -0
  174. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +24 -0
  175. package/dist/lib/service/panorama/ModuleDiscoverer.js +185 -0
  176. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +29 -0
  177. package/dist/lib/service/panorama/PanoramaAggregator.js +228 -0
  178. package/dist/lib/service/panorama/PanoramaScanner.d.ts +52 -0
  179. package/dist/lib/service/panorama/PanoramaScanner.js +188 -0
  180. package/dist/lib/service/panorama/PanoramaService.d.ts +108 -0
  181. package/dist/lib/service/panorama/PanoramaService.js +220 -0
  182. package/dist/lib/service/panorama/PanoramaTypes.d.ts +134 -0
  183. package/dist/lib/service/panorama/PanoramaTypes.js +6 -0
  184. package/dist/lib/service/panorama/RoleRefiner.d.ts +48 -0
  185. package/dist/lib/service/panorama/RoleRefiner.js +535 -0
  186. package/dist/lib/service/search/MultiSignalRanker.d.ts +1 -0
  187. package/dist/lib/service/search/MultiSignalRanker.js +16 -0
  188. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  189. package/dist/lib/service/search/SearchEngine.js +9 -1
  190. package/dist/lib/service/search/SearchTypes.d.ts +2 -0
  191. package/dist/lib/service/signal/HitRecorder.d.ts +68 -0
  192. package/dist/lib/service/signal/HitRecorder.js +173 -0
  193. package/dist/lib/service/skills/SignalCollector.d.ts +3 -1
  194. package/dist/lib/service/skills/SignalCollector.js +31 -1
  195. package/dist/lib/service/task/IntentExtractor.d.ts +58 -0
  196. package/dist/lib/service/task/IntentExtractor.js +142 -0
  197. package/dist/lib/service/task/PrimeSearchPipeline.d.ts +54 -0
  198. package/dist/lib/service/task/PrimeSearchPipeline.js +98 -0
  199. package/dist/lib/shared/constants.d.ts +0 -15
  200. package/dist/lib/shared/constants.js +0 -10
  201. package/dist/lib/shared/schemas/config.d.ts +4 -1
  202. package/dist/lib/shared/schemas/config.js +8 -1
  203. package/dist/lib/shared/schemas/mcp-tools.d.ts +41 -96
  204. package/dist/lib/shared/schemas/mcp-tools.js +59 -119
  205. package/dist/scripts/analyze-signals.d.ts +20 -0
  206. package/dist/scripts/analyze-signals.js +155 -0
  207. package/dist/scripts/diagnose-mcp.js +1 -1
  208. package/dist/scripts/release.js +2 -10
  209. package/package.json +4 -19
  210. package/skills/autosnippet-devdocs/SKILL.md +11 -8
  211. package/templates/claude-code/hooks/autosnippet-session.sh +10 -15
  212. package/templates/cursor-hooks/hooks/session-start.sh +1 -1
  213. package/templates/instructions/agent-static.md +2 -1
  214. package/templates/instructions/conventions.md +5 -6
  215. package/templates/recipes-setup/README.md +1 -2
  216. package/dashboard/dist/assets/icons-C1dUryS-.js +0 -1
  217. package/dashboard/dist/assets/index-D0whuycy.css +0 -1
  218. package/dashboard/dist/assets/index-DdvZE4Yd.js +0 -128
  219. package/dist/lib/domain/task/Task.d.ts +0 -140
  220. package/dist/lib/domain/task/Task.js +0 -254
  221. package/dist/lib/domain/task/TaskDependency.d.ts +0 -23
  222. package/dist/lib/domain/task/TaskDependency.js +0 -34
  223. package/dist/lib/domain/task/TaskIdGenerator.d.ts +0 -40
  224. package/dist/lib/domain/task/TaskIdGenerator.js +0 -75
  225. package/dist/lib/domain/task/index.d.ts +0 -4
  226. package/dist/lib/domain/task/index.js +0 -4
  227. package/dist/lib/http/routes/snippets.js +0 -49
  228. package/dist/lib/infrastructure/database/migrations/002_add_tasks.d.ts +0 -11
  229. package/dist/lib/infrastructure/database/migrations/002_add_tasks.js +0 -86
  230. package/dist/lib/platform/ClipboardManager.d.ts +0 -24
  231. package/dist/lib/platform/ClipboardManager.js +0 -142
  232. package/dist/lib/platform/NativeUi.d.ts +0 -53
  233. package/dist/lib/platform/NativeUi.js +0 -284
  234. package/dist/lib/platform/ios/index.d.ts +0 -38
  235. package/dist/lib/platform/ios/index.js +0 -42
  236. package/dist/lib/platform/ios/routes/spm.d.ts +0 -9
  237. package/dist/lib/platform/ios/routes/spm.js +0 -371
  238. package/dist/lib/platform/ios/snippet/PlaceholderConverter.d.ts +0 -21
  239. package/dist/lib/platform/ios/snippet/PlaceholderConverter.js +0 -48
  240. package/dist/lib/platform/ios/snippet/XcodeCodec.d.ts +0 -23
  241. package/dist/lib/platform/ios/snippet/XcodeCodec.js +0 -96
  242. package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +0 -56
  243. package/dist/lib/platform/ios/spm/DependencyGraph.js +0 -195
  244. package/dist/lib/platform/ios/spm/PackageSwiftParser.d.ts +0 -69
  245. package/dist/lib/platform/ios/spm/PackageSwiftParser.js +0 -231
  246. package/dist/lib/platform/ios/spm/PathFinder.d.ts +0 -28
  247. package/dist/lib/platform/ios/spm/PathFinder.js +0 -117
  248. package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +0 -44
  249. package/dist/lib/platform/ios/spm/PolicyEngine.js +0 -79
  250. package/dist/lib/platform/ios/spm/SpmHelper.d.ts +0 -102
  251. package/dist/lib/platform/ios/spm/SpmHelper.js +0 -464
  252. package/dist/lib/platform/ios/xcode/HeaderResolver.d.ts +0 -33
  253. package/dist/lib/platform/ios/xcode/HeaderResolver.js +0 -90
  254. package/dist/lib/platform/ios/xcode/SaveEventFilter.d.ts +0 -66
  255. package/dist/lib/platform/ios/xcode/SaveEventFilter.js +0 -142
  256. package/dist/lib/platform/ios/xcode/XcodeAutomation.d.ts +0 -71
  257. package/dist/lib/platform/ios/xcode/XcodeAutomation.js +0 -327
  258. package/dist/lib/platform/ios/xcode/XcodeImportResolver.d.ts +0 -130
  259. package/dist/lib/platform/ios/xcode/XcodeImportResolver.js +0 -404
  260. package/dist/lib/platform/ios/xcode/XcodeIntegration.d.ts +0 -89
  261. package/dist/lib/platform/ios/xcode/XcodeIntegration.js +0 -588
  262. package/dist/lib/platform/ios/xcode/XcodeWriteUtils.d.ts +0 -99
  263. package/dist/lib/platform/ios/xcode/XcodeWriteUtils.js +0 -190
  264. package/dist/lib/repository/task/TaskRepository.impl.d.ts +0 -171
  265. package/dist/lib/repository/task/TaskRepository.impl.js +0 -347
  266. package/dist/lib/service/automation/ActionPipeline.d.ts +0 -34
  267. package/dist/lib/service/automation/ActionPipeline.js +0 -53
  268. package/dist/lib/service/automation/AutomationOrchestrator.d.ts +0 -86
  269. package/dist/lib/service/automation/AutomationOrchestrator.js +0 -57
  270. package/dist/lib/service/automation/ContextCollector.d.ts +0 -24
  271. package/dist/lib/service/automation/ContextCollector.js +0 -35
  272. package/dist/lib/service/automation/DirectiveDetector.d.ts +0 -51
  273. package/dist/lib/service/automation/DirectiveDetector.js +0 -112
  274. package/dist/lib/service/automation/FileWatcher.d.ts +0 -51
  275. package/dist/lib/service/automation/FileWatcher.js +0 -366
  276. package/dist/lib/service/automation/TriggerResolver.d.ts +0 -36
  277. package/dist/lib/service/automation/TriggerResolver.js +0 -62
  278. package/dist/lib/service/automation/handlers/AlinkHandler.d.ts +0 -7
  279. package/dist/lib/service/automation/handlers/AlinkHandler.js +0 -80
  280. package/dist/lib/service/automation/handlers/CreateHandler.d.ts +0 -11
  281. package/dist/lib/service/automation/handlers/CreateHandler.js +0 -170
  282. package/dist/lib/service/automation/handlers/GuardHandler.d.ts +0 -17
  283. package/dist/lib/service/automation/handlers/GuardHandler.js +0 -218
  284. package/dist/lib/service/automation/handlers/HeaderHandler.d.ts +0 -2
  285. package/dist/lib/service/automation/handlers/HeaderHandler.js +0 -32
  286. package/dist/lib/service/automation/handlers/SearchHandler.d.ts +0 -11
  287. package/dist/lib/service/automation/handlers/SearchHandler.js +0 -278
  288. package/dist/lib/service/snippet/SnippetFactory.d.ts +0 -101
  289. package/dist/lib/service/snippet/SnippetFactory.js +0 -145
  290. package/dist/lib/service/snippet/SnippetInstaller.d.ts +0 -91
  291. package/dist/lib/service/snippet/SnippetInstaller.js +0 -276
  292. package/dist/lib/service/snippet/codecs/SnippetCodec.d.ts +0 -44
  293. package/dist/lib/service/snippet/codecs/SnippetCodec.js +0 -35
  294. package/dist/lib/service/snippet/codecs/VSCodeCodec.d.ts +0 -27
  295. package/dist/lib/service/snippet/codecs/VSCodeCodec.js +0 -82
  296. package/dist/lib/service/task/TaskGraphService.d.ts +0 -222
  297. package/dist/lib/service/task/TaskGraphService.js +0 -597
  298. package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +0 -95
  299. package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -298
  300. package/dist/lib/service/task/TaskReadyEngine.d.ts +0 -84
  301. package/dist/lib/service/task/TaskReadyEngine.js +0 -115
  302. package/dist/scripts/build-native-ui.d.ts +0 -3
  303. package/dist/scripts/build-native-ui.js +0 -62
  304. package/dist/scripts/init-snippets.d.ts +0 -30
  305. package/dist/scripts/init-snippets.js +0 -298
  306. package/dist/scripts/install-full.d.ts +0 -7
  307. package/dist/scripts/install-full.js +0 -38
  308. package/resources/native-ui/README.md +0 -29
  309. package/resources/native-ui/combined-window.swift +0 -494
  310. package/resources/native-ui/main.swift +0 -598
  311. package/scripts/postinstall-safe.mjs +0 -89
@@ -10,6 +10,7 @@
10
10
  * bootstrap_dim_files, code_entities
11
11
  * 002: tasks, task_dependencies, task_events
12
12
  * 003: remote_commands
13
+ * 004: evolution_proposals (+ knowledge_entries.staging_deadline)
13
14
  * 内联: remote_state
14
15
  * 内部: schema_migrations
15
16
  */
@@ -77,6 +78,8 @@ export const knowledgeEntries = sqliteTable('knowledge_entries', {
77
78
  publishedBy: text('publishedBy'),
78
79
  // Content hash
79
80
  contentHash: text('contentHash'),
81
+ // M2: Staging support (migration 004)
82
+ stagingDeadline: integer('staging_deadline'),
80
83
  }, (table) => [
81
84
  index('idx_ke3_lifecycle').on(table.lifecycle),
82
85
  index('idx_ke3_language').on(table.language),
@@ -275,75 +278,7 @@ export const codeEntities = sqliteTable('code_entities', {
275
278
  index('idx_ce_superclass').on(table.superclass),
276
279
  ]);
277
280
  // ═══════════════════════════════════════════════════════════════
278
- // 11. tasks任务表 (migration 002)
279
- // ═══════════════════════════════════════════════════════════════
280
- export const tasks = sqliteTable('tasks', {
281
- id: text('id').primaryKey(),
282
- parentId: text('parent_id'),
283
- childSeq: integer('child_seq').default(0),
284
- title: text('title').notNull(),
285
- description: text('description').default(''),
286
- design: text('design').default(''),
287
- acceptance: text('acceptance').default(''),
288
- notes: text('notes').default(''),
289
- status: text('status').notNull().default('open'),
290
- priority: integer('priority').notNull().default(2),
291
- taskType: text('task_type').notNull().default('task'),
292
- closeReason: text('close_reason').default(''),
293
- contentHash: text('content_hash').default(''),
294
- failCount: integer('fail_count').default(0),
295
- lastFailReason: text('last_fail_reason').default(''),
296
- assignee: text('assignee').default(''),
297
- createdBy: text('created_by').default('agent'),
298
- createdAt: integer('created_at').notNull(),
299
- updatedAt: integer('updated_at').notNull(),
300
- closedAt: integer('closed_at'),
301
- metadata: text('metadata').default('{}'),
302
- }, (table) => [
303
- index('idx_tasks_status').on(table.status),
304
- index('idx_tasks_priority').on(table.priority),
305
- index('idx_tasks_parent').on(table.parentId),
306
- index('idx_tasks_type').on(table.taskType),
307
- index('idx_tasks_assignee').on(table.assignee),
308
- index('idx_tasks_created').on(table.createdAt),
309
- index('idx_tasks_hash').on(table.contentHash),
310
- ]);
311
- // ═══════════════════════════════════════════════════════════════
312
- // 12. task_dependencies — 任务依赖表 (migration 002)
313
- // ═══════════════════════════════════════════════════════════════
314
- export const taskDependencies = sqliteTable('task_dependencies', {
315
- id: integer('id').primaryKey({ autoIncrement: true }),
316
- taskId: text('task_id').notNull(),
317
- dependsOnId: text('depends_on_id').notNull(),
318
- depType: text('dep_type').notNull().default('blocks'),
319
- metadata: text('metadata').default('{}'),
320
- createdAt: integer('created_at').notNull(),
321
- createdBy: text('created_by').default('agent'),
322
- }, (table) => [
323
- uniqueIndex('task_dependencies_unique').on(table.taskId, table.dependsOnId, table.depType),
324
- index('idx_td_task').on(table.taskId),
325
- index('idx_td_depends_on').on(table.dependsOnId),
326
- index('idx_td_type').on(table.depType),
327
- ]);
328
- // ═══════════════════════════════════════════════════════════════
329
- // 13. task_events — 任务事件审计表 (migration 002)
330
- // ═══════════════════════════════════════════════════════════════
331
- export const taskEvents = sqliteTable('task_events', {
332
- id: integer('id').primaryKey({ autoIncrement: true }),
333
- taskId: text('task_id').notNull(),
334
- eventType: text('event_type').notNull(),
335
- actor: text('actor').default('agent'),
336
- oldValue: text('old_value'),
337
- newValue: text('new_value'),
338
- comment: text('comment'),
339
- createdAt: integer('created_at').notNull(),
340
- }, (table) => [
341
- index('idx_te_task').on(table.taskId),
342
- index('idx_te_type').on(table.eventType),
343
- index('idx_te_created').on(table.createdAt),
344
- ]);
345
- // ═══════════════════════════════════════════════════════════════
346
- // 14. remote_commands — 远程指令队列 (migration 003)
281
+ // 11. remote_commands远程指令队列 (migration 003)
347
282
  // ═══════════════════════════════════════════════════════════════
348
283
  export const remoteCommands = sqliteTable('remote_commands', {
349
284
  id: text('id').primaryKey(),
@@ -370,3 +305,27 @@ export const remoteState = sqliteTable('remote_state', {
370
305
  value: text('value'),
371
306
  updatedAt: integer('updated_at'),
372
307
  });
308
+ // ═══════════════════════════════════════════════════════════════
309
+ // 16. evolution_proposals — 知识进化提案 (M2 Recipe 治理)
310
+ // ═══════════════════════════════════════════════════════════════
311
+ export const evolutionProposals = sqliteTable('evolution_proposals', {
312
+ id: text('id').primaryKey(),
313
+ type: text('type').notNull(),
314
+ targetRecipeId: text('target_recipe_id').notNull(),
315
+ relatedRecipeIds: text('related_recipe_ids').default('[]'),
316
+ confidence: real('confidence').notNull().default(0),
317
+ source: text('source').notNull(),
318
+ description: text('description').default(''),
319
+ evidence: text('evidence').default('[]'),
320
+ status: text('status').notNull().default('pending'),
321
+ proposedAt: integer('proposed_at').notNull(),
322
+ expiresAt: integer('expires_at').notNull(),
323
+ resolvedAt: integer('resolved_at'),
324
+ resolvedBy: text('resolved_by'),
325
+ resolution: text('resolution'),
326
+ }, (table) => [
327
+ index('idx_ep_status').on(table.status),
328
+ index('idx_ep_target').on(table.targetRecipeId),
329
+ index('idx_ep_expires').on(table.expiresAt),
330
+ index('idx_ep_source').on(table.source),
331
+ ]);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Migration 004 — Evolution Proposals + Staging Support
3
+ *
4
+ * M2 Recipe 治理所需的 schema 扩展:
5
+ * 1. evolution_proposals 表 — 存储进化提案(矛盾/冗余/衰退/增强)
6
+ * 2. knowledge_entries 添加 staging_deadline 列
7
+ */
8
+ export default function migrate(db: import('better-sqlite3').Database): void;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Migration 004 — Evolution Proposals + Staging Support
3
+ *
4
+ * M2 Recipe 治理所需的 schema 扩展:
5
+ * 1. evolution_proposals 表 — 存储进化提案(矛盾/冗余/衰退/增强)
6
+ * 2. knowledge_entries 添加 staging_deadline 列
7
+ */
8
+ export default function migrate(db) {
9
+ db.exec(`
10
+ -- 进化提案表
11
+ CREATE TABLE IF NOT EXISTS evolution_proposals (
12
+ id TEXT PRIMARY KEY,
13
+ type TEXT NOT NULL,
14
+ target_recipe_id TEXT NOT NULL,
15
+ related_recipe_ids TEXT DEFAULT '[]',
16
+ confidence REAL NOT NULL DEFAULT 0,
17
+ source TEXT NOT NULL,
18
+ description TEXT DEFAULT '',
19
+ evidence TEXT DEFAULT '[]',
20
+ status TEXT NOT NULL DEFAULT 'pending',
21
+ proposed_at INTEGER NOT NULL,
22
+ expires_at INTEGER NOT NULL,
23
+ resolved_at INTEGER,
24
+ resolved_by TEXT,
25
+ resolution TEXT,
26
+
27
+ FOREIGN KEY (target_recipe_id) REFERENCES knowledge_entries(id)
28
+ );
29
+
30
+ CREATE INDEX IF NOT EXISTS idx_ep_status ON evolution_proposals(status);
31
+ CREATE INDEX IF NOT EXISTS idx_ep_target ON evolution_proposals(target_recipe_id);
32
+ CREATE INDEX IF NOT EXISTS idx_ep_expires ON evolution_proposals(expires_at);
33
+ CREATE INDEX IF NOT EXISTS idx_ep_source ON evolution_proposals(source);
34
+ `);
35
+ // knowledge_entries 添加 staging_deadline 列(兼容已有数据)
36
+ // 使用 ALTER TABLE — SQLite 不支持 IF NOT EXISTS for columns,需要 try/catch
37
+ try {
38
+ db.exec(`ALTER TABLE knowledge_entries ADD COLUMN staging_deadline INTEGER`);
39
+ }
40
+ catch {
41
+ // 列已存在,忽略
42
+ }
43
+ }
@@ -23,5 +23,7 @@ export declare class Logger {
23
23
  static info(message: string, meta?: Record<string, unknown>): void;
24
24
  static warn(message: string, meta?: Record<string, unknown>): void;
25
25
  static error(message: string, meta?: Record<string, unknown>): void;
26
+ /** 审计日志 — 写入独立 audit.log,不受 LOG_LEVEL 控制 */
27
+ static audit(event: string, meta?: Record<string, unknown>): void;
26
28
  }
27
29
  export default Logger;
@@ -1,6 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import winston from 'winston';
4
+ import pathGuard from '../../shared/PathGuard.js';
4
5
  // Agent 系统相关标签 — 终端高亮显示
5
6
  const AGENT_TAGS = [
6
7
  'AgentRuntime',
@@ -11,7 +12,7 @@ const AGENT_TAGS = [
11
12
  'CircuitBreaker',
12
13
  'EventAggregator',
13
14
  ];
14
- const MUTED_PREFIXES = ['HTTP Request', 'Tool registered:', '📊 性能统计已更新'];
15
+ const MUTED_PREFIXES = ['Tool registered:'];
15
16
  // ANSI 颜色常量 — 保证深色终端可读性
16
17
  const C = {
17
18
  reset: '\x1b[0m',
@@ -33,6 +34,19 @@ const LEVEL_COLORS = {
33
34
  info: C.green,
34
35
  debug: C.blue,
35
36
  };
37
+ /**
38
+ * 静音过滤器(winston format)
39
+ * 通过 transform 返回 false 彻底丢弃匹配消息,避免空行。
40
+ * 注意:printf 返回 '' 并不会被 winston 跳过,Console transport 仍会写 '\n'。
41
+ */
42
+ const muteFilter = winston.format((info) => {
43
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: intentional ANSI escape sequence stripping
44
+ const rawLevel = info.level.replace(/\u001b\[\d+m/g, '');
45
+ if (rawLevel === 'info' && MUTED_PREFIXES.some((p) => info.message.startsWith(p))) {
46
+ return false;
47
+ }
48
+ return info;
49
+ });
36
50
  /**
37
51
  * 精简 Console 格式
38
52
  * - Agent 相关日志: 高亮 cyan/magenta,显示完整信息
@@ -50,10 +64,6 @@ const compactConsoleFormat = winston.format.printf(({ level, message, timestamp,
50
64
  // biome-ignore lint/suspicious/noControlCharactersInRegex: intentional ANSI escape sequence stripping
51
65
  const rawLevel = level.replace(/\u001b\[\d+m/g, ''); // 去 ANSI
52
66
  const lc = LEVEL_COLORS[rawLevel] || C.gray;
53
- // 静音高频噪音日志
54
- if (rawLevel === 'info' && MUTED_PREFIXES.some((p) => message.startsWith(p))) {
55
- return ''; // 返回空字符串会被 winston 跳过
56
- }
57
67
  // 判断是否为 Agent 相关日志
58
68
  const isAgentLog = AGENT_TAGS.some((tag) => message.includes(tag) || message.startsWith(`[${tag}]`));
59
69
  if (isAgentLog) {
@@ -98,7 +108,12 @@ export class Logger {
98
108
  static instance = null;
99
109
  static getInstance(config = {}) {
100
110
  if (!this.instance) {
101
- const logsDir = config.file?.path || './.autosnippet/logs';
111
+ const rawLogsDir = config.file?.path || './.autosnippet/logs';
112
+ // 与 DatabaseConnection 一致:相对路径按 PathGuard.projectRoot 解析,避免 MCP cwd 非项目目录时写到错误位置
113
+ const projectRoot = pathGuard.projectRoot;
114
+ const logsDir = projectRoot && !path.isAbsolute(rawLogsDir)
115
+ ? path.resolve(projectRoot, rawLogsDir)
116
+ : path.resolve(rawLogsDir);
102
117
  // 确保日志目录存在
103
118
  if (!fs.existsSync(logsDir)) {
104
119
  fs.mkdirSync(logsDir, { recursive: true });
@@ -110,7 +125,7 @@ export class Logger {
110
125
  if (config.console !== false && !isMcpMode) {
111
126
  transports.push(new winston.transports.Console({
112
127
  stderrLevels: ['error', 'warn', 'info', 'debug'],
113
- format: winston.format.combine(winston.format.timestamp(), compactConsoleFormat),
128
+ format: winston.format.combine(winston.format.timestamp(), muteFilter(), compactConsoleFormat),
114
129
  }));
115
130
  }
116
131
  // File transports
@@ -124,6 +139,14 @@ export class Logger {
124
139
  filename: path.join(logsDir, 'combined.log'),
125
140
  format: winston.format.json(),
126
141
  }));
142
+ // audit 独立通道 — 不受 LOG_LEVEL 影响,业务关键事件永不丢失
143
+ transports.push(new winston.transports.File({
144
+ filename: path.join(logsDir, 'audit.log'),
145
+ level: 'info',
146
+ format: winston.format.combine(winston.format((info) => {
147
+ return info.audit === true ? info : false;
148
+ })(), winston.format.timestamp(), winston.format.json()),
149
+ }));
127
150
  }
128
151
  this.instance = winston.createLogger({
129
152
  level: logLevel,
@@ -145,5 +168,9 @@ export class Logger {
145
168
  static error(message, meta = {}) {
146
169
  this.getInstance().error(message, meta);
147
170
  }
171
+ /** 审计日志 — 写入独立 audit.log,不受 LOG_LEVEL 控制 */
172
+ static audit(event, meta = {}) {
173
+ this.getInstance().info(event, { ...meta, audit: true });
174
+ }
148
175
  }
149
176
  export default Logger;
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import fs from 'node:fs';
6
6
  import path from 'node:path';
7
+ import pathGuard from '../../shared/PathGuard.js';
7
8
  import Logger from '../logging/Logger.js';
8
9
  export class ErrorTracker {
9
10
  criticalErrors;
@@ -14,7 +15,8 @@ export class ErrorTracker {
14
15
  reportInterval;
15
16
  constructor(options = {}) {
16
17
  this.config = {
17
- logDirectory: options.logDirectory || path.join(process.cwd(), '.autosnippet', 'logs', 'errors'),
18
+ logDirectory: options.logDirectory ||
19
+ path.join(pathGuard.projectRoot ?? process.cwd(), '.autosnippet', 'logs', 'errors'),
18
20
  maxErrorsInMemory: options.maxErrorsInMemory || 500,
19
21
  enableFileLogging: options.enableFileLogging !== false,
20
22
  enableConsoleLogging: options.enableConsoleLogging !== false,
@@ -56,8 +56,8 @@ export declare class PerformanceMonitor {
56
56
  }, next: () => void) => void;
57
57
  /** 记录请求 */
58
58
  recordRequest(requestData: RequestData): void;
59
- /** 计算统计数据 */
60
- calculateStats(): void;
59
+ /** 计算统计数据。silent=true 时不输出日志(定时器调用) */
60
+ calculateStats(silent?: boolean): void;
61
61
  /** 获取统计信息 */
62
62
  getStats(): {
63
63
  summary: {
@@ -27,7 +27,7 @@ export class PerformanceMonitor {
27
27
  maxSlowRequests: 100, // 最多保留慢请求数
28
28
  };
29
29
  // 定期计算统计数据(unref 避免阻止进程退出)
30
- this.statsInterval = setInterval(() => this.calculateStats(), 30000);
30
+ this.statsInterval = setInterval(() => this.calculateStats(true), 30000);
31
31
  if (this.statsInterval.unref) {
32
32
  this.statsInterval.unref();
33
33
  }
@@ -117,8 +117,8 @@ export class PerformanceMonitor {
117
117
  Logger.warn(`🐢 慢请求: ${route} - ${duration}ms`);
118
118
  }
119
119
  }
120
- /** 计算统计数据 */
121
- calculateStats() {
120
+ /** 计算统计数据。silent=true 时不输出日志(定时器调用) */
121
+ calculateStats(silent = false) {
122
122
  const { total, errors } = this.metrics.requests;
123
123
  // 错误率
124
124
  this.metrics.errorRate = total > 0 ? ((errors / total) * 100).toFixed(2) : 0;
@@ -138,13 +138,15 @@ export class PerformanceMonitor {
138
138
  this.metrics.p95 = sorted[p95Index] || 0;
139
139
  this.metrics.p99 = sorted[p99Index] || 0;
140
140
  }
141
- Logger.info('📊 性能统计已更新', {
142
- requests: total,
143
- errors,
144
- errorRate: `${this.metrics.errorRate}%`,
145
- avgResponseTime: `${this.metrics.averageResponseTime}ms`,
146
- rpm: this.metrics.rpm,
147
- });
141
+ if (!silent) {
142
+ Logger.debug('📊 性能统计已更新', {
143
+ requests: total,
144
+ errors,
145
+ errorRate: `${this.metrics.errorRate}%`,
146
+ avgResponseTime: `${this.metrics.averageResponseTime}ms`,
147
+ rpm: this.metrics.rpm,
148
+ });
149
+ }
148
150
  }
149
151
  /** 获取统计信息 */
150
152
  getStats() {
@@ -0,0 +1,24 @@
1
+ /**
2
+ * LarkNotifier — Lark notification transport
3
+ *
4
+ * Extracted from task.ts. Sends task progress notifications via API Server → Lark.
5
+ * All methods are non-blocking and fire-and-forget.
6
+ *
7
+ * @module infrastructure/notification/LarkNotifier
8
+ */
9
+ interface NotifyArgs {
10
+ id?: string;
11
+ title?: string;
12
+ reason?: string;
13
+ [key: string]: unknown;
14
+ }
15
+ interface NotifyResult {
16
+ success: boolean;
17
+ data?: unknown;
18
+ }
19
+ /**
20
+ * Send task progress notification to Lark (async, non-blocking).
21
+ * Fire-and-forget — failures are logged to stderr but never throw.
22
+ */
23
+ export declare function notifyTaskProgress(operation: string, args: NotifyArgs, result: NotifyResult): Promise<void>;
24
+ export {};
@@ -0,0 +1,97 @@
1
+ /**
2
+ * LarkNotifier — Lark notification transport
3
+ *
4
+ * Extracted from task.ts. Sends task progress notifications via API Server → Lark.
5
+ * All methods are non-blocking and fire-and-forget.
6
+ *
7
+ * @module infrastructure/notification/LarkNotifier
8
+ */
9
+ // ── Internal Transport ──────────────────────────────
10
+ async function sendLarkViaApi(text) {
11
+ try {
12
+ const port = process.env.PORT || 3000;
13
+ const resp = await fetch(`http://localhost:${port}/api/v1/remote/notify`, {
14
+ method: 'POST',
15
+ headers: { 'Content-Type': 'application/json' },
16
+ body: JSON.stringify({ text }),
17
+ signal: AbortSignal.timeout(5000),
18
+ });
19
+ if (!resp.ok) {
20
+ process.stderr.write(`[LarkNotifier] HTTP ${resp.status}\n`);
21
+ return false;
22
+ }
23
+ const body = (await resp.json());
24
+ return body.success === true;
25
+ }
26
+ catch (err) {
27
+ process.stderr.write(`[LarkNotifier] notify failed: ${err instanceof Error ? err.message : String(err)}\n`);
28
+ return false;
29
+ }
30
+ }
31
+ async function sendScreenshotViaApi(caption = '') {
32
+ try {
33
+ const port = process.env.PORT || 3000;
34
+ const resp = await fetch(`http://localhost:${port}/api/v1/remote/screenshot`, {
35
+ method: 'POST',
36
+ headers: { 'Content-Type': 'application/json' },
37
+ body: JSON.stringify({ caption }),
38
+ signal: AbortSignal.timeout(15000),
39
+ });
40
+ if (!resp.ok) {
41
+ process.stderr.write(`[LarkNotifier] Screenshot HTTP ${resp.status}\n`);
42
+ return false;
43
+ }
44
+ const body = (await resp.json());
45
+ return body.success === true;
46
+ }
47
+ catch (err) {
48
+ process.stderr.write(`[LarkNotifier] Screenshot failed: ${err instanceof Error ? err.message : String(err)}\n`);
49
+ return false;
50
+ }
51
+ }
52
+ // ── Public API ──────────────────────────────────────
53
+ /**
54
+ * Send task progress notification to Lark (async, non-blocking).
55
+ * Fire-and-forget — failures are logged to stderr but never throw.
56
+ */
57
+ export async function notifyTaskProgress(operation, args, result) {
58
+ if (!result || result.success === false) {
59
+ return;
60
+ }
61
+ const data = result.data;
62
+ let text = '';
63
+ switch (operation) {
64
+ case 'create': {
65
+ const title = data?.title || args.title || '';
66
+ const id = data?.id || '';
67
+ text = `📋 新任务: ${id}\n${title}`;
68
+ break;
69
+ }
70
+ case 'close': {
71
+ const closed = (data?.closed || data);
72
+ const title = closed?.title || args.title || '';
73
+ const id = closed?.id || args.id;
74
+ const reason = closed?.reason || args.reason || '';
75
+ text = `✅ 完成: ${id}\n${title}\n原因: ${reason}`;
76
+ break;
77
+ }
78
+ case 'fail': {
79
+ const failed = (data?.failed || data);
80
+ const id = failed?.id || args.id;
81
+ const reason = failed?.reason || args.reason || '未知';
82
+ text = `❌ 失败: ${id}\n原因: ${reason}`;
83
+ break;
84
+ }
85
+ case 'record_decision': {
86
+ const title = args.title || '';
87
+ text = `📌 决策: ${title}`;
88
+ break;
89
+ }
90
+ default:
91
+ return;
92
+ }
93
+ if (text) {
94
+ await sendLarkViaApi(text);
95
+ await sendScreenshotViaApi();
96
+ }
97
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * ReportStore — 报告持久化服务
3
+ *
4
+ * 管道产物(governance / compliance / metrics / analysis)写入 JSONL,
5
+ * 供 API 查询历史报告。
6
+ *
7
+ * @module infrastructure/report/ReportStore
8
+ */
9
+ export type ReportCategory = 'governance' | 'compliance' | 'metrics' | 'analysis';
10
+ export interface ReportEntry {
11
+ /** 自动生成 `rpt-{date}-{rand}` */
12
+ id: string;
13
+ category: ReportCategory;
14
+ /** 如 'metabolism_cycle', 'redundancy_report' */
15
+ type: string;
16
+ /** 生产者类名 */
17
+ producer: string;
18
+ data: Record<string, unknown>;
19
+ timestamp: number;
20
+ duration_ms?: number;
21
+ }
22
+ export interface ReportQueryOptions {
23
+ category?: ReportCategory[];
24
+ type?: string;
25
+ from?: number;
26
+ to?: number;
27
+ limit?: number;
28
+ offset?: number;
29
+ }
30
+ export declare class ReportStore {
31
+ #private;
32
+ constructor(baseDir: string);
33
+ /** 写入一条报告(追加 JSONL) */
34
+ write(entry: Omit<ReportEntry, 'id'>): Promise<ReportEntry>;
35
+ /** 查询报告列表 */
36
+ query(opts?: ReportQueryOptions): Promise<{
37
+ reports: ReportEntry[];
38
+ total: number;
39
+ }>;
40
+ /** 分类统计 */
41
+ stats(opts?: {
42
+ from?: number;
43
+ to?: number;
44
+ }): Promise<Record<string, number>>;
45
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * ReportStore — 报告持久化服务
3
+ *
4
+ * 管道产物(governance / compliance / metrics / analysis)写入 JSONL,
5
+ * 供 API 查询历史报告。
6
+ *
7
+ * @module infrastructure/report/ReportStore
8
+ */
9
+ import { randomBytes } from 'node:crypto';
10
+ import fs from 'node:fs';
11
+ import path from 'node:path';
12
+ // ── Constants ───────────────────────────────────────
13
+ const VALID_CATEGORIES = new Set([
14
+ 'governance',
15
+ 'compliance',
16
+ 'metrics',
17
+ 'analysis',
18
+ ]);
19
+ // ── ReportStore ─────────────────────────────────────
20
+ export class ReportStore {
21
+ #baseDir;
22
+ constructor(baseDir) {
23
+ this.#baseDir = baseDir;
24
+ }
25
+ /** 写入一条报告(追加 JSONL) */
26
+ async write(entry) {
27
+ const id = ReportStore.#generateId(entry.timestamp);
28
+ const full = { id, ...entry };
29
+ const filePath = this.#resolveFile(entry.category, entry.timestamp);
30
+ const dir = path.dirname(filePath);
31
+ fs.mkdirSync(dir, { recursive: true });
32
+ fs.appendFileSync(filePath, `${JSON.stringify(full)}\n`, 'utf8');
33
+ return full;
34
+ }
35
+ /** 查询报告列表 */
36
+ async query(opts = {}) {
37
+ const categories = opts.category?.length
38
+ ? opts.category.filter((c) => VALID_CATEGORIES.has(c))
39
+ : [...VALID_CATEGORIES];
40
+ const all = [];
41
+ for (const cat of categories) {
42
+ const catDir = path.join(this.#baseDir, cat);
43
+ if (!fs.existsSync(catDir)) {
44
+ continue;
45
+ }
46
+ const files = fs
47
+ .readdirSync(catDir)
48
+ .filter((f) => f.endsWith('.jsonl'))
49
+ .sort()
50
+ .reverse();
51
+ for (const file of files) {
52
+ const entries = this.#readJsonl(path.join(catDir, file));
53
+ all.push(...entries);
54
+ }
55
+ }
56
+ // 过滤
57
+ let filtered = all;
58
+ if (opts.type) {
59
+ filtered = filtered.filter((e) => e.type === opts.type);
60
+ }
61
+ if (opts.from) {
62
+ filtered = filtered.filter((e) => e.timestamp >= opts.from);
63
+ }
64
+ if (opts.to) {
65
+ filtered = filtered.filter((e) => e.timestamp <= opts.to);
66
+ }
67
+ // 按时间倒序
68
+ filtered.sort((a, b) => b.timestamp - a.timestamp);
69
+ const total = filtered.length;
70
+ const offset = opts.offset ?? 0;
71
+ const limit = opts.limit ?? 20;
72
+ const reports = filtered.slice(offset, offset + limit);
73
+ return { reports, total };
74
+ }
75
+ /** 分类统计 */
76
+ async stats(opts = {}) {
77
+ const result = {};
78
+ for (const cat of VALID_CATEGORIES) {
79
+ const catDir = path.join(this.#baseDir, cat);
80
+ if (!fs.existsSync(catDir)) {
81
+ result[cat] = 0;
82
+ continue;
83
+ }
84
+ const files = fs.readdirSync(catDir).filter((f) => f.endsWith('.jsonl'));
85
+ let count = 0;
86
+ for (const file of files) {
87
+ const entries = this.#readJsonl(path.join(catDir, file));
88
+ for (const e of entries) {
89
+ if (opts.from && e.timestamp < opts.from) {
90
+ continue;
91
+ }
92
+ if (opts.to && e.timestamp > opts.to) {
93
+ continue;
94
+ }
95
+ count++;
96
+ }
97
+ }
98
+ result[cat] = count;
99
+ }
100
+ return result;
101
+ }
102
+ // ── Private ───────────────────────────────────────
103
+ #resolveFile(category, timestamp) {
104
+ const d = new Date(timestamp);
105
+ const dateStr = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
106
+ return path.join(this.#baseDir, category, `${dateStr}.jsonl`);
107
+ }
108
+ #readJsonl(filePath) {
109
+ try {
110
+ const content = fs.readFileSync(filePath, 'utf8');
111
+ const lines = content.split('\n').filter((l) => l.trim());
112
+ const entries = [];
113
+ for (const line of lines) {
114
+ try {
115
+ entries.push(JSON.parse(line));
116
+ }
117
+ catch {
118
+ // 跳过损坏行
119
+ }
120
+ }
121
+ return entries;
122
+ }
123
+ catch {
124
+ return [];
125
+ }
126
+ }
127
+ static #generateId(timestamp) {
128
+ const d = new Date(timestamp);
129
+ const dateStr = `${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}`;
130
+ const rand = randomBytes(4).toString('hex');
131
+ return `rpt-${dateStr}-${rand}`;
132
+ }
133
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * SignalAggregator — 滑窗统计 + 异常检测
3
+ *
4
+ * 订阅可聚合的事实型信号,周期性写入 Report(统计)并在异常时发射 Signal。
5
+ *
6
+ * @module infrastructure/signal/SignalAggregator
7
+ */
8
+ import type { ReportStore } from '../report/ReportStore.js';
9
+ import type { SignalBus } from './SignalBus.js';
10
+ export declare class SignalAggregator {
11
+ #private;
12
+ constructor(signalBus: SignalBus, reportStore: ReportStore, opts?: {
13
+ intervalMs?: number;
14
+ windowMs?: number;
15
+ });
16
+ start(): void;
17
+ stop(): void;
18
+ }