autosnippet 3.3.7 → 3.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +1 -0
  2. package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
  3. package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
  4. package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
  5. package/dashboard/dist/index.html +3 -3
  6. package/dist/bin/cli.js +7 -4
  7. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  8. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  9. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  10. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  11. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  12. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  13. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  14. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  15. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  16. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  17. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  18. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  19. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  20. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  21. package/dist/lib/agent/memory/SessionStore.js +0 -2
  22. package/dist/lib/agent/tools/ast-graph.js +21 -19
  23. package/dist/lib/agent/tools/infrastructure.js +3 -2
  24. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  25. package/dist/lib/agent/tools/project-access.js +5 -4
  26. package/dist/lib/bootstrap.js +2 -1
  27. package/dist/lib/cli/AiScanService.js +4 -17
  28. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  29. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  30. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  31. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
  32. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
  33. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  34. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  35. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  36. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  37. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  38. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  39. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  40. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  41. package/dist/lib/domain/knowledge/index.js +1 -1
  42. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  43. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  44. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
  45. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  46. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  47. package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
  48. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
  49. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  50. package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
  51. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  52. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  53. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  54. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  55. package/dist/lib/external/mcp/handlers/search.js +3 -1
  56. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  57. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  58. package/dist/lib/external/mcp/handlers/system.js +10 -34
  59. package/dist/lib/http/routes/ai.js +11 -13
  60. package/dist/lib/http/routes/guardReport.js +3 -5
  61. package/dist/lib/http/routes/panorama.js +12 -12
  62. package/dist/lib/http/routes/recipes.js +59 -8
  63. package/dist/lib/http/routes/remote.js +3 -13
  64. package/dist/lib/http/routes/search.js +11 -8
  65. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  66. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  67. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  68. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  69. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  70. package/dist/lib/injection/ServiceContainer.js +7 -4
  71. package/dist/lib/injection/ServiceMap.d.ts +20 -0
  72. package/dist/lib/injection/modules/AppModule.js +2 -1
  73. package/dist/lib/injection/modules/GuardModule.js +5 -5
  74. package/dist/lib/injection/modules/InfraModule.js +60 -0
  75. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  76. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  77. package/dist/lib/injection/modules/VectorModule.js +3 -0
  78. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  79. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  80. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  81. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  82. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  83. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  84. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  85. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  86. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  87. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  88. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  89. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  90. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  91. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  92. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  93. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  94. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  95. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  96. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  97. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  98. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  99. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  100. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  101. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  102. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  103. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  104. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  105. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  106. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  107. package/dist/lib/repository/session/SessionRepository.js +110 -0
  108. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  109. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  110. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  111. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  112. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  113. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  114. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  115. package/dist/lib/service/cleanup/CleanupService.js +8 -4
  116. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
  117. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  118. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  119. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  120. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  121. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  122. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  123. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  124. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  125. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  126. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  127. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  128. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  129. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  130. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  131. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  132. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  133. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  134. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  135. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  136. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  137. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  138. package/dist/lib/service/evolution/StagingManager.js +37 -95
  139. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  140. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  141. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  142. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  143. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  144. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  145. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  146. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  147. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  148. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  149. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
  150. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
  151. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  152. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  153. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  154. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  155. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  156. package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
  157. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  158. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  159. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  160. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  161. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
  162. package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
  163. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  164. package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
  165. package/dist/lib/service/panorama/LayerInferrer.js +1 -1
  166. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
  167. package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
  168. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
  169. package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
  170. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  171. package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
  172. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  173. package/dist/lib/service/panorama/PanoramaService.js +41 -66
  174. package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
  175. package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
  176. package/dist/lib/service/panorama/RoleRefiner.js +52 -283
  177. package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
  178. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  179. package/dist/lib/service/quality/QualityScorer.js +157 -83
  180. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  181. package/dist/lib/service/search/SearchEngine.js +32 -37
  182. package/dist/lib/service/signal/HitRecorder.js +5 -5
  183. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  184. package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
  185. package/dist/lib/service/skills/SignalCollector.js +28 -55
  186. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  187. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  188. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  189. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  190. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  191. package/dist/lib/service/vector/VectorService.js +3 -0
  192. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  193. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  194. package/dist/lib/shared/LanguageProfiles.js +939 -0
  195. package/dist/lib/shared/LanguageService.d.ts +6 -0
  196. package/dist/lib/shared/LanguageService.js +16 -0
  197. package/dist/lib/shared/constants.d.ts +19 -19
  198. package/dist/lib/shared/constants.js +10 -10
  199. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  200. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  201. package/dist/lib/types/project-snapshot-builder.js +0 -1
  202. package/dist/lib/types/project-snapshot.d.ts +0 -1
  203. package/dist/lib/types/project-snapshot.js +0 -1
  204. package/dist/lib/types/snapshot-views.d.ts +0 -2
  205. package/dist/lib/types/snapshot-views.js +0 -1
  206. package/package.json +2 -1
  207. package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
  208. package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
  209. package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
  210. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  211. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -5,7 +5,6 @@
5
5
  * 通过 discriminated union(`type` 字段)实现编译期事件校验。
6
6
  *
7
7
  * @module service/bootstrap/bootstrap-event-types
8
- * @see docs/copilot/unified-project-snapshot-design.md §11.3 H6
9
8
  */
10
9
  export interface DimensionSkippedPayload {
11
10
  type: 'skipped';
@@ -5,6 +5,5 @@
5
5
  * 通过 discriminated union(`type` 字段)实现编译期事件校验。
6
6
  *
7
7
  * @module service/bootstrap/bootstrap-event-types
8
- * @see docs/copilot/unified-project-snapshot-design.md §11.3 H6
9
8
  */
10
9
  export {};
@@ -25,6 +25,7 @@ import fs from 'node:fs';
25
25
  import path from 'node:path';
26
26
  import { CANDIDATES_DIR } from '#infra/config/Defaults.js';
27
27
  import { getContextIndexPath, getProjectKnowledgePath, getProjectRecipesPath, getProjectSkillsPath, } from '#infra/config/Paths.js';
28
+ import { CONSUMABLE_LIFECYCLES, lifecycleInSql } from '../../domain/knowledge/Lifecycle.js';
28
29
  // ── 常量 ────────────────────────────────────────────────────
29
30
  /** 垃圾桶根目录(相对于 .autosnippet/) */
30
31
  const TRASH_DIR = '.trash';
@@ -275,12 +276,15 @@ export class CleanupService {
275
276
  return { count: 0, entries: [], coverageByDimension: {} };
276
277
  }
277
278
  try {
279
+ const { sql: lcFilter, params: lcParams } = lifecycleInSql(CONSUMABLE_LIFECYCLES);
278
280
  const rows = this.#db
279
- .prepare(`SELECT id, title, trigger, category, knowledgeType, doClause,
281
+ .prepare(
282
+ // @escape-hatch(permanent) — dynamic lifecycle filter + json_extract
283
+ `SELECT id, title, trigger, category, knowledgeType, doClause,
280
284
  sourceFile, lifecycle, content, json_extract(reasoning, '$.sources') AS sourceRefsJson
281
285
  FROM knowledge_entries
282
- WHERE lifecycle IN ('active', 'staging', 'evolving')`)
283
- .all();
286
+ WHERE ${lcFilter}`)
287
+ .all(...lcParams);
284
288
  const entries = rows.map((r) => {
285
289
  let parsedContent;
286
290
  try {
@@ -430,7 +434,7 @@ export class CleanupService {
430
434
  const lines = [];
431
435
  for (const table of tablesToExport) {
432
436
  try {
433
- const rows = this.#db.prepare(`SELECT * FROM ${table}`).all();
437
+ const rows = this.#db.prepare(`SELECT * FROM ${table}`).all(); // @escape-hatch(permanent) — dynamic table name for backup export
434
438
  for (const row of rows) {
435
439
  lines.push(JSON.stringify({ _table: table, ...row }));
436
440
  totalRows++;
@@ -18,6 +18,8 @@
18
18
  */
19
19
  import fs from 'node:fs';
20
20
  import path from 'node:path';
21
+ import { RawDbCallGraphAdapter, } from '../../repository/delivery/DeliveryRepoAdapter.js';
22
+ import { unwrapRawDb } from '../../repository/search/SearchRepoAdapter.js';
21
23
  import { DELIVERY_RANK, KNOWLEDGE_CONFIDENCE } from '../../shared/constants.js';
22
24
  import { DEFAULT_KNOWLEDGE_BASE_DIR } from '../../shared/ProjectMarkers.js';
23
25
  import { AgentInstructionsGenerator } from './AgentInstructionsGenerator.js';
@@ -313,20 +315,16 @@ export class CursorDeliveryPipeline {
313
315
  return null;
314
316
  }
315
317
  try {
316
- const db = typeof this.database.getDb === 'function' ? this.database.getDb() : this.database;
318
+ const rawDb = unwrapRawDb(this.database);
319
+ const repo = new RawDbCallGraphAdapter(rawDb);
317
320
  // 查询调用边中的跨目录调用模式
318
- const callEdges = db
319
- .prepare(`SELECT from_id, to_id, metadata_json FROM knowledge_edges
320
- WHERE relation = 'calls' AND metadata_json LIKE '%phase5%'`)
321
- .all();
321
+ const callEdges = repo.findCallEdges();
322
322
  if (!callEdges || callEdges.length < 5) {
323
323
  return null;
324
324
  }
325
325
  // 提取 caller/callee 对应的文件路径
326
326
  const entityFiles = new Map();
327
- const entities = db
328
- .prepare(`SELECT entity_id, file_path FROM code_entities WHERE entity_type = 'method'`)
329
- .all();
327
+ const entities = repo.findMethodEntities();
330
328
  for (const e of entities) {
331
329
  entityFiles.set(e.entity_id, e.file_path);
332
330
  }
@@ -14,11 +14,7 @@
14
14
  * 2. 语义域覆盖 — category + trigger 是否落在已有 Recipe 管辖范围
15
15
  * 3. 独立价值 — 内容长度、具体性、是否有独立 coreCode
16
16
  */
17
- interface DatabaseLike {
18
- prepare(sql: string): {
19
- all(...params: unknown[]): Record<string, unknown>[];
20
- };
21
- }
17
+ import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
22
18
  /** 提交候选的必要字段 */
23
19
  export interface CandidateForConsolidation {
24
20
  title: string;
@@ -92,14 +88,14 @@ export interface BatchConsolidationResult {
92
88
  }
93
89
  export declare class ConsolidationAdvisor {
94
90
  #private;
95
- constructor(db: DatabaseLike);
91
+ constructor(knowledgeRepo: KnowledgeRepositoryImpl);
96
92
  /**
97
93
  * 分析候选知识与现有知识库的关系,返回融合建议。
98
94
  *
99
95
  * @param candidate - 待提交的候选数据
100
96
  * @returns ConsolidationAdvice — 建议 + 理由 + 上下文
101
97
  */
102
- analyze(candidate: CandidateForConsolidation): ConsolidationAdvice;
98
+ analyze(candidate: CandidateForConsolidation): Promise<ConsolidationAdvice>;
103
99
  /**
104
100
  * 批量分析候选知识与现有知识库的关系。
105
101
  *
@@ -109,6 +105,5 @@ export declare class ConsolidationAdvisor {
109
105
  * @param candidates - 待提交的候选数组
110
106
  * @returns BatchConsolidationResult — 每条分析 + 批次内重叠
111
107
  */
112
- analyzeBatch(candidates: CandidateForConsolidation[]): BatchConsolidationResult;
108
+ analyzeBatch(candidates: CandidateForConsolidation[]): Promise<BatchConsolidationResult>;
113
109
  }
114
- export {};
@@ -15,6 +15,7 @@
15
15
  * 3. 独立价值 — 内容长度、具体性、是否有独立 coreCode
16
16
  */
17
17
  var _a;
18
+ import { COUNTABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
18
19
  import Logger from '../../infrastructure/logging/Logger.js';
19
20
  import { ContradictionDetector } from './ContradictionDetector.js';
20
21
  /* ────────────────────── Constants ────────────────────── */
@@ -29,10 +30,10 @@ const MAX_CANDIDATES_PER_ANALYSIS = 30;
29
30
  const WEIGHTS = { title: 0.2, clause: 0.3, code: 0.3, guard: 0.2 };
30
31
  /* ────────────────────── Class ────────────────────── */
31
32
  export class ConsolidationAdvisor {
32
- #db;
33
+ #knowledgeRepo;
33
34
  #logger = Logger.getInstance();
34
- constructor(db) {
35
- this.#db = db;
35
+ constructor(knowledgeRepo) {
36
+ this.#knowledgeRepo = knowledgeRepo;
36
37
  }
37
38
  /**
38
39
  * 分析候选知识与现有知识库的关系,返回融合建议。
@@ -40,11 +41,11 @@ export class ConsolidationAdvisor {
40
41
  * @param candidate - 待提交的候选数据
41
42
  * @returns ConsolidationAdvice — 建议 + 理由 + 上下文
42
43
  */
43
- analyze(candidate) {
44
+ async analyze(candidate) {
44
45
  // ── Step 1: 独立价值评估 ──
45
46
  const substanceScore = this.#assessSubstance(candidate);
46
47
  // ── Step 2: 加载同域 / 相关 Recipe ──
47
- const related = this.#loadRelatedRecipes(candidate);
48
+ const related = await this.#loadRelatedRecipes(candidate);
48
49
  // ── Step 3: insufficient — 独立价值不足,交给 Agent 与开发者决定 ──
49
50
  if (substanceScore < MIN_SUBSTANCE_SCORE) {
50
51
  if (related.length > 0) {
@@ -188,12 +189,12 @@ export class ConsolidationAdvisor {
188
189
  * @param candidates - 待提交的候选数组
189
190
  * @returns BatchConsolidationResult — 每条分析 + 批次内重叠
190
191
  */
191
- analyzeBatch(candidates) {
192
+ async analyzeBatch(candidates) {
192
193
  // 对每个候选独立分析(vs DB)
193
- const items = candidates.map((c, index) => ({
194
- index,
195
- advice: this.analyze(c),
196
- }));
194
+ const items = [];
195
+ for (let index = 0; index < candidates.length; index++) {
196
+ items.push({ index, advice: await this.analyze(candidates[index]) });
197
+ }
197
198
  // 检测批次内候选之间的相互重叠
198
199
  const internalOverlaps = [];
199
200
  for (let i = 0; i < candidates.length; i++) {
@@ -288,78 +289,41 @@ export class ConsolidationAdvisor {
288
289
  return msg;
289
290
  }
290
291
  /* ════════════════════ 相关 Recipe 加载 ════════════════════ */
291
- #loadRelatedRecipes(candidate) {
292
+ async #loadRelatedRecipes(candidate) {
292
293
  try {
293
- // 先按 category 精确匹配 + trigger 前缀匹配
294
294
  const category = candidate.category || '';
295
295
  const trigger = candidate.trigger || '';
296
296
  const triggerPrefix = trigger.startsWith('@')
297
297
  ? trigger.slice(0, Math.max(3, trigger.indexOf('-', 1) > 0 ? trigger.indexOf('-', 1) : trigger.length))
298
298
  : '';
299
- let rows;
299
+ const toSummary = (e) => ({
300
+ id: e.id,
301
+ title: e.title,
302
+ doClause: e.doClause || null,
303
+ dontClause: e.dontClause || null,
304
+ coreCode: e.coreCode || null,
305
+ category: e.category || null,
306
+ trigger: e.trigger || null,
307
+ whenClause: e.whenClause || null,
308
+ guardPattern: e.content?.pattern || null,
309
+ });
300
310
  if (category) {
301
- // category Recipe 是最有可能重叠的
302
- rows = this.#db
303
- .prepare(`SELECT id, title,
304
- doClause,
305
- dontClause,
306
- json_extract(content, '$.coreCode') AS coreCode,
307
- category, trigger, whenClause,
308
- json_extract(content, '$.pattern') AS guardPattern
309
- FROM knowledge_entries
310
- WHERE lifecycle IN ('active', 'staging', 'evolving', 'pending')
311
- AND category = ?
312
- ORDER BY lifecycle DESC
313
- LIMIT ?`)
314
- .all(category, MAX_CANDIDATES_PER_ANALYSIS);
315
- // 如果同 category 不够,再加载 trigger 相关的
316
- if (rows.length < 5 && triggerPrefix.length >= 3) {
317
- const extra = this.#db
318
- .prepare(`SELECT id, title,
319
- doClause,
320
- dontClause,
321
- json_extract(content, '$.coreCode') AS coreCode,
322
- category, trigger, whenClause,
323
- json_extract(content, '$.pattern') AS guardPattern
324
- FROM knowledge_entries
325
- WHERE lifecycle IN ('active', 'staging', 'evolving', 'pending')
326
- AND category != ?
327
- AND trigger LIKE ?
328
- LIMIT ?`)
329
- .all(category, `${triggerPrefix}%`, MAX_CANDIDATES_PER_ANALYSIS - rows.length);
330
- const existingIds = new Set(rows.map((r) => r.id));
311
+ const entries = await this.#knowledgeRepo.findAllByLifecyclesAndCategory(COUNTABLE_LIFECYCLES, category, MAX_CANDIDATES_PER_ANALYSIS);
312
+ const results = entries.map(toSummary);
313
+ if (results.length < 5 && triggerPrefix.length >= 3) {
314
+ const extra = await this.#knowledgeRepo.findByLifecyclesAndTriggerPrefix(COUNTABLE_LIFECYCLES, category, triggerPrefix, MAX_CANDIDATES_PER_ANALYSIS - results.length);
315
+ const existingIds = new Set(results.map((r) => r.id));
331
316
  for (const e of extra) {
332
- if (!existingIds.has(e.id)) {
333
- rows.push(e);
317
+ const s = toSummary(e);
318
+ if (!existingIds.has(s.id)) {
319
+ results.push(s);
334
320
  }
335
321
  }
336
322
  }
323
+ return results;
337
324
  }
338
- else {
339
- // category 时按 title 关键词粗筛
340
- rows = this.#db
341
- .prepare(`SELECT id, title,
342
- doClause,
343
- dontClause,
344
- json_extract(content, '$.coreCode') AS coreCode,
345
- category, trigger, whenClause,
346
- json_extract(content, '$.pattern') AS guardPattern
347
- FROM knowledge_entries
348
- WHERE lifecycle IN ('active', 'staging', 'evolving', 'pending')
349
- LIMIT ?`)
350
- .all(MAX_CANDIDATES_PER_ANALYSIS);
351
- }
352
- return rows.map((r) => ({
353
- id: r.id,
354
- title: r.title,
355
- doClause: r.doClause ?? null,
356
- dontClause: r.dontClause ?? null,
357
- coreCode: r.coreCode ?? null,
358
- category: r.category ?? null,
359
- trigger: r.trigger ?? null,
360
- whenClause: r.whenClause ?? null,
361
- guardPattern: r.guardPattern ?? null,
362
- }));
325
+ const entries = await this.#knowledgeRepo.findAllByLifecycles(COUNTABLE_LIFECYCLES);
326
+ return entries.slice(0, MAX_CANDIDATES_PER_ANALYSIS).map(toSummary);
363
327
  }
364
328
  catch (err) {
365
329
  this.#logger.warn(`ConsolidationAdvisor: failed to load recipes: ${err instanceof Error ? err.message : String(err)}`);
@@ -16,19 +16,12 @@
16
16
  *
17
17
  * @module service/evolution/ContentPatcher
18
18
  */
19
+ import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
20
+ import type { RecipeSourceRefRepositoryImpl } from '../../repository/sourceref/RecipeSourceRefRepository.js';
19
21
  import type { ContentPatchResult } from '../../types/evolution.js';
20
- interface DatabaseLike {
21
- prepare(sql: string): {
22
- all(...params: unknown[]): Record<string, unknown>[];
23
- get(...params: unknown[]): Record<string, unknown> | undefined;
24
- run(...params: unknown[]): {
25
- changes: number;
26
- };
27
- };
28
- }
29
22
  export declare class ContentPatcher {
30
23
  #private;
31
- constructor(db: DatabaseLike);
24
+ constructor(knowledgeRepo: KnowledgeRepositoryImpl, sourceRefRepo: RecipeSourceRefRepositoryImpl);
32
25
  /**
33
26
  * 从 Proposal evidence 提取 suggestedChanges 并应用到 Recipe
34
27
  *
@@ -39,6 +32,5 @@ export declare class ContentPatcher {
39
32
  type: string;
40
33
  targetRecipeId: string;
41
34
  evidence: Record<string, unknown>[];
42
- }, patchSource?: 'agent-suggestion' | 'correction' | 'merge'): ContentPatchResult;
35
+ }, patchSource?: 'agent-suggestion' | 'correction' | 'merge'): Promise<ContentPatchResult>;
43
36
  }
44
- export {};
@@ -31,20 +31,22 @@ const PATCHABLE_FIELDS = new Set([
31
31
  ]);
32
32
  /* ────────────────────── Class ────────────────────── */
33
33
  export class ContentPatcher {
34
- #db;
34
+ #knowledgeRepo;
35
+ #sourceRefRepo;
35
36
  #logger = Logger.getInstance();
36
- constructor(db) {
37
- this.#db = db;
37
+ constructor(knowledgeRepo, sourceRefRepo) {
38
+ this.#knowledgeRepo = knowledgeRepo;
39
+ this.#sourceRefRepo = sourceRefRepo;
38
40
  }
39
41
  /**
40
42
  * 从 Proposal evidence 提取 suggestedChanges 并应用到 Recipe
41
43
  *
42
44
  * @returns ContentPatchResult — success: 是否成功应用了至少一个 patch
43
45
  */
44
- applyProposal(proposal, patchSource = 'agent-suggestion') {
46
+ async applyProposal(proposal, patchSource = 'agent-suggestion') {
45
47
  const recipeId = proposal.targetRecipeId;
46
48
  // 1. 获取 Recipe 当前内容
47
- const recipe = this.#getRecipe(recipeId);
49
+ const recipe = await this.#getRecipe(recipeId);
48
50
  if (!recipe) {
49
51
  return this.#skipResult(recipeId, patchSource, 'Recipe not found');
50
52
  }
@@ -66,7 +68,7 @@ export class ContentPatcher {
66
68
  return this.#skipResult(recipeId, patchSource, 'No valid fields to patch');
67
69
  }
68
70
  // 6. 持久化
69
- this.#persistRecipe(recipe);
71
+ await this.#persistRecipe(recipe);
70
72
  // 7. 创建 after 快照
71
73
  const afterSnapshot = this.#createSnapshot(recipe);
72
74
  this.#logger.info(`[ContentPatcher] Applied ${fieldsPatched.length} patches to recipe ${recipeId}: ${fieldsPatched.join(', ')}`);
@@ -257,20 +259,47 @@ export class ContentPatcher {
257
259
  };
258
260
  }
259
261
  /* ═══════════════════ DB ═══════════════════ */
260
- #getRecipe(recipeId) {
261
- const row = this.#db
262
- .prepare(`SELECT id, title, coreCode, doClause, dontClause, whenClause, content, sourceRefs, headers
263
- FROM knowledge_entries WHERE id = ?`)
264
- .get(recipeId);
265
- return row ?? null;
262
+ async #getRecipe(recipeId) {
263
+ const entry = await this.#knowledgeRepo.findById(recipeId);
264
+ if (!entry) {
265
+ return null;
266
+ }
267
+ // recipe_source_refs 表读取关联的源引用路径
268
+ const refs = this.#sourceRefRepo.findByRecipeId(entry.id);
269
+ const sourcePaths = refs.map((r) => r.sourcePath);
270
+ return {
271
+ id: entry.id,
272
+ title: entry.title,
273
+ coreCode: entry.coreCode || '',
274
+ doClause: entry.doClause || '',
275
+ dontClause: entry.dontClause || '',
276
+ whenClause: entry.whenClause || '',
277
+ content: JSON.stringify(entry.content || {}),
278
+ sourceRefs: JSON.stringify(sourcePaths),
279
+ headers: JSON.stringify(entry.headers || []),
280
+ };
266
281
  }
267
- #persistRecipe(recipe) {
268
- this.#db
269
- .prepare(`UPDATE knowledge_entries
270
- SET coreCode = ?, doClause = ?, dontClause = ?, whenClause = ?,
271
- content = ?, sourceRefs = ?, headers = ?, updatedAt = ?
272
- WHERE id = ?`)
273
- .run(recipe.coreCode, recipe.doClause, recipe.dontClause, recipe.whenClause, recipe.content, recipe.sourceRefs, recipe.headers, Date.now(), recipe.id);
282
+ async #persistRecipe(recipe) {
283
+ await this.#knowledgeRepo.update(recipe.id, {
284
+ coreCode: recipe.coreCode,
285
+ doClause: recipe.doClause,
286
+ dontClause: recipe.dontClause,
287
+ whenClause: recipe.whenClause,
288
+ content: safeJsonParse(recipe.content, {}),
289
+ headers: safeJsonParse(recipe.headers, []),
290
+ });
291
+ // 同步 sourceRefs 到 recipe_source_refs 表
292
+ const newPaths = safeJsonParse(recipe.sourceRefs, []);
293
+ const now = Math.floor(Date.now() / 1000);
294
+ this.#sourceRefRepo.deleteByRecipeId(recipe.id);
295
+ for (const sourcePath of newPaths) {
296
+ this.#sourceRefRepo.upsert({
297
+ recipeId: recipe.id,
298
+ sourcePath,
299
+ status: 'active',
300
+ verifiedAt: now,
301
+ });
302
+ }
274
303
  }
275
304
  /* ═══════════════════ Helpers ═══════════════════ */
276
305
  #skipResult(recipeId, patchSource, reason) {
@@ -13,11 +13,7 @@
13
13
  * 结果:硬矛盾 (confidence ≥ 0.8) / 软矛盾 (0.4-0.8)
14
14
  */
15
15
  import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
16
- interface DatabaseLike {
17
- prepare(sql: string): {
18
- all(...params: unknown[]): Record<string, unknown>[];
19
- };
20
- }
16
+ import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
21
17
  export interface ContradictionResult {
22
18
  recipeA: string;
23
19
  recipeB: string;
@@ -37,13 +33,13 @@ interface RecipeEntry {
37
33
  }
38
34
  export declare class ContradictionDetector {
39
35
  #private;
40
- constructor(db: DatabaseLike, options?: {
36
+ constructor(knowledgeRepo: KnowledgeRepositoryImpl, options?: {
41
37
  signalBus?: SignalBus;
42
38
  });
43
39
  /**
44
40
  * 检测所有 active/staging/evolving Recipe 之间的矛盾
45
41
  */
46
- detectAll(): ContradictionResult[];
42
+ detectAll(): Promise<ContradictionResult[]>;
47
43
  /**
48
44
  * 检测两条 Recipe 是否矛盾
49
45
  */
@@ -13,6 +13,7 @@
13
13
  * 结果:硬矛盾 (confidence ≥ 0.8) / 软矛盾 (0.4-0.8)
14
14
  */
15
15
  var _a;
16
+ import { CONSUMABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
16
17
  import Logger from '../../infrastructure/logging/Logger.js';
17
18
  /* ────────────────────── Constants ────────────────────── */
18
19
  const NEGATION_PATTERNS_ZH = /不(再)?使用|禁止|废弃|移除|取消|停止|不要|不采用|弃用|淘汰/;
@@ -71,18 +72,18 @@ const STOP_WORDS = new Set([
71
72
  ]);
72
73
  /* ────────────────────── Class ────────────────────── */
73
74
  export class ContradictionDetector {
74
- #db;
75
+ #knowledgeRepo;
75
76
  #signalBus;
76
77
  #logger = Logger.getInstance();
77
- constructor(db, options = {}) {
78
- this.#db = db;
78
+ constructor(knowledgeRepo, options = {}) {
79
+ this.#knowledgeRepo = knowledgeRepo;
79
80
  this.#signalBus = options.signalBus ?? null;
80
81
  }
81
82
  /**
82
83
  * 检测所有 active/staging/evolving Recipe 之间的矛盾
83
84
  */
84
- detectAll() {
85
- const recipes = this.#loadRecipes();
85
+ async detectAll() {
86
+ const recipes = await this.#loadRecipes();
86
87
  const results = [];
87
88
  for (let i = 0; i < recipes.length; i++) {
88
89
  for (let j = i + 1; j < recipes.length; j++) {
@@ -155,26 +156,18 @@ export class ContradictionDetector {
155
156
  };
156
157
  }
157
158
  /* ── Internal ── */
158
- #loadRecipes() {
159
+ async #loadRecipes() {
159
160
  try {
160
- const rows = this.#db
161
- .prepare(`SELECT id, title, lifecycle, description,
162
- json_extract(content, '$.markdown') AS content_markdown,
163
- doClause,
164
- dontClause,
165
- json_extract(content, '$.pattern') AS guardPattern
166
- FROM knowledge_entries
167
- WHERE lifecycle IN ('active', 'staging', 'evolving')`)
168
- .all();
169
- return rows.map((r) => ({
170
- id: r.id,
171
- title: r.title,
172
- lifecycle: r.lifecycle,
173
- doClause: r.doClause ?? null,
174
- dontClause: r.dontClause ?? null,
175
- guardPattern: r.guardPattern ?? null,
176
- description: r.description ?? null,
177
- content_markdown: r.content_markdown ?? null,
161
+ const entries = await this.#knowledgeRepo.findAllByLifecycles(CONSUMABLE_LIFECYCLES);
162
+ return entries.map((e) => ({
163
+ id: e.id,
164
+ title: e.title,
165
+ lifecycle: e.lifecycle,
166
+ doClause: e.doClause || null,
167
+ dontClause: e.dontClause || null,
168
+ guardPattern: e.content?.pattern || null,
169
+ description: e.description || null,
170
+ content_markdown: e.content?.markdown || null,
178
171
  }));
179
172
  }
180
173
  catch {
@@ -18,13 +18,11 @@
18
18
  * 20-39: 严重 → Grace Period 缩短到 15d
19
19
  * 0-19: 死亡 → 跳过确认直接 deprecated
20
20
  */
21
+ import type { DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
21
22
  import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
22
- interface DatabaseLike {
23
- prepare(sql: string): {
24
- all(...params: unknown[]): Record<string, unknown>[];
25
- get(...params: unknown[]): Record<string, unknown> | undefined;
26
- };
27
- }
23
+ import type { KnowledgeEdgeRepositoryImpl } from '../../repository/knowledge/KnowledgeEdgeRepository.js';
24
+ import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
25
+ import type { RecipeSourceRefRepositoryImpl } from '../../repository/sourceref/RecipeSourceRefRepository.js';
28
26
  export interface DecaySignal {
29
27
  recipeId: string;
30
28
  strategy: DecayStrategy;
@@ -57,16 +55,19 @@ interface RecipeForDecay {
57
55
  }
58
56
  export declare class DecayDetector {
59
57
  #private;
60
- constructor(db: DatabaseLike, options?: {
58
+ constructor(knowledgeRepo: KnowledgeRepositoryImpl, options?: {
61
59
  signalBus?: SignalBus;
60
+ knowledgeEdgeRepo?: KnowledgeEdgeRepositoryImpl;
61
+ sourceRefRepo?: RecipeSourceRefRepositoryImpl;
62
+ drizzle?: DrizzleDB;
62
63
  });
63
64
  /**
64
65
  * 扫描所有 active 条目的衰退状态
65
66
  */
66
- scanAll(): DecayScoreResult[];
67
+ scanAll(): Promise<DecayScoreResult[]>;
67
68
  /**
68
69
  * 评估单条 Recipe 的衰退状态
69
70
  */
70
- evaluate(recipe: RecipeForDecay): DecayScoreResult;
71
+ evaluate(recipe: RecipeForDecay): Promise<DecayScoreResult>;
71
72
  }
72
73
  export {};