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,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,30 @@
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
+ * 设计文档: docs/copilot/custom-config-discoverer-design.md
15
+ */
16
+ import { type DependencyGraph, type DiscoveredFile, type DiscoveredTarget, ProjectDiscoverer } from './ProjectDiscoverer.js';
17
+ export declare class CustomConfigDiscoverer extends ProjectDiscoverer {
18
+ #private;
19
+ get id(): string;
20
+ get displayName(): string;
21
+ detect(projectRoot: string): Promise<{
22
+ match: boolean;
23
+ confidence: number;
24
+ reason: string;
25
+ }>;
26
+ load(projectRoot: string): Promise<void>;
27
+ listTargets(): Promise<DiscoveredTarget[]>;
28
+ getTargetFiles(target: DiscoveredTarget): Promise<DiscoveredFile[]>;
29
+ getDependencyGraph(): Promise<DependencyGraph>;
30
+ }