autosnippet 3.3.6 → 3.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +1 -0
  2. package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
  3. package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
  4. package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
  5. package/dashboard/dist/index.html +3 -3
  6. package/dist/bin/cli.js +8 -4
  7. package/dist/lib/agent/AgentRuntime.d.ts +2 -2
  8. package/dist/lib/agent/AgentRuntime.js +26 -18
  9. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  10. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  11. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  12. package/dist/lib/agent/domain/ChatAgentTasks.js +4 -0
  13. package/dist/lib/agent/forced-summary.js +7 -2
  14. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  15. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  16. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  17. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  18. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  19. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  20. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  21. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  22. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  23. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  24. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  25. package/dist/lib/agent/memory/SessionStore.js +0 -2
  26. package/dist/lib/agent/tools/ast-graph.js +21 -19
  27. package/dist/lib/agent/tools/infrastructure.js +3 -2
  28. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  29. package/dist/lib/agent/tools/project-access.js +5 -4
  30. package/dist/lib/bootstrap.js +2 -1
  31. package/dist/lib/cli/AiScanService.js +8 -21
  32. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  33. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  34. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  35. package/dist/lib/core/discovery/ConfigWatcher.d.ts +64 -0
  36. package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
  37. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +28 -0
  38. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1303 -0
  39. package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
  40. package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
  41. package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
  42. package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
  43. package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
  44. package/dist/lib/core/discovery/index.d.ts +2 -0
  45. package/dist/lib/core/discovery/index.js +4 -0
  46. package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
  47. package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
  48. package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
  49. package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
  50. package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
  51. package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
  52. package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
  53. package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
  54. package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
  55. package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
  56. package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
  57. package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
  58. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  59. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  60. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  61. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  62. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  63. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +7 -1
  64. package/dist/lib/domain/knowledge/KnowledgeEntry.js +17 -3
  65. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  66. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  67. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  68. package/dist/lib/domain/knowledge/index.js +1 -1
  69. package/dist/lib/external/ai/AiProvider.d.ts +12 -0
  70. package/dist/lib/external/ai/AiProvider.js +24 -0
  71. package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
  72. package/dist/lib/external/ai/AiProviderManager.js +193 -0
  73. package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
  74. package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
  75. package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
  76. package/dist/lib/external/ai/providers/MockProvider.js +290 -14
  77. package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
  78. package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
  79. package/dist/lib/external/lark/LarkTransport.js +10 -2
  80. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  81. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  82. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.d.ts +20 -0
  83. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
  84. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -24
  85. package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
  86. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  87. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  88. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +9 -0
  89. package/dist/lib/external/mcp/handlers/bootstrap-external.js +3 -1
  90. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
  91. package/dist/lib/external/mcp/handlers/consolidated.js +2 -1
  92. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +9 -4
  93. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  94. package/dist/lib/external/mcp/handlers/evolve-external.js +18 -18
  95. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  96. package/dist/lib/external/mcp/handlers/knowledge.js +5 -4
  97. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  98. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  99. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  100. package/dist/lib/external/mcp/handlers/search.js +3 -1
  101. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  102. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  103. package/dist/lib/external/mcp/handlers/system.js +10 -34
  104. package/dist/lib/http/routes/ai.js +109 -30
  105. package/dist/lib/http/routes/candidates.js +11 -4
  106. package/dist/lib/http/routes/commands.js +10 -1
  107. package/dist/lib/http/routes/guardReport.js +3 -5
  108. package/dist/lib/http/routes/health.js +11 -0
  109. package/dist/lib/http/routes/modules.js +27 -0
  110. package/dist/lib/http/routes/panorama.js +12 -12
  111. package/dist/lib/http/routes/recipes.js +66 -8
  112. package/dist/lib/http/routes/remote.js +3 -13
  113. package/dist/lib/http/routes/search.js +11 -8
  114. package/dist/lib/http/utils/routeHelpers.js +2 -1
  115. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  116. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  117. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  118. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  119. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  120. package/dist/lib/injection/ServiceContainer.d.ts +6 -5
  121. package/dist/lib/injection/ServiceContainer.js +18 -31
  122. package/dist/lib/injection/ServiceMap.d.ts +22 -0
  123. package/dist/lib/injection/modules/AiModule.d.ts +6 -9
  124. package/dist/lib/injection/modules/AiModule.js +82 -39
  125. package/dist/lib/injection/modules/AppModule.js +2 -1
  126. package/dist/lib/injection/modules/GuardModule.js +5 -5
  127. package/dist/lib/injection/modules/InfraModule.js +60 -0
  128. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  129. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  130. package/dist/lib/injection/modules/VectorModule.js +3 -0
  131. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  132. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  133. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  134. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  135. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  136. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  137. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  138. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  139. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  140. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  141. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  142. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  143. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  144. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  145. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  146. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  147. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  148. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  149. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  150. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  151. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  152. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  153. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  154. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  155. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  156. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  157. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  158. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  159. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  160. package/dist/lib/repository/session/SessionRepository.js +110 -0
  161. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  162. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  163. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  164. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  165. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  166. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  167. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  168. package/dist/lib/service/cleanup/CleanupService.d.ts +54 -7
  169. package/dist/lib/service/cleanup/CleanupService.js +291 -40
  170. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
  171. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  172. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  173. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  174. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  175. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  176. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  177. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  178. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  179. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  180. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  181. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  182. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  183. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  184. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  185. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  186. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  187. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  188. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  189. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  190. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  191. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  192. package/dist/lib/service/evolution/StagingManager.js +37 -95
  193. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  194. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  195. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  196. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  197. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  198. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  199. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  200. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  201. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  202. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  203. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +45 -63
  204. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -496
  205. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  206. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  207. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  208. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  209. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  210. package/dist/lib/service/knowledge/KnowledgeService.js +97 -46
  211. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  212. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  213. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  214. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  215. package/dist/lib/service/module/ModuleService.js +10 -19
  216. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +14 -3
  217. package/dist/lib/service/panorama/CouplingAnalyzer.js +137 -32
  218. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  219. package/dist/lib/service/panorama/DimensionAnalyzer.js +94 -33
  220. package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
  221. package/dist/lib/service/panorama/LayerInferrer.js +118 -1
  222. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +14 -4
  223. package/dist/lib/service/panorama/ModuleDiscoverer.js +209 -61
  224. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +15 -4
  225. package/dist/lib/service/panorama/PanoramaAggregator.js +128 -62
  226. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  227. package/dist/lib/service/panorama/PanoramaScanner.js +60 -31
  228. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  229. package/dist/lib/service/panorama/PanoramaService.js +49 -69
  230. package/dist/lib/service/panorama/PanoramaTypes.d.ts +41 -0
  231. package/dist/lib/service/panorama/RoleRefiner.d.ts +10 -5
  232. package/dist/lib/service/panorama/RoleRefiner.js +92 -282
  233. package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
  234. package/dist/lib/service/panorama/TechStackProfiler.js +79 -0
  235. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  236. package/dist/lib/service/quality/QualityScorer.js +157 -83
  237. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  238. package/dist/lib/service/search/SearchEngine.js +32 -37
  239. package/dist/lib/service/signal/HitRecorder.js +5 -5
  240. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  241. package/dist/lib/service/skills/SignalCollector.d.ts +6 -8
  242. package/dist/lib/service/skills/SignalCollector.js +34 -60
  243. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  244. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  245. package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
  246. package/dist/lib/service/vector/ContextualEnricher.js +4 -0
  247. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  248. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  249. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  250. package/dist/lib/service/vector/VectorService.js +3 -0
  251. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  252. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  253. package/dist/lib/shared/LanguageProfiles.js +939 -0
  254. package/dist/lib/shared/LanguageService.d.ts +6 -0
  255. package/dist/lib/shared/LanguageService.js +19 -0
  256. package/dist/lib/shared/constants.d.ts +19 -19
  257. package/dist/lib/shared/constants.js +10 -10
  258. package/dist/lib/shared/developer-identity.d.ts +18 -0
  259. package/dist/lib/shared/developer-identity.js +62 -0
  260. package/dist/lib/shared/schemas/http-requests.d.ts +8 -17
  261. package/dist/lib/shared/schemas/http-requests.js +9 -6
  262. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  263. package/dist/lib/types/knowledge-wire.d.ts +1 -0
  264. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  265. package/dist/lib/types/project-snapshot-builder.js +0 -1
  266. package/dist/lib/types/project-snapshot.d.ts +0 -1
  267. package/dist/lib/types/project-snapshot.js +0 -1
  268. package/dist/lib/types/snapshot-views.d.ts +0 -2
  269. package/dist/lib/types/snapshot-views.js +0 -1
  270. package/package.json +2 -1
  271. package/dashboard/dist/assets/icons-D1aVZYFW.js +0 -1
  272. package/dashboard/dist/assets/index-CxHOu8Hd.css +0 -1
  273. package/dashboard/dist/assets/index-DDdAOpYT.js +0 -128
  274. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  275. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -0,0 +1,336 @@
1
+ /**
2
+ * ConfigWatcher — 构建配置文件热更新监听器
3
+ *
4
+ * 监听自研构建系统的配置文件变更,执行增量重解析并通知下游服务。
5
+ *
6
+ * 核心策略:
7
+ * - debounce 3s(配置文件常有连续保存)
8
+ * - MD5 hash 差量检测避免无效重解析
9
+ * - 60s 最大频率保护(防 git checkout 等批量变更风暴)
10
+ * - 增量解析:单文件变更只影响对应模块
11
+ * - 通过 SignalBus 触发 PanoramaService 缓存失效
12
+ * - 通过 RealtimeService 推送 Dashboard WebSocket 事件
13
+ *
14
+ * @module ConfigWatcher
15
+ */
16
+ import { createHash } from 'node:crypto';
17
+ import { watch } from 'node:fs';
18
+ import { glob, readFile } from 'node:fs/promises';
19
+ import { join, relative } from 'node:path';
20
+ import { shutdown } from '#shared/shutdown.js';
21
+ /* ═══ Types ═══════════════════════════════════════════════ */
22
+ /** 配置文件系统类型 → 需要监听的文件 glob 列表 */
23
+ const WATCH_PATTERNS = {
24
+ easybox: ['Boxfile', 'Boxfile.local', 'Boxfile.overlay', 'LocalModule/**/*.boxspec'],
25
+ tuist: ['Project.swift', 'Tuist/**/*.swift'],
26
+ xcodegen: ['project.yml', 'project.yaml'],
27
+ };
28
+ /* ═══ ConfigWatcher ═══════════════════════════════════════ */
29
+ export class ConfigWatcher {
30
+ #projectRoot;
31
+ #systemId;
32
+ #signalBus;
33
+ #onChange;
34
+ #debounceMs;
35
+ #fullRebuildIntervalMs;
36
+ /** fs.watch 实例列表 */
37
+ #watchers = [];
38
+ /** 已知文件 → hash 映射 */
39
+ #fileHashes = new Map();
40
+ /** debounce 定时器 */
41
+ #debounceTimer = null;
42
+ /** 待处理的变更文件路径(debounce 窗口内合并) */
43
+ #pendingChanges = new Set();
44
+ /** 上次全量重建时间 */
45
+ #lastFullRebuild = 0;
46
+ /** 是否已关闭 */
47
+ #disposed = false;
48
+ constructor(options) {
49
+ this.#projectRoot = options.projectRoot;
50
+ this.#systemId = options.systemId;
51
+ this.#signalBus = options.signalBus ?? null;
52
+ this.#onChange = options.onChange ?? null;
53
+ this.#debounceMs = options.debounceMs ?? 3000;
54
+ this.#fullRebuildIntervalMs = options.fullRebuildIntervalMs ?? 60_000;
55
+ }
56
+ /* ─── Public API ────────────────────────────────── */
57
+ /**
58
+ * 启动文件监听。异步解析初始文件 hash 并注册 fs.watch。
59
+ * 自动注册 shutdown hook 以清理资源。
60
+ */
61
+ async start() {
62
+ if (this.#disposed) {
63
+ return;
64
+ }
65
+ const patterns = WATCH_PATTERNS[this.#systemId] ?? [];
66
+ if (patterns.length === 0) {
67
+ return;
68
+ }
69
+ // 1. 遍历 glob patterns 收集初始文件
70
+ const resolvedFiles = await this.#resolveWatchFiles(patterns);
71
+ // 2. 计算初始 hash
72
+ for (const file of resolvedFiles) {
73
+ const absPath = join(this.#projectRoot, file.relativePath);
74
+ try {
75
+ const content = await readFile(absPath, 'utf-8');
76
+ file.hash = computeHash(content);
77
+ this.#fileHashes.set(file.relativePath, file);
78
+ }
79
+ catch {
80
+ /* 文件可能已删除,跳过 */
81
+ }
82
+ }
83
+ // 3. 对每个 pattern 设置 fs.watch(目录级)
84
+ this.#setupWatchers(patterns);
85
+ // 4. 注册 shutdown hook
86
+ shutdown.register(() => this.dispose(), `ConfigWatcher(${this.#systemId})`);
87
+ }
88
+ /**
89
+ * 停止监听,释放所有 fs.watch 资源
90
+ */
91
+ dispose() {
92
+ if (this.#disposed) {
93
+ return;
94
+ }
95
+ this.#disposed = true;
96
+ if (this.#debounceTimer) {
97
+ clearTimeout(this.#debounceTimer);
98
+ this.#debounceTimer = null;
99
+ }
100
+ for (const watcher of this.#watchers) {
101
+ try {
102
+ watcher.close();
103
+ }
104
+ catch {
105
+ /* 忽略关闭错误 */
106
+ }
107
+ }
108
+ this.#watchers.length = 0;
109
+ this.#pendingChanges.clear();
110
+ this.#fileHashes.clear();
111
+ }
112
+ /** 是否正在监听 */
113
+ get active() {
114
+ return !this.#disposed && this.#watchers.length > 0;
115
+ }
116
+ /** 监听的文件数 */
117
+ get watchedFileCount() {
118
+ return this.#fileHashes.size;
119
+ }
120
+ /* ─── Internal ──────────────────────────────────── */
121
+ /**
122
+ * 解析 glob patterns → WatchedFile 列表
123
+ */
124
+ async #resolveWatchFiles(patterns) {
125
+ const files = [];
126
+ for (const pattern of patterns) {
127
+ const scope = inferChangeScope(pattern, this.#systemId);
128
+ try {
129
+ // Node 22 has native glob in fs/promises
130
+ const matches = glob(pattern, { cwd: this.#projectRoot });
131
+ for await (const match of matches) {
132
+ files.push({
133
+ relativePath: match,
134
+ hash: '',
135
+ scope,
136
+ moduleName: scope === 'module' ? extractModuleName(match, this.#systemId) : undefined,
137
+ });
138
+ }
139
+ }
140
+ catch {
141
+ /* pattern 不匹配或目录不存在 */
142
+ }
143
+ }
144
+ return files;
145
+ }
146
+ /**
147
+ * 设置 fs.watch 监听器
148
+ */
149
+ #setupWatchers(patterns) {
150
+ // 收集要监听的目录(去重)
151
+ const watchDirs = new Set();
152
+ watchDirs.add(this.#projectRoot); // 根目录(Boxfile, project.yml 等)
153
+ for (const pattern of patterns) {
154
+ // 对含 ** 的 pattern,监听其父目录
155
+ const slashIdx = pattern.indexOf('/');
156
+ if (slashIdx > 0) {
157
+ const dir = pattern.substring(0, slashIdx);
158
+ const absDir = join(this.#projectRoot, dir);
159
+ watchDirs.add(absDir);
160
+ }
161
+ }
162
+ for (const dir of watchDirs) {
163
+ try {
164
+ const watcher = watch(dir, { recursive: true }, (_eventType, filename) => {
165
+ if (!filename || this.#disposed) {
166
+ return;
167
+ }
168
+ const relPath = dir === this.#projectRoot ? filename : join(relative(this.#projectRoot, dir), filename);
169
+ // 过滤非配置文件
170
+ if (this.#isRelevantFile(relPath, patterns)) {
171
+ this.#scheduleCheck(relPath);
172
+ }
173
+ });
174
+ this.#watchers.push(watcher);
175
+ // 处理 watcher 错误(macOS 上目录被删除等)
176
+ watcher.on('error', () => {
177
+ /* 静默忽略,下次变更无法检测可通过手动 rescan 恢复 */
178
+ });
179
+ }
180
+ catch {
181
+ /* 目录不存在或权限不足 */
182
+ }
183
+ }
184
+ }
185
+ /**
186
+ * 检查文件路径是否匹配 watch patterns
187
+ */
188
+ #isRelevantFile(relPath, patterns) {
189
+ for (const pattern of patterns) {
190
+ // 简单匹配:精确文件名 / 扩展名 / 子目录包含
191
+ if (!pattern.includes('*') && !pattern.includes('/')) {
192
+ // 精确文件名匹配
193
+ if (relPath === pattern) {
194
+ return true;
195
+ }
196
+ }
197
+ else if (pattern.includes('**')) {
198
+ // glob 通配 — 提取目录前缀和扩展名
199
+ const parts = pattern.split('/');
200
+ const dirPrefix = parts[0];
201
+ const extMatch = pattern.match(/\*(\.\w+)$/);
202
+ if (relPath.startsWith(`${dirPrefix}/`) && extMatch && relPath.endsWith(extMatch[1])) {
203
+ return true;
204
+ }
205
+ }
206
+ }
207
+ return false;
208
+ }
209
+ /**
210
+ * debounce 调度:合并多次变更后统一处理
211
+ */
212
+ #scheduleCheck(relPath) {
213
+ this.#pendingChanges.add(relPath);
214
+ if (this.#debounceTimer) {
215
+ clearTimeout(this.#debounceTimer);
216
+ }
217
+ this.#debounceTimer = setTimeout(() => {
218
+ this.#debounceTimer = null;
219
+ void this.#processChanges();
220
+ }, this.#debounceMs);
221
+ }
222
+ /**
223
+ * 处理 debounce 窗口内累积的变更
224
+ */
225
+ async #processChanges() {
226
+ if (this.#disposed || this.#pendingChanges.size === 0) {
227
+ return;
228
+ }
229
+ // 频率保护:60s 内最多一次全量重建
230
+ const now = Date.now();
231
+ const hasFullScope = [...this.#pendingChanges].some((p) => {
232
+ const watched = this.#fileHashes.get(p);
233
+ return !watched || watched.scope === 'full';
234
+ });
235
+ if (hasFullScope && now - this.#lastFullRebuild < this.#fullRebuildIntervalMs) {
236
+ // 跳过此轮,等待下次
237
+ this.#pendingChanges.clear();
238
+ return;
239
+ }
240
+ const changedPaths = [...this.#pendingChanges];
241
+ this.#pendingChanges.clear();
242
+ // 逐个检查 hash 变化
243
+ const actualChanges = [];
244
+ for (const relPath of changedPaths) {
245
+ const absPath = join(this.#projectRoot, relPath);
246
+ try {
247
+ const content = await readFile(absPath, 'utf-8');
248
+ const newHash = computeHash(content);
249
+ const existing = this.#fileHashes.get(relPath);
250
+ if (existing && existing.hash === newHash) {
251
+ continue; // hash 未变,跳过
252
+ }
253
+ // 更新 hash
254
+ const scope = existing?.scope ?? inferChangeScope(relPath, this.#systemId);
255
+ const moduleName = scope === 'module'
256
+ ? (existing?.moduleName ?? extractModuleName(relPath, this.#systemId))
257
+ : undefined;
258
+ this.#fileHashes.set(relPath, { relativePath: relPath, hash: newHash, scope, moduleName });
259
+ actualChanges.push({ path: relPath, scope, moduleName });
260
+ }
261
+ catch {
262
+ // 文件被删除 — 也算变更
263
+ if (this.#fileHashes.has(relPath)) {
264
+ const existing = this.#fileHashes.get(relPath);
265
+ this.#fileHashes.delete(relPath);
266
+ actualChanges.push({
267
+ path: relPath,
268
+ scope: existing.scope,
269
+ moduleName: existing.moduleName,
270
+ });
271
+ }
272
+ }
273
+ }
274
+ if (actualChanges.length === 0) {
275
+ return; // 所有文件 hash 未变
276
+ }
277
+ if (hasFullScope) {
278
+ this.#lastFullRebuild = now;
279
+ }
280
+ // 发射信号 → PanoramaService 缓存失效
281
+ if (this.#signalBus) {
282
+ this.#signalBus.send('lifecycle', 'ConfigWatcher', 1.0, {
283
+ metadata: {
284
+ event: 'config_changed',
285
+ systemId: this.#systemId,
286
+ changedCount: actualChanges.length,
287
+ },
288
+ });
289
+ }
290
+ // 回调通知(RealtimeService 等)
291
+ const event = {
292
+ changedFiles: actualChanges,
293
+ systemId: this.#systemId,
294
+ timestamp: now,
295
+ };
296
+ this.#onChange?.(event);
297
+ }
298
+ }
299
+ /* ═══ Helpers ═════════════════════════════════════════════ */
300
+ function computeHash(content) {
301
+ return createHash('md5').update(content).digest('hex');
302
+ }
303
+ /**
304
+ * 根据文件 pattern 推断变更影响范围
305
+ */
306
+ function inferChangeScope(pattern, systemId) {
307
+ if (systemId === 'easybox') {
308
+ if (pattern.includes('.boxspec')) {
309
+ return 'module';
310
+ }
311
+ if (pattern.includes('.local') || pattern.includes('.overlay')) {
312
+ return 'overlay';
313
+ }
314
+ return 'full';
315
+ }
316
+ if (systemId === 'tuist') {
317
+ if (pattern.includes('Tuist/')) {
318
+ return 'full';
319
+ }
320
+ return 'full';
321
+ }
322
+ // xcodegen / 其他
323
+ return 'full';
324
+ }
325
+ /**
326
+ * 从文件路径提取模块名
327
+ * e.g. "LocalModule/BDPictures/BDPictures.boxspec" → "BDPictures"
328
+ */
329
+ function extractModuleName(relPath, _systemId) {
330
+ // 通用:取 spec 文件所在目录名
331
+ const parts = relPath.split('/');
332
+ if (parts.length >= 2) {
333
+ return parts[parts.length - 2];
334
+ }
335
+ return undefined;
336
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @module CustomConfigDiscoverer
3
+ * @description 自研配置文件发现器 — 识别使用非标准/自研构建系统的项目
4
+ *
5
+ * 两级检测策略:
6
+ * Level 1: 已知自研工具指纹匹配 (confidence 0.70-0.80)
7
+ * Level 2: 启发式目录结构探测 (confidence 0.50-0.65)
8
+ *
9
+ * 当前支持:
10
+ * - Baidu EasyBox (Boxfile + *.boxspec)
11
+ * - Tuist (Project.swift)
12
+ * - XcodeGen (project.yml)
13
+ */
14
+ import { type DependencyGraph, type DiscoveredFile, type DiscoveredTarget, ProjectDiscoverer } from './ProjectDiscoverer.js';
15
+ export declare class CustomConfigDiscoverer extends ProjectDiscoverer {
16
+ #private;
17
+ get id(): string;
18
+ get displayName(): string;
19
+ detect(projectRoot: string): Promise<{
20
+ match: boolean;
21
+ confidence: number;
22
+ reason: string;
23
+ }>;
24
+ load(projectRoot: string): Promise<void>;
25
+ listTargets(): Promise<DiscoveredTarget[]>;
26
+ getTargetFiles(target: DiscoveredTarget): Promise<DiscoveredFile[]>;
27
+ getDependencyGraph(): Promise<DependencyGraph>;
28
+ }