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
@@ -1,47 +1,323 @@
1
1
  /**
2
- * MockProvider - 测试用 AI 提供商
3
- * 返回固定/随机数据,不发网络请求
2
+ * MockProvider Smart Mock AI 提供商
3
+ *
4
+ * 不发网络请求,但根据 prompt 内容智能匹配场景,返回符合格式的仿真响应。
5
+ * 用于让用户在没有 API Key 的情况下体验 AutoSnippet 完整工作流。
6
+ *
7
+ * 智能匹配场景:
8
+ * 1. probe / ping → "pong"
9
+ * 2. 重复度检测 (DUPLICATE/SIMILAR/UNIQUE) → "UNIQUE"
10
+ * 3. 对话压缩总结 → 从消息中提取关键词
11
+ * 4. 代码上下文化 (<chunk>) → 从代码提取函数/类名
12
+ * 5. 候选润色 (JSON 9字段) → 原样回传输入字段
13
+ * 6. 维度摘要 (dimensionDigest) → 模板化 JSON
14
+ * 7. 风格检查建议 → 空数组
15
+ * 8. Agent 路由分类 → functionCall classify_intent
16
+ * 9. 通用 fallback → 语义化占位文本
17
+ *
18
+ * 模拟延迟: 50-200ms 随机延迟,营造 "AI 思考" 体验
4
19
  */
5
- import { AiProvider } from '../AiProvider.js';
20
+ import { AiProvider, } from '../AiProvider.js';
21
+ // ── 工具函数 ──────────────────────────────────────────────
22
+ /** 模拟延迟 (50-200ms) */
23
+ function mockDelay() {
24
+ const ms = 50 + Math.floor(Math.random() * 150);
25
+ return new Promise((resolve) => setTimeout(resolve, ms));
26
+ }
27
+ /** 模拟 token 用量 */
28
+ function mockUsage(prompt, response) {
29
+ return {
30
+ inputTokens: Math.ceil(prompt.length / 4),
31
+ outputTokens: Math.ceil(response.length / 4),
32
+ totalTokens: Math.ceil(prompt.length / 4) + Math.ceil(response.length / 4),
33
+ };
34
+ }
35
+ /** 从代码片段中提取函数/类/结构名称 */
36
+ function extractCodeSymbols(code) {
37
+ const symbols = [];
38
+ // Swift/TS class/struct/protocol/enum
39
+ for (const m of code.matchAll(/(?:class|struct|protocol|enum|interface|type)\s+(\w+)/g)) {
40
+ symbols.push(m[1]);
41
+ }
42
+ // func/function
43
+ for (const m of code.matchAll(/(?:func|function)\s+(\w+)/g)) {
44
+ symbols.push(m[1]);
45
+ }
46
+ // property patterns
47
+ for (const m of code.matchAll(/(?:let|var|const)\s+(\w+)/g)) {
48
+ if (m[1].length > 3) {
49
+ symbols.push(m[1]);
50
+ }
51
+ }
52
+ return [...new Set(symbols)].slice(0, 8);
53
+ }
54
+ /** 从 prompt 中尝试提取 JSON 输入(用于润色回传) */
55
+ function extractJsonFromPrompt(prompt) {
56
+ try {
57
+ const match = prompt.match(/\{[\s\S]*?"description"[\s\S]*?\}/);
58
+ if (match) {
59
+ return JSON.parse(match[0]);
60
+ }
61
+ }
62
+ catch {
63
+ /* parse failed */
64
+ }
65
+ return null;
66
+ }
67
+ // ── MockProvider ─────────────────────────────────────────
6
68
  export class MockProvider extends AiProvider {
7
69
  callLog;
8
70
  responses;
9
71
  constructor(config = {}) {
10
72
  super(config);
11
73
  this.name = 'mock';
12
- this.model = 'mock-model';
74
+ this.model = 'mock-smart';
13
75
  this.responses = config.responses || {};
14
76
  this.callLog = [];
15
77
  }
78
+ // ── 核心: chat() 智能路由 ──────────────────────────────
16
79
  async chat(prompt, context = {}) {
17
- this.callLog.push({ method: 'chat', prompt, context });
80
+ this.callLog.push({ method: 'chat', prompt: prompt.slice(0, 200), context });
81
+ await mockDelay();
82
+ // 0. 用户注入的固定响应(单元测试用)
18
83
  if (this.responses.chat) {
19
84
  return this.responses.chat;
20
85
  }
21
- return `Mock response for: ${prompt.slice(0, 80)}`;
86
+ const p = prompt.toLowerCase();
87
+ // 1. Probe / ping
88
+ if (p === 'ping' || p.includes('ping')) {
89
+ return 'pong';
90
+ }
91
+ // 2. 重复度检测 — "请回答: DUPLICATE / SIMILAR / UNIQUE"
92
+ if (p.includes('duplicate') && p.includes('similar') && p.includes('unique')) {
93
+ return 'UNIQUE';
94
+ }
95
+ // 3. 对话压缩总结 — "请用 2-3 句话总结"
96
+ if (p.includes('总结以下对话') || p.includes('summarize the following')) {
97
+ const lines = prompt
98
+ .split('\n')
99
+ .filter((l) => l.startsWith('[user]') || l.startsWith('[assistant]'));
100
+ const topics = lines
101
+ .slice(0, 3)
102
+ .map((l) => l.slice(0, 60))
103
+ .join(';');
104
+ return `[Mock 摘要] 对话涉及: ${topics || '项目开发相关讨论'}。用户和助手讨论了代码实现和架构设计。`;
105
+ }
106
+ // 4. 代码上下文化 — <chunk>...</chunk>
107
+ if (p.includes('<chunk>')) {
108
+ const chunkMatch = prompt.match(/<chunk>([\s\S]*?)<\/chunk>/);
109
+ if (chunkMatch) {
110
+ const symbols = extractCodeSymbols(chunkMatch[1]);
111
+ if (symbols.length > 0) {
112
+ return `This chunk defines ${symbols.slice(0, 3).join(', ')} which handles ${symbols.length > 3 ? symbols.slice(3, 5).join(' and ') : 'core logic'} in the module.`;
113
+ }
114
+ return 'This chunk contains utility code for the module.';
115
+ }
116
+ }
117
+ // 5. 候选润色 — "知识库条目润色助手" + JSON 输出
118
+ if (p.includes('知识库条目润色') || p.includes('润色助手')) {
119
+ const existing = extractJsonFromPrompt(prompt);
120
+ if (existing) {
121
+ return JSON.stringify(existing);
122
+ }
123
+ return JSON.stringify({
124
+ description: '[Mock] 保持原内容不变',
125
+ pattern: '',
126
+ markdown: '',
127
+ rationale: '',
128
+ tags: [],
129
+ confidence: 0.8,
130
+ aiInsight: null,
131
+ agentNotes: null,
132
+ relations: {},
133
+ });
134
+ }
135
+ // 6. 维度摘要 — "dimensionDigest"
136
+ if (p.includes('dimensiondigest') || p.includes('dimension digest')) {
137
+ const dimMatch = prompt.match(/维度[::]\s*["']?(\w[\w-]+)/i) ||
138
+ prompt.match(/dimension[::]\s*["']?(\w[\w-]+)/i);
139
+ const dimId = dimMatch?.[1] || 'unknown';
140
+ const countMatch = prompt.match(/提交了\s*(\d+)\s*个候选/);
141
+ const count = countMatch ? parseInt(countMatch[1], 10) : 3;
142
+ return `\`\`\`json
143
+ ${JSON.stringify({
144
+ dimensionDigest: {
145
+ summary: `[Mock] ${dimId} 维度分析完成,基于项目代码结构生成了 ${count} 个候选知识。`,
146
+ candidateCount: count,
147
+ keyFindings: ['项目采用模块化架构设计', '发现多个核心设计模式', '代码风格整体一致'],
148
+ crossRefs: {},
149
+ gaps: ['部分模块缺少充分的文档注释'],
150
+ remainingTasks: [],
151
+ },
152
+ }, null, 2)}
153
+ \`\`\``;
154
+ }
155
+ // 7. 风格检查建议 — "violation" + "suggestion"
156
+ if (p.includes('violation') && p.includes('suggestion')) {
157
+ return '[]';
158
+ }
159
+ // 8. 分析报告 — "Markdown 格式" + "代码分析报告"
160
+ if (p.includes('代码分析报告') || p.includes('分析报告')) {
161
+ const symbols = extractCodeSymbols(prompt);
162
+ return `## Mock 代码分析报告
163
+
164
+ ### 核心发现
165
+
166
+ 1. **模块结构**: 项目采用分层架构,${symbols.length > 0 ? `核心类型包括 ${symbols.slice(0, 3).join('、')}` : '各模块职责清晰'}
167
+ 2. **设计模式**: 广泛使用协议/接口抽象和依赖注入
168
+ 3. **代码质量**: 类型安全处理规范,错误处理完善
169
+
170
+ ### 文件分析
171
+
172
+ 分析的文件展现了良好的代码组织,模块间通过明确的接口通信。
173
+
174
+ > ⚠️ 此报告由 Mock AI 生成,仅包含模板化分析结果。`;
175
+ }
176
+ // 9. 通用 fallback — 语义化占位
177
+ const symbols = extractCodeSymbols(prompt);
178
+ const topic = symbols.length > 0
179
+ ? `关于 ${symbols.slice(0, 3).join('、')} 的分析`
180
+ : `对 ${prompt.slice(0, 40).replace(/\n/g, ' ')} 的回复`;
181
+ return `[Mock AI] ${topic}。此响应由 Mock 模式生成,非真实 AI 分析结果。`;
182
+ }
183
+ // ── chatWithTools() — 智能函数调用模拟 ─────────────────
184
+ async chatWithTools(prompt, opts = {}) {
185
+ this.callLog.push({
186
+ method: 'chatWithTools',
187
+ prompt: prompt.slice(0, 200),
188
+ toolChoice: opts.toolChoice,
189
+ });
190
+ await mockDelay();
191
+ const schemas = (opts.toolSchemas || []);
192
+ const schemaNames = schemas.map((s) => s.name);
193
+ // toolChoice='none' → 纯文本回复(维度摘要、最终总结等)
194
+ if (opts.toolChoice === 'none') {
195
+ const text = await this.chat(prompt, {
196
+ systemPrompt: opts.systemPrompt,
197
+ temperature: opts.temperature,
198
+ maxTokens: opts.maxTokens,
199
+ });
200
+ return { text, functionCalls: null, usage: mockUsage(prompt, text) };
201
+ }
202
+ // Agent 路由分类 — classify_intent tool
203
+ if (schemaNames.includes('classify_intent')) {
204
+ const response = JSON.stringify({ type: 'general', confidence: 0.9 });
205
+ return {
206
+ text: null,
207
+ functionCalls: [
208
+ {
209
+ id: `mock-fc-${Date.now()}`,
210
+ name: 'classify_intent',
211
+ args: { type: 'general', confidence: 0.9 },
212
+ },
213
+ ],
214
+ usage: mockUsage(prompt, response),
215
+ };
216
+ }
217
+ // 有 tool schemas → 返回文本(让 AgentRuntime 的文本解析处理)
218
+ // Mock 不模拟复杂的多步工具调用链 — bootstrap 走 lightweight pipeline
219
+ if (schemas.length > 0) {
220
+ const text = `[Mock] 我已完成对项目代码的分析。基于代码结构,发现了几个关键的设计模式和架构约定。
221
+
222
+ 以下是主要发现:
223
+ 1. 项目采用模块化分层架构
224
+ 2. 核心模块使用依赖注入模式
225
+ 3. 错误处理遵循统一的类型安全约定
226
+
227
+ > 此分析由 Mock AI 生成,结果基于模板。切换到真实 AI Provider 可获得深度项目分析。`;
228
+ return { text, functionCalls: null, usage: mockUsage(prompt, text) };
229
+ }
230
+ // 无 tools → 纯文本
231
+ const text = await this.chat(prompt, {
232
+ systemPrompt: opts.systemPrompt,
233
+ temperature: opts.temperature,
234
+ maxTokens: opts.maxTokens,
235
+ });
236
+ return { text, functionCalls: null, usage: mockUsage(prompt, text) };
22
237
  }
238
+ // ── chatWithStructuredOutput() — 结构化 JSON 模拟 ──────
239
+ async chatWithStructuredOutput(prompt, opts = {}) {
240
+ this.callLog.push({ method: 'chatWithStructuredOutput', prompt: prompt.slice(0, 200) });
241
+ await mockDelay();
242
+ const p = prompt.toLowerCase();
243
+ // 候选润色 → 尝试回传 prompt 中的 JSON
244
+ if (p.includes('润色') || p.includes('refine')) {
245
+ const existing = extractJsonFromPrompt(prompt);
246
+ if (existing) {
247
+ return existing;
248
+ }
249
+ return {
250
+ description: '[Mock] 保持原内容',
251
+ pattern: '',
252
+ markdown: '',
253
+ rationale: '',
254
+ tags: [],
255
+ confidence: 0.8,
256
+ aiInsight: null,
257
+ agentNotes: null,
258
+ relations: {},
259
+ };
260
+ }
261
+ // 风格检查 → 空数组
262
+ if (opts.openChar === '[' || p.includes('violation')) {
263
+ return [];
264
+ }
265
+ // 通用 → 尝试从 prompt 中提取已有 JSON,否则返回空对象
266
+ const existing = extractJsonFromPrompt(prompt);
267
+ return existing || {};
268
+ }
269
+ // ── summarize() — 代码摘要 ─────────────────────────────
23
270
  async summarize(code) {
24
271
  this.callLog.push({ method: 'summarize', code: code?.slice(0, 80) });
272
+ await mockDelay();
25
273
  if (this.responses.summarize) {
26
274
  return this.responses.summarize;
27
275
  }
276
+ const symbols = extractCodeSymbols(code || '');
277
+ const lang = code?.includes('func ')
278
+ ? 'swift'
279
+ : code?.includes('function ')
280
+ ? 'typescript'
281
+ : code?.includes('def ')
282
+ ? 'python'
283
+ : 'unknown';
28
284
  return {
29
- title: 'Mock Summary',
30
- description: `Summary of ${code?.length || 0} chars`,
31
- language: 'unknown',
32
- patterns: [],
33
- keyAPIs: [],
285
+ title: symbols.length > 0 ? `${symbols[0]} 模块` : 'Mock Summary',
286
+ description: symbols.length > 0
287
+ ? `定义了 ${symbols.slice(0, 3).join('')} 等 ${symbols.length} 个核心类型`
288
+ : `Summary of ${code?.length || 0} chars`,
289
+ language: lang,
290
+ patterns: symbols.slice(0, 3).map((s) => `${s} pattern`),
291
+ keyAPIs: symbols.slice(0, 4),
34
292
  };
35
293
  }
294
+ // ── embed() — 确定性伪向量 ─────────────────────────────
36
295
  async embed(text) {
37
296
  this.callLog.push({ method: 'embed', text: Array.isArray(text) ? text.length : 1 });
297
+ // 使用基于内容的确定性哈希生成向量(相似文本产生相似向量)
38
298
  const dim = 768;
39
- const makeVector = () => Array.from({ length: dim }, () => Math.random() * 2 - 1);
299
+ const makeVector = (input) => {
300
+ let hash = 0;
301
+ for (let i = 0; i < input.length; i++) {
302
+ hash = ((hash << 5) - hash + input.charCodeAt(i)) | 0;
303
+ }
304
+ return Array.from({ length: dim }, (_, i) => {
305
+ // 基于 hash + 位置的伪随机,范围 [-1, 1]
306
+ const x = Math.sin(hash * 0.001 + i * 0.7127) * 43758.5453;
307
+ return (x - Math.floor(x)) * 2 - 1;
308
+ });
309
+ };
40
310
  if (Array.isArray(text)) {
41
- return text.map(() => makeVector());
311
+ return text.map((t) => makeVector(t));
42
312
  }
43
- return makeVector();
313
+ return makeVector(text);
314
+ }
315
+ // ── probe() — 连接检测 ────────────────────────────────
316
+ async probe() {
317
+ this.callLog.push({ method: 'probe' });
318
+ return true;
44
319
  }
320
+ // ── 辅助方法 ──────────────────────────────────────────
45
321
  /** 获取调用日志(测试断言用) */
46
322
  getCalls() {
47
323
  return this.callLog;
@@ -42,6 +42,14 @@ export class OpenAiProvider extends AiProvider {
42
42
  max_tokens: maxTokens,
43
43
  };
44
44
  const data = await this._post(`${this.baseUrl}/chat/completions`, body);
45
+ // 提取 token 用量
46
+ if (data?.usage) {
47
+ this._emitTokenUsage({
48
+ inputTokens: data.usage.prompt_tokens || 0,
49
+ outputTokens: data.usage.completion_tokens || 0,
50
+ totalTokens: data.usage.total_tokens || 0,
51
+ });
52
+ }
45
53
  return data?.choices?.[0]?.message?.content || '';
46
54
  });
47
55
  }
@@ -197,6 +205,14 @@ export class OpenAiProvider extends AiProvider {
197
205
  response_format: { type: 'json_object' },
198
206
  };
199
207
  const data = await this._post(`${this.baseUrl}/chat/completions`, body);
208
+ // 提取 token 用量
209
+ if (data?.usage) {
210
+ this._emitTokenUsage({
211
+ inputTokens: data.usage.prompt_tokens || 0,
212
+ outputTokens: data.usage.completion_tokens || 0,
213
+ totalTokens: data.usage.total_tokens || 0,
214
+ });
215
+ }
200
216
  const text = data?.choices?.[0]?.message?.content || '';
201
217
  if (!text) {
202
218
  return null;
@@ -21,6 +21,10 @@ import type { AgentRuntime } from '#agent/AgentRuntime.js';
21
21
  interface AgentFactory {
22
22
  createLark(opts: RuntimeOverrides): AgentRuntime;
23
23
  createRemoteExec(opts: RuntimeOverrides): AgentRuntime;
24
+ getAiProviderInfo(): {
25
+ name: string;
26
+ model?: string;
27
+ };
24
28
  }
25
29
  interface RuntimeOverrides {
26
30
  lang?: string;
@@ -34,7 +38,7 @@ interface ProgressEvent {
34
38
  interface LarkTransportConfig {
35
39
  agentFactory: AgentFactory;
36
40
  replyFn: (messageId: string, text: string) => Promise<void>;
37
- sendFn: (text: string) => Promise<void | boolean>;
41
+ sendFn: (text: string) => Promise<undefined | boolean>;
38
42
  sendImageFn?: (caption: string) => Promise<{
39
43
  success: boolean;
40
44
  message: string;
@@ -276,6 +276,10 @@ export class LarkTransport {
276
276
  }
277
277
  /** 远程命令执行 — 使用 remote-exec preset(含 SafetyPolicy 命令白名单) */
278
278
  async #handleRemoteExec(command, messageId, chatId, senderId, senderName) {
279
+ if (this.#agentFactory.getAiProviderInfo().name === 'mock') {
280
+ await this.#reply(messageId, '⚠️ AI 服务未配置,当前为 Mock 模式。请先配置 API Key。');
281
+ return;
282
+ }
279
283
  await this.#reply(messageId, `⚡ 正在执行: \`${command.slice(0, 60)}\`...`);
280
284
  try {
281
285
  const history = this.#getHistory(chatId);
@@ -316,6 +320,10 @@ export class LarkTransport {
316
320
  }
317
321
  /** Bot Agent 知识任务 — 服务端 AgentRuntime 直接处理 */
318
322
  async #handleBotAgent(text, messageId, chatId, senderId, senderName) {
323
+ if (this.#agentFactory.getAiProviderInfo().name === 'mock') {
324
+ await this.#reply(messageId, '⚠️ AI 服务未配置,当前为 Mock 模式。请先配置 API Key。');
325
+ return;
326
+ }
319
327
  // 进度提示
320
328
  await this.#reply(messageId, '🤔 正在思考...');
321
329
  try {
@@ -453,8 +461,8 @@ export class LarkTransport {
453
461
  const history = this.#conversationHistory.get(chatId);
454
462
  history.push({ role, content });
455
463
  // 限制内存历史长度
456
- if (history.length > _a.MAX_HISTORY * 2) {
457
- history.splice(0, history.length - _a.MAX_HISTORY * 2);
464
+ if (history?.length > _a.MAX_HISTORY * 2) {
465
+ history?.splice(0, history?.length - _a.MAX_HISTORY * 2);
458
466
  }
459
467
  }
460
468
  // ═══════════════════════════════════════════════════
@@ -36,7 +36,9 @@ import * as systemHandlers from './handlers/system.js';
36
36
  // ─── External Agent Bootstrap 新 handler ──────────────────────
37
37
  import { bootstrapExternal } from './handlers/bootstrap-external.js';
38
38
  import { dimensionComplete } from './handlers/dimension-complete-external.js';
39
+ import { evolveExternal } from './handlers/evolve-external.js';
39
40
  import { panoramaHandler } from './handlers/panorama.js';
41
+ import { rescanExternal } from './handlers/rescan-external.js';
40
42
  import { taskHandler } from './handlers/task.js';
41
43
  import { wikiRouter } from './handlers/wiki-external.js';
42
44
  // ─── McpServer 类 ─────────────────────────────────────────────
@@ -363,6 +365,8 @@ export class McpServer {
363
365
  autosnippet_panorama: (ctx, args) => panoramaHandler(ctx, args),
364
366
  // ── External Agent Bootstrap (v3.1) ──
365
367
  autosnippet_bootstrap: (ctx, _args) => bootstrapExternal(ctx),
368
+ autosnippet_rescan: (ctx, args) => rescanExternal(ctx, args),
369
+ autosnippet_evolve: (ctx, args) => evolveExternal(ctx, args),
366
370
  autosnippet_dimension_complete: (ctx, args) => dimensionComplete(ctx, args),
367
371
  autosnippet_wiki: (ctx, args) => wikiRouter(ctx, args),
368
372
  // ── Admin 层 (+4) ──
@@ -6,6 +6,6 @@
6
6
  * - 文件名 → 分析优先级推断
7
7
  */
8
8
  /** 根据 Target 名称推断模块职责 */
9
- export declare function inferTargetRole(targetName: string): "model" | "config" | "networking" | "ui" | "service" | "auth" | "core" | "storage" | "test" | "app" | "routing" | "utility" | "feature";
9
+ export declare function inferTargetRole(targetName: string): "model" | "config" | "networking" | "ui" | "core" | "app" | "service" | "storage" | "feature" | "test" | "auth" | "routing" | "utility";
10
10
  /** 根据文件名推断分析优先级 */
11
11
  export declare function inferFilePriority(filename: string): "high" | "medium" | "low";
@@ -15,18 +15,10 @@
15
15
  * @module bootstrap/BootstrapSession
16
16
  */
17
17
  import { SessionStore } from '#agent/memory/SessionStore.js';
18
+ import type { DimensionDef } from '#types/project-snapshot.js';
19
+ import type { SessionCacheShape } from '#types/snapshot-views.js';
18
20
  import type { DimensionQualityReport } from './ExternalSubmissionTracker.js';
19
21
  import { ExternalSubmissionTracker } from './ExternalSubmissionTracker.js';
20
- /** 维度定义 */
21
- export interface DimensionDef {
22
- id: string;
23
- label?: string;
24
- skillWorthy?: boolean;
25
- skillMeta?: {
26
- name?: string;
27
- description?: string;
28
- };
29
- }
30
22
  /** Bootstrap 会话构造参数 */
31
23
  interface BootstrapSessionOpts {
32
24
  projectRoot: string;
@@ -61,7 +53,7 @@ export declare class BootstrapSession {
61
53
  completedDimensions: Map<string, DimensionCompletion>;
62
54
  crossDimensionHints: Record<string, CrossDimensionHint[]>;
63
55
  dimensions: DimensionDef[];
64
- phaseCache: Record<string, unknown> | null;
56
+ snapshotCache: SessionCacheShape | null;
65
57
  sessionStore: SessionStore;
66
58
  submissionTracker: ExternalSubmissionTracker;
67
59
  /**
@@ -101,12 +93,12 @@ export declare class BootstrapSession {
101
93
  */
102
94
  getAccumulatedHints(): Record<string, CrossDimensionHint[]>;
103
95
  /**
104
- * 缓存 Phase 1-4 分析结果
105
- * @param cache { files, astData, entityGraph, depGraph, guardFindings, skills, ... }
96
+ * 缓存 Phase 1-4 分析结果(ProjectSnapshot 的 session cache 形式)
97
+ * @param cache toSessionCache(snapshot) 的返回值
106
98
  */
107
- setPhaseCache(cache: Record<string, unknown> | null): void;
108
- /** 获取 Phase 缓存(wiki_plan 复用) */
109
- getPhaseCache(): Record<string, unknown> | null;
99
+ setSnapshotCache(cache: SessionCacheShape | null): void;
100
+ /** 获取 Snapshot 缓存(wiki_plan / dimension-complete 复用) */
101
+ getSnapshotCache(): SessionCacheShape | null;
110
102
  toJSON(): {
111
103
  id: string;
112
104
  projectRoot: string;
@@ -29,7 +29,7 @@ export class BootstrapSession {
29
29
  completedDimensions;
30
30
  crossDimensionHints;
31
31
  dimensions;
32
- phaseCache;
32
+ snapshotCache;
33
33
  sessionStore;
34
34
  submissionTracker;
35
35
  /**
@@ -46,7 +46,7 @@ export class BootstrapSession {
46
46
  /** 外部 Agent 提交追踪 (v2: 对标内部 Agent 的 EvidenceCollector) */
47
47
  this.submissionTracker = new ExternalSubmissionTracker();
48
48
  /** Phase 1-4 分析结果缓存,供 wiki_plan 复用 */
49
- this.phaseCache = null;
49
+ this.snapshotCache = null;
50
50
  /** 跨维度 hints 收集 */
51
51
  this.crossDimensionHints = {}; // targetDimId → [{ fromDim, hint }]
52
52
  this._activeSession = null;
@@ -136,17 +136,17 @@ export class BootstrapSession {
136
136
  }
137
137
  return accumulated;
138
138
  }
139
- // ── Phase 缓存 ────────────────────────────────────────────
139
+ // ── Snapshot 缓存 ──────────────────────────────────────────
140
140
  /**
141
- * 缓存 Phase 1-4 分析结果
142
- * @param cache { files, astData, entityGraph, depGraph, guardFindings, skills, ... }
141
+ * 缓存 Phase 1-4 分析结果(ProjectSnapshot 的 session cache 形式)
142
+ * @param cache toSessionCache(snapshot) 的返回值
143
143
  */
144
- setPhaseCache(cache) {
145
- this.phaseCache = cache;
144
+ setSnapshotCache(cache) {
145
+ this.snapshotCache = cache;
146
146
  }
147
- /** 获取 Phase 缓存(wiki_plan 复用) */
148
- getPhaseCache() {
149
- return this.phaseCache;
147
+ /** 获取 Snapshot 缓存(wiki_plan / dimension-complete 复用) */
148
+ getSnapshotCache() {
149
+ return this.snapshotCache;
150
150
  }
151
151
  // ── 序列化 ────────────────────────────────────────────────
152
152
  toJSON() {
@@ -162,5 +162,12 @@ export declare class ExternalSubmissionTracker {
162
162
  negativeSignals: number;
163
163
  usedTriggers: number;
164
164
  };
165
+ /**
166
+ * 获取所有已提交候选的标题集合(小写,用于跨维度硬去重)
167
+ *
168
+ * @param [excludeDimId] 可选,排除指定维度的标题
169
+ * @returns Set<string> 小写标题集合
170
+ */
171
+ getAllSubmittedTitles(excludeDimId?: string): Set<string>;
165
172
  }
166
173
  export default ExternalSubmissionTracker;
@@ -288,5 +288,25 @@ export class ExternalSubmissionTracker {
288
288
  usedTriggers: this.#usedTriggers.size,
289
289
  };
290
290
  }
291
+ /**
292
+ * 获取所有已提交候选的标题集合(小写,用于跨维度硬去重)
293
+ *
294
+ * @param [excludeDimId] 可选,排除指定维度的标题
295
+ * @returns Set<string> 小写标题集合
296
+ */
297
+ getAllSubmittedTitles(excludeDimId) {
298
+ const titles = new Set();
299
+ for (const [dimId, submissions] of this.#dimensionSubmissions) {
300
+ if (excludeDimId && dimId === excludeDimId) {
301
+ continue;
302
+ }
303
+ for (const sub of submissions) {
304
+ if (sub.title) {
305
+ titles.add(sub.title.toLowerCase().trim());
306
+ }
307
+ }
308
+ }
309
+ return titles;
310
+ }
291
311
  }
292
312
  export default ExternalSubmissionTracker;