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
@@ -37,7 +37,7 @@ export async function produceForcedSummary({ aiProvider, source, toolCalls = [],
37
37
  const candidateCount = toolCalls.filter((tc) => tc.tool === 'submit_knowledge' || tc.tool === 'submit_with_check').length;
38
38
  let finalReply;
39
39
  // 如果熔断器已打开,跳过 AI 调用直接合成摘要
40
- const isCircuitOpen = aiProvider._circuitState === 'OPEN';
40
+ const isCircuitOpen = aiProvider._circuitState === 'OPEN' || aiProvider.name === 'mock';
41
41
  if (isCircuitOpen) {
42
42
  const outputType = isAnalyst ? 'analysis' : isSystem ? 'digest' : 'summary';
43
43
  logger.warn(`[ForcedSummary] circuit breaker is OPEN — skipping AI summary, using synthetic ${outputType}`);
@@ -160,7 +160,7 @@ ${toolContextSummary}
160
160
  .slice(0, 8);
161
161
  const classesExplored = toolCalls
162
162
  .filter((tc) => tc.tool === 'get_class_info' || tc.tool === 'get_class_hierarchy')
163
- .map((tc) => (tc.args || tc.params || {}).className)
163
+ .map((tc) => (tc.args || tc.params)?.className)
164
164
  .filter((v) => Boolean(v))
165
165
  .slice(0, 10);
166
166
  finalReply = `## 代码分析报告\n\n通过 **${toolCalls.length} 次工具调用**(${iterations} 轮迭代)探索了项目代码。\n\n`;
@@ -228,6 +228,11 @@ ${toolContextSummary}
228
228
  finalReply += '> ⚠️ AI 服务异常,未能生成完整分析。请稍后重试或缩小分析范围。';
229
229
  }
230
230
  }
231
+ // 兜底: 确保 finalReply 始终非空
232
+ if (!finalReply) {
233
+ logger.warn('[ForcedSummary] ⚠ finalReply is empty after all paths — using fallback');
234
+ finalReply = `## 分析总结\n\n通过 **${toolCalls.length} 次工具调用**探索了项目代码,但未能生成完整分析。请重试或缩小分析范围。`;
235
+ }
231
236
  logger.info(`[ForcedSummary] ✅ forced summary — ${finalReply.length} chars`);
232
237
  return { reply: finalReply, tokenUsage: resultTokenUsage };
233
238
  }
@@ -21,6 +21,7 @@
21
21
  *
22
22
  * @module ActiveContext
23
23
  */
24
+ import type { DistilledContext } from './memory-flush-contract.js';
24
25
  interface ActiveContextOptions {
25
26
  maxRecentRounds?: number;
26
27
  lightweight?: boolean;
@@ -189,34 +190,7 @@ export declare class ActiveContext {
189
190
  * 蒸馏 ActiveContext 为结构化报告
190
191
  * 在 Agent execute 结束时调用,结果写入 SessionStore
191
192
  */
192
- distill(): {
193
- keyFindings: {
194
- finding: string;
195
- evidence: string;
196
- importance: number;
197
- }[];
198
- toolCallSummary: string[];
199
- stats: {
200
- totalRounds: number;
201
- thoughtCount: number;
202
- totalActions: number;
203
- totalObservations: number;
204
- reflectionCount: number;
205
- totalDurationMs: number;
206
- };
207
- plan: {
208
- steps: {
209
- description: string;
210
- status: string;
211
- keywords: string[];
212
- }[];
213
- text: string;
214
- createdAtIteration: number;
215
- lastUpdatedAtIteration: number;
216
- } | null;
217
- totalObservations: number;
218
- compressedCount: number;
219
- };
193
+ distill(): DistilledContext;
220
194
  /**
221
195
  * 获取所有有 Thought 的轮次
222
196
  * @returns >}
@@ -14,7 +14,7 @@
14
14
  * @module MemoryCoordinator
15
15
  */
16
16
  import { ActiveContext } from './ActiveContext.js';
17
- import type { SessionStore } from './SessionStore.js';
17
+ import type { DimensionReportInput, SessionStore } from './SessionStore.js';
18
18
  /** PersistentMemory 接口 (声明式) */
19
19
  interface PersistentMemoryLike {
20
20
  toPromptSection(opts: {
@@ -153,7 +153,7 @@ export declare class MemoryCoordinator {
153
153
  * 完成维度: 蒸馏 + 存储到 SessionStore
154
154
  * @param [report] 附加报告数据
155
155
  */
156
- completeDimension(scopeId: string, report?: Record<string, unknown>): void;
156
+ completeDimension(scopeId: string, report?: DimensionReportInput): void;
157
157
  /**
158
158
  * 完成会话: 触发 Consolidator
159
159
  * @returns |null>}
@@ -22,6 +22,7 @@
22
22
  *
23
23
  * @module SessionStore
24
24
  */
25
+ import type { SessionStoreSerialized } from './session-store-schema.js';
25
26
  /** Finding 结构 */
26
27
  export interface Finding {
27
28
  finding: string;
@@ -59,7 +60,10 @@ export interface WorkingMemoryDistilled {
59
60
  tool: string;
60
61
  summary: string;
61
62
  }>;
62
- [key: string]: unknown;
63
+ stats?: Record<string, number>;
64
+ plan?: Record<string, unknown> | null;
65
+ totalObservations?: number;
66
+ compressedCount?: number;
63
67
  }
64
68
  /** 维度摘要 */
65
69
  export interface DimensionDigest {
@@ -168,17 +172,7 @@ export declare class SessionStore {
168
172
  set(toolName: string, args: ToolArgs, result: unknown): void;
169
173
  saveCheckpoint(projectRoot: string): Promise<void>;
170
174
  loadCheckpoint(projectRoot: string): Promise<boolean>;
171
- toJSON(): {
172
- dimensionReports: {
173
- [k: string]: DimensionReport;
174
- };
175
- crossReferences: CrossReference[];
176
- tierReflections: TierReflection[];
177
- submittedCandidates: {
178
- [k: string]: CandidateSummary[];
179
- };
180
- projectContext: Record<string, unknown>;
181
- };
175
+ toJSON(): SessionStoreSerialized;
182
176
  static fromJSON(json: Record<string, unknown>): SessionStore;
183
177
  /** 获取所有已引用文件 (去重, F10) */
184
178
  getAllReferencedFiles(): Set<string>;
@@ -26,6 +26,7 @@ import fs from 'node:fs';
26
26
  import path from 'node:path';
27
27
  import Logger from '#infra/logging/Logger.js';
28
28
  import { CACHE } from '#shared/constants.js';
29
+ import { validateSessionStoreShape } from './session-store-schema.js';
29
30
  // ── 类型定义 ──
30
31
  /** 副作用工具 — 不缓存结果 (B3 fix) */
31
32
  const NON_CACHEABLE = new Set([
@@ -570,24 +571,17 @@ export class SessionStore {
570
571
  };
571
572
  }
572
573
  static fromJSON(json) {
574
+ const validated = validateSessionStoreShape(json);
573
575
  const store = new SessionStore({
574
- projectContext: json.projectContext || {},
576
+ projectContext: validated.projectContext,
575
577
  });
576
- if (json.dimensionReports) {
577
- for (const [k, v] of Object.entries(json.dimensionReports)) {
578
- store.#dimensionReports.set(k, v);
579
- }
580
- }
581
- if (json.crossReferences) {
582
- store.#crossReferences = json.crossReferences;
578
+ for (const [k, v] of Object.entries(validated.dimensionReports)) {
579
+ store.#dimensionReports.set(k, v);
583
580
  }
584
- if (json.tierReflections) {
585
- store.#tierReflections = json.tierReflections;
586
- }
587
- if (json.submittedCandidates) {
588
- for (const [k, v] of Object.entries(json.submittedCandidates)) {
589
- store.#submittedCandidates.set(k, v);
590
- }
581
+ store.#crossReferences = validated.crossReferences;
582
+ store.#tierReflections = validated.tierReflections;
583
+ for (const [k, v] of Object.entries(validated.submittedCandidates)) {
584
+ store.#submittedCandidates.set(k, v);
591
585
  }
592
586
  return store;
593
587
  }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * §11.3 H3: MemoryFlushContract — 层级数据流转规约
3
+ *
4
+ * 定义 completeDimension() 保存数据的显式检查表,
5
+ * 确保 distill() 的结果在 ActiveContext.clear() 之前完整提取。
6
+ */
7
+ import type { Finding } from './SessionStore.js';
8
+ /** ActiveContext.distill() 的结构化返回类型 */
9
+ export interface DistilledContext {
10
+ keyFindings: Array<{
11
+ finding: string;
12
+ evidence: string;
13
+ importance: number;
14
+ }>;
15
+ toolCallSummary: string[];
16
+ stats: {
17
+ totalRounds: number;
18
+ thoughtCount: number;
19
+ totalActions: number;
20
+ totalObservations: number;
21
+ reflectionCount: number;
22
+ totalDurationMs: number;
23
+ };
24
+ plan: {
25
+ text: string;
26
+ steps: Array<{
27
+ description: string;
28
+ status: string;
29
+ keywords: string[];
30
+ }>;
31
+ createdAtIteration: number;
32
+ lastUpdatedAtIteration: number;
33
+ } | null;
34
+ totalObservations: number;
35
+ compressedCount: number;
36
+ }
37
+ /** completeDimension() 执行数据保存时使用的结构化清单 */
38
+ export interface DimensionFlushManifest {
39
+ /** distill() 的结果 — 总是存入 SessionStore */
40
+ distilled: DistilledContext;
41
+ /** 原始 scratchpad findings — 重要性 >= threshold 的需要转发 */
42
+ highPriorityFindings: Finding[];
43
+ /** 工具调用统计 — 用于 SessionStore.toolCallLog */
44
+ toolCallSummary: string[];
45
+ /** 是否触发向 PersistentMemory 的异步 consolidation */
46
+ shouldConsolidate: boolean;
47
+ }
48
+ /** 从 DistilledContext 提取高优先级 findings (importance >= threshold) */
49
+ export declare function extractHighPriorityFindings(distilled: DistilledContext, threshold?: number): Finding[];
@@ -0,0 +1,16 @@
1
+ /**
2
+ * §11.3 H3: MemoryFlushContract — 层级数据流转规约
3
+ *
4
+ * 定义 completeDimension() 保存数据的显式检查表,
5
+ * 确保 distill() 的结果在 ActiveContext.clear() 之前完整提取。
6
+ */
7
+ /** 从 DistilledContext 提取高优先级 findings (importance >= threshold) */
8
+ export function extractHighPriorityFindings(distilled, threshold = 7) {
9
+ return distilled.keyFindings
10
+ .filter((f) => f.importance >= threshold)
11
+ .map((f) => ({
12
+ finding: f.finding,
13
+ evidence: f.evidence,
14
+ importance: f.importance,
15
+ }));
16
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * SessionStore 序列化校验
3
+ *
4
+ * `SessionStore.fromJSON()` 的反序列化入口,对边界数据做轻量类型校验。
5
+ *
6
+ * @module agent/memory/session-store-schema
7
+ */
8
+ import type { CandidateSummary, CrossReference, DimensionReport, TierReflection, WorkingMemoryDistilled } from './SessionStore.js';
9
+ export interface SessionStoreSerialized {
10
+ dimensionReports: Record<string, DimensionReport>;
11
+ crossReferences: CrossReference[];
12
+ tierReflections: TierReflection[];
13
+ submittedCandidates: Record<string, CandidateSummary[]>;
14
+ projectContext: Record<string, unknown>;
15
+ workingMemory?: WorkingMemoryDistilled;
16
+ }
17
+ /**
18
+ * 校验反序列化数据的关键字段类型,返回类型安全的结构。
19
+ */
20
+ export declare function validateSessionStoreShape(raw: Record<string, unknown>): SessionStoreSerialized;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SessionStore 序列化校验
3
+ *
4
+ * `SessionStore.fromJSON()` 的反序列化入口,对边界数据做轻量类型校验。
5
+ *
6
+ * @module agent/memory/session-store-schema
7
+ */
8
+ // ── Helpers ──────────────────────────────────────────────────
9
+ function isRecord(val) {
10
+ return val !== null && typeof val === 'object' && !Array.isArray(val);
11
+ }
12
+ // ── Public API ───────────────────────────────────────────────
13
+ /**
14
+ * 校验反序列化数据的关键字段类型,返回类型安全的结构。
15
+ */
16
+ export function validateSessionStoreShape(raw) {
17
+ if (raw.dimensionReports !== undefined && !isRecord(raw.dimensionReports)) {
18
+ throw new Error('SessionStore schema: dimensionReports must be a Record');
19
+ }
20
+ if (raw.crossReferences !== undefined && !Array.isArray(raw.crossReferences)) {
21
+ throw new Error('SessionStore schema: crossReferences must be an array');
22
+ }
23
+ if (raw.tierReflections !== undefined && !Array.isArray(raw.tierReflections)) {
24
+ throw new Error('SessionStore schema: tierReflections must be an array');
25
+ }
26
+ if (raw.submittedCandidates !== undefined && !isRecord(raw.submittedCandidates)) {
27
+ throw new Error('SessionStore schema: submittedCandidates must be a Record');
28
+ }
29
+ return {
30
+ dimensionReports: raw.dimensionReports ?? {},
31
+ crossReferences: raw.crossReferences ?? [],
32
+ tierReflections: raw.tierReflections ?? [],
33
+ submittedCandidates: raw.submittedCandidates ?? {},
34
+ projectContext: isRecord(raw.projectContext)
35
+ ? raw.projectContext
36
+ : {},
37
+ workingMemory: isRecord(raw.workingMemory)
38
+ ? raw.workingMemory
39
+ : undefined,
40
+ };
41
+ }
@@ -19,7 +19,7 @@
19
19
  *
20
20
  * @module presets
21
21
  */
22
- import { insightGateEvaluator } from './domain/insight-gate.js';
22
+ import { evolutionGateEvaluator, insightGateEvaluator } from './domain/insight-gate.js';
23
23
  import { producerRejectionGateEvaluator } from './domain/insight-producer.js';
24
24
  import { BudgetPolicy, QualityGatePolicy, SafetyPolicy } from './policies.js';
25
25
  import { type Strategy } from './strategies.js';
@@ -168,6 +168,50 @@ export declare const PRESETS: Readonly<{
168
168
  enabled: boolean;
169
169
  };
170
170
  };
171
+ evolution: {
172
+ name: string;
173
+ description: string;
174
+ capabilities: string[];
175
+ strategy: {
176
+ type: string;
177
+ maxRetries: number;
178
+ stages: ({
179
+ name: string;
180
+ capabilities: string[];
181
+ budget: {
182
+ temperature: number;
183
+ timeoutMs: number;
184
+ maxIterations: number;
185
+ searchBudget: number;
186
+ searchBudgetGrace: number;
187
+ maxSubmits: number;
188
+ softSubmitLimit: number;
189
+ idleRoundsToExit: number;
190
+ };
191
+ systemPrompt: string;
192
+ promptBuilder: (ctx: Record<string, unknown>) => string;
193
+ gate?: undefined;
194
+ } | {
195
+ name: string;
196
+ gate: {
197
+ evaluator: typeof evolutionGateEvaluator;
198
+ maxRetries: number;
199
+ };
200
+ capabilities?: undefined;
201
+ budget?: undefined;
202
+ systemPrompt?: undefined;
203
+ promptBuilder?: undefined;
204
+ })[];
205
+ };
206
+ policies: ((config?: PolicyFactoryConfig) => BudgetPolicy)[];
207
+ persona: {
208
+ role: string;
209
+ description: string;
210
+ };
211
+ memory: {
212
+ enabled: boolean;
213
+ };
214
+ };
171
215
  lark: {
172
216
  name: string;
173
217
  description: string;
@@ -323,6 +367,50 @@ declare const _default: {
323
367
  enabled: boolean;
324
368
  };
325
369
  };
370
+ evolution: {
371
+ name: string;
372
+ description: string;
373
+ capabilities: string[];
374
+ strategy: {
375
+ type: string;
376
+ maxRetries: number;
377
+ stages: ({
378
+ name: string;
379
+ capabilities: string[];
380
+ budget: {
381
+ temperature: number;
382
+ timeoutMs: number;
383
+ maxIterations: number;
384
+ searchBudget: number;
385
+ searchBudgetGrace: number;
386
+ maxSubmits: number;
387
+ softSubmitLimit: number;
388
+ idleRoundsToExit: number;
389
+ };
390
+ systemPrompt: string;
391
+ promptBuilder: (ctx: Record<string, unknown>) => string;
392
+ gate?: undefined;
393
+ } | {
394
+ name: string;
395
+ gate: {
396
+ evaluator: typeof evolutionGateEvaluator;
397
+ maxRetries: number;
398
+ };
399
+ capabilities?: undefined;
400
+ budget?: undefined;
401
+ systemPrompt?: undefined;
402
+ promptBuilder?: undefined;
403
+ })[];
404
+ };
405
+ policies: ((config?: PolicyFactoryConfig) => BudgetPolicy)[];
406
+ persona: {
407
+ role: string;
408
+ description: string;
409
+ };
410
+ memory: {
411
+ enabled: boolean;
412
+ };
413
+ };
326
414
  lark: {
327
415
  name: string;
328
416
  description: string;
@@ -21,7 +21,8 @@
21
21
  */
22
22
  // v3.0: 导入 Insight 领域函数 (domain/ 模块)
23
23
  import { ANALYST_BUDGET, ANALYST_SYSTEM_PROMPT, buildAnalystPrompt, } from './domain/insight-analyst.js';
24
- import { buildRetryPrompt, insightGateEvaluator } from './domain/insight-gate.js';
24
+ import { buildEvolverPrompt, EVOLVER_BUDGET, EVOLVER_SYSTEM_PROMPT, } from './domain/insight-evolver.js';
25
+ import { buildRetryPrompt, evolutionGateEvaluator, insightGateEvaluator, } from './domain/insight-gate.js';
25
26
  import { buildProducerPromptV2, PRODUCER_BUDGET, PRODUCER_SYSTEM_PROMPT, producerRejectionGateEvaluator, } from './domain/insight-producer.js';
26
27
  import { PipelineStrategy } from './PipelineStrategy.js';
27
28
  import { BudgetPolicy, QualityGatePolicy, SafetyPolicy } from './policies.js';
@@ -81,7 +82,7 @@ export const PRESETS = Object.freeze({
81
82
  timeoutMs: 300_000,
82
83
  },
83
84
  systemPrompt: ANALYST_SYSTEM_PROMPT,
84
- promptBuilder: (ctx) => buildAnalystPrompt(ctx.dimConfig, ctx.projectInfo, ctx.dimContext, ctx.sessionStore, ctx.semanticMemory, ctx.codeEntityGraph),
85
+ promptBuilder: (ctx) => buildAnalystPrompt(ctx.dimConfig, ctx.projectInfo, ctx.dimContext, ctx.sessionStore, ctx.semanticMemory, ctx.codeEntityGraph, ctx.rescanContext, ctx.panorama, ctx.evidenceStarters, ctx.gateArtifact),
85
86
  retryPromptBuilder: (retryCtx, _origPrompt, prev) => {
86
87
  const prevAnalysis = prev.analyze?.reply || '';
87
88
  const retryHint = buildRetryPrompt(retryCtx.reason ?? '');
@@ -106,7 +107,7 @@ export const PRESETS = Object.freeze({
106
107
  budget: { ...PRODUCER_BUDGET, temperature: 0.3, timeoutMs: 180_000 },
107
108
  systemPrompt: PRODUCER_SYSTEM_PROMPT,
108
109
  promptBuilder: (ctx) => buildProducerPromptV2(ctx.gateArtifact, // 来自 quality_gate 的 AnalysisArtifact
109
- ctx.dimConfig, ctx.projectInfo),
110
+ ctx.dimConfig, ctx.projectInfo, ctx.rescanContext, ctx.panorama),
110
111
  // 拒绝率过高时: 缩减预算 + 特定修复 prompt (对齐旧 ProducerAgent 的 rejection retry)
111
112
  retryBudget: { maxIterations: 5, temperature: 0.3, timeoutMs: 120_000 },
112
113
  retryPromptBuilder: (retryCtx, _origPrompt, prev) => {
@@ -129,7 +130,7 @@ export const PRESETS = Object.freeze({
129
130
  2. content.markdown 字段 ≥ 200 字符,含代码块 (\`\`\`)
130
131
  3. content.rationale 必填 — 设计原理说明(为什么这样设计)
131
132
  4. 包含来源标注 (来源: FileName.m:行号)
132
- 5. 标题使用项目真实类名
133
+ 5. 标题使用项目真实类名,不以项目名开头
133
134
  6. 必填: trigger (@kebab-case)、kind (rule/pattern/fact)、doClause (英文祈使句)`;
134
135
  },
135
136
  skipOnDegrade: true,
@@ -150,7 +151,7 @@ export const PRESETS = Object.freeze({
150
151
  maxIterations: config?.maxIterations ?? 24,
151
152
  maxTokens: config?.maxTokens ?? 4096,
152
153
  temperature: config?.temperature ?? 0.3,
153
- timeoutMs: config?.timeoutMs ?? 600_000,
154
+ timeoutMs: config?.timeoutMs ?? 3_600_000,
154
155
  }),
155
156
  (config) => new QualityGatePolicy({
156
157
  minEvidenceLength: config?.minEvidenceLength ?? 500,
@@ -166,6 +167,53 @@ export const PRESETS = Object.freeze({
166
167
  enabled: false, // 无状态 worker
167
168
  },
168
169
  },
170
+ // ─── evolution: 衰退 Recipe 进化决策 ─────────
171
+ evolution: {
172
+ name: '进化',
173
+ description: '审查衰退 Recipe,决定进化(supersede)、废弃或跳过。Evolve→EvolutionGate。',
174
+ capabilities: ['evolution_analysis'],
175
+ strategy: {
176
+ type: 'pipeline',
177
+ maxRetries: 1,
178
+ stages: [
179
+ // ── Phase 1: Evolver ──
180
+ {
181
+ name: 'evolve',
182
+ capabilities: ['evolution_analysis'],
183
+ budget: {
184
+ ...EVOLVER_BUDGET,
185
+ temperature: 0.3,
186
+ timeoutMs: 180_000,
187
+ },
188
+ systemPrompt: EVOLVER_SYSTEM_PROMPT,
189
+ promptBuilder: (ctx) => buildEvolverPrompt(null, null, ctx),
190
+ },
191
+ // ── Phase 2: Evolution Gate ──
192
+ {
193
+ name: 'evolution_gate',
194
+ gate: {
195
+ evaluator: evolutionGateEvaluator,
196
+ maxRetries: 1,
197
+ },
198
+ },
199
+ ],
200
+ },
201
+ policies: [
202
+ (config) => new BudgetPolicy({
203
+ maxIterations: config?.maxIterations ?? 16,
204
+ maxTokens: config?.maxTokens ?? 4096,
205
+ temperature: config?.temperature ?? 0.3,
206
+ timeoutMs: config?.timeoutMs ?? 180_000,
207
+ }),
208
+ ],
209
+ persona: {
210
+ role: 'analyst',
211
+ description: '知识进化专家',
212
+ },
213
+ memory: {
214
+ enabled: false,
215
+ },
216
+ },
169
217
  // ─── lark: 飞书知识管理对话 ─────────────
170
218
  lark: {
171
219
  name: '飞书对话',
@@ -5,17 +5,7 @@ export declare const PROJECT_ROOT: string;
5
5
  export declare const SKILLS_DIR: string;
6
6
  /** 项目级 skills 目录 */
7
7
  export declare const PROJECT_SKILLS_DIR: string;
8
- export declare const DIMENSION_DISPLAY_GROUP: {
9
- architecture: string;
10
- 'code-pattern': string;
11
- 'project-profile': string;
12
- 'best-practice': string;
13
- 'code-standard': string;
14
- 'event-and-data-flow': string;
15
- 'objc-deep-scan': string;
16
- 'category-scan': string;
17
- 'agent-guidelines': string;
18
- };
8
+ export { DIMENSION_DISPLAY_GROUP } from '#domain/dimension/DimensionRegistry.js';
19
9
  /**
20
10
  * 基于维度元数据 (dimensionMeta) 检查提交是否合法
21
11
  * @param dimensionMeta
@@ -25,10 +15,7 @@ export declare const DIMENSION_DISPLAY_GROUP: {
25
15
  export declare function checkDimensionType(dimensionMeta: DimensionMeta, params: Record<string, unknown>, logger?: {
26
16
  info(msg: string, ...args: unknown[]): void;
27
17
  warn(msg: string, ...args: unknown[]): void;
28
- } | null): {
29
- status: string;
30
- reason: string;
31
- } | null;
18
+ } | null): null;
32
19
  /** DI container service lookup (returns dynamic service instances) */
33
20
  export interface ServiceContainer {
34
21
  get(name: string): any;
@@ -67,3 +54,8 @@ export interface ToolSchemaEntry {
67
54
  description: string;
68
55
  parameters: Record<string, unknown>;
69
56
  }
57
+ /**
58
+ * 剥离标题中冗余的项目名前缀(如 "BiliDili 分页控制器" → "分页控制器")
59
+ * 同一知识库内所有条目都属于同一项目,标题中重复项目名没有信息量。
60
+ */
61
+ export declare function stripProjectNamePrefix(title: string, projectRoot: string): string;
@@ -6,18 +6,8 @@ export const PROJECT_ROOT = PACKAGE_ROOT;
6
6
  export const SKILLS_DIR = _SKILLS_DIR;
7
7
  /** 项目级 skills 目录 */
8
8
  export const PROJECT_SKILLS_DIR = path.resolve(PACKAGE_ROOT, '.autosnippet', 'skills');
9
- // Bootstrap 维度展示分组 — 9 个细粒度维度合并为 4 个展示组
10
- export const DIMENSION_DISPLAY_GROUP = {
11
- architecture: 'architecture', // → 架构与设计
12
- 'code-pattern': 'architecture', // → 架构与设计
13
- 'project-profile': 'architecture', // → 架构与设计
14
- 'best-practice': 'best-practice', // → 规范与实践
15
- 'code-standard': 'best-practice', // → 规范与实践
16
- 'event-and-data-flow': 'event-and-data-flow', // → 事件与数据流
17
- 'objc-deep-scan': 'objc-deep-scan', // → 深度扫描
18
- 'category-scan': 'objc-deep-scan', // → 深度扫描
19
- 'agent-guidelines': 'agent-guidelines', // skill-only
20
- };
9
+ // Bootstrap 维度展示分组 — DimensionRegistry 自动生成
10
+ export { DIMENSION_DISPLAY_GROUP } from '#domain/dimension/DimensionRegistry.js';
21
11
  /**
22
12
  * 基于维度元数据 (dimensionMeta) 检查提交是否合法
23
13
  * @param dimensionMeta
@@ -25,15 +15,7 @@ export const DIMENSION_DISPLAY_GROUP = {
25
15
  * @returns | null} 不合法返回 rejected,合法返回 null
26
16
  */
27
17
  export function checkDimensionType(dimensionMeta, params, logger) {
28
- // 1. Skill-only 维度不允许提交 Candidate
29
- if (dimensionMeta.outputType === 'skill') {
30
- logger?.info(`[submit_knowledge] ✗ rejected — dimension "${dimensionMeta.id}" is skill-only, cannot submit candidates`);
31
- return {
32
- status: 'rejected',
33
- reason: `当前维度 "${dimensionMeta.id}" 的输出类型为 skill-only,不允许调用 submit_knowledge。请只在最终回复中提供 dimensionDigest JSON。`,
34
- };
35
- }
36
- // 2. knowledgeType 校验 — 不在允许列表时自动修正为第一个允许类型
18
+ // 1. knowledgeType 校验 — 不在允许列表时自动修正为第一个允许类型
37
19
  const allowed = dimensionMeta.allowedKnowledgeTypes || [];
38
20
  if (allowed.length > 0 && params.knowledgeType) {
39
21
  if (!allowed.includes(params.knowledgeType)) {
@@ -44,3 +26,20 @@ export function checkDimensionType(dimensionMeta, params, logger) {
44
26
  }
45
27
  return null;
46
28
  }
29
+ /**
30
+ * 剥离标题中冗余的项目名前缀(如 "BiliDili 分页控制器" → "分页控制器")
31
+ * 同一知识库内所有条目都属于同一项目,标题中重复项目名没有信息量。
32
+ */
33
+ export function stripProjectNamePrefix(title, projectRoot) {
34
+ if (!title || !projectRoot) {
35
+ return title;
36
+ }
37
+ const projectName = path.basename(projectRoot);
38
+ if (!projectName || projectName.length < 2) {
39
+ return title;
40
+ }
41
+ // 匹配: "ProjectName 标题" / "ProjectName的标题" / "ProjectName — 标题"
42
+ const prefix = new RegExp(`^${projectName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*[的—–-]?\\s*`, 'i');
43
+ const stripped = title.replace(prefix, '');
44
+ return stripped.length > 0 ? stripped : title;
45
+ }