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
@@ -19,6 +19,8 @@
19
19
  * 0-19: 死亡 → 跳过确认直接 deprecated
20
20
  */
21
21
  var _a;
22
+ import { and, like, sql } from 'drizzle-orm';
23
+ import { auditLogs } from '../../infrastructure/database/drizzle/schema.js';
22
24
  import Logger from '../../infrastructure/logging/Logger.js';
23
25
  /* ────────────────────── Helpers ────────────────────── */
24
26
  /**
@@ -49,21 +51,27 @@ const SCORE_WEIGHTS = {
49
51
  };
50
52
  /* ────────────────────── Class ────────────────────── */
51
53
  export class DecayDetector {
52
- #db;
54
+ #knowledgeRepo;
55
+ #edgeRepo;
56
+ #sourceRefRepo;
57
+ #drizzle;
53
58
  #signalBus;
54
59
  #logger = Logger.getInstance();
55
- constructor(db, options = {}) {
56
- this.#db = db;
60
+ constructor(knowledgeRepo, options = {}) {
61
+ this.#knowledgeRepo = knowledgeRepo;
62
+ this.#edgeRepo = options.knowledgeEdgeRepo ?? null;
63
+ this.#sourceRefRepo = options.sourceRefRepo ?? null;
64
+ this.#drizzle = options.drizzle ?? null;
57
65
  this.#signalBus = options.signalBus ?? null;
58
66
  }
59
67
  /**
60
68
  * 扫描所有 active 条目的衰退状态
61
69
  */
62
- scanAll() {
63
- const recipes = this.#loadActiveRecipes();
70
+ async scanAll() {
71
+ const recipes = await this.#loadActiveRecipes();
64
72
  const results = [];
65
73
  for (const recipe of recipes) {
66
- const result = this.evaluate(recipe);
74
+ const result = await this.evaluate(recipe);
67
75
  results.push(result);
68
76
  }
69
77
  // 发射衰退信号
@@ -87,7 +95,7 @@ export class DecayDetector {
87
95
  /**
88
96
  * 评估单条 Recipe 的衰退状态
89
97
  */
90
- evaluate(recipe) {
98
+ async evaluate(recipe) {
91
99
  const stats = _a.#parseStats(recipe.stats);
92
100
  const signals = [];
93
101
  const now = Date.now();
@@ -127,7 +135,7 @@ export class DecayDetector {
127
135
  });
128
136
  }
129
137
  // 策略 3: 符号漂移(由 ReverseGuard 提供,此处从 DB 查 drift 标记)
130
- if (this.#hasSymbolDrift(recipe.id)) {
138
+ if (await this.#hasSymbolDrift(recipe.id)) {
131
139
  signals.push({
132
140
  recipeId: recipe.id,
133
141
  strategy: 'symbol_drift',
@@ -135,7 +143,7 @@ export class DecayDetector {
135
143
  });
136
144
  }
137
145
  // 策略 3b: 来源引用失效(由 SourceRefReconciler 填充 recipe_source_refs)
138
- const staleRefCount = this.#getStaleSourceRefCount(recipe.id);
146
+ const staleRefCount = await this.#getStaleSourceRefCount(recipe.id);
139
147
  if (staleRefCount > 0) {
140
148
  signals.push({
141
149
  recipeId: recipe.id,
@@ -144,7 +152,7 @@ export class DecayDetector {
144
152
  });
145
153
  }
146
154
  // 策略 4: 被取代(有 deprecated_by 关系指向更新版本)
147
- if (this.#isSuperseded(recipe.id)) {
155
+ if (await this.#isSuperseded(recipe.id)) {
148
156
  signals.push({
149
157
  recipeId: recipe.id,
150
158
  strategy: 'superseded',
@@ -152,7 +160,7 @@ export class DecayDetector {
152
160
  });
153
161
  }
154
162
  // 计算 decayScore(staleRatio 影响 quality 维度)
155
- const staleRatio = this.#getSourceRefStaleRatio(recipe.id);
163
+ const staleRatio = await this.#getSourceRefStaleRatio(recipe.id);
156
164
  const dimensions = this.#computeScoreDimensions(stats, recipe, { staleRatio });
157
165
  const decayScore = Math.round(dimensions.freshness * SCORE_WEIGHTS.freshness * 100 +
158
166
  dimensions.usage * SCORE_WEIGHTS.usage * 100 +
@@ -171,23 +179,24 @@ export class DecayDetector {
171
179
  };
172
180
  }
173
181
  /* ── Internal ── */
174
- #loadActiveRecipes() {
182
+ async #loadActiveRecipes() {
175
183
  try {
176
- const rows = this.#db
177
- .prepare(`SELECT id, title, lifecycle, stats, quality, createdAt
178
- FROM knowledge_entries
179
- WHERE lifecycle = 'active'`)
180
- .all();
181
- return rows.map((r) => {
182
- const qualityObj = _a.#parseQuality(r.quality);
184
+ const entries = await this.#knowledgeRepo.findAllByLifecycles(['active']);
185
+ return entries.map((e) => {
186
+ const qualityObj = typeof e.quality === 'object'
187
+ ? {
188
+ grade: e.quality.grade ?? null,
189
+ score: e.quality.overall ?? null,
190
+ }
191
+ : _a.#parseQuality(null);
183
192
  return {
184
- id: r.id,
185
- title: r.title,
186
- lifecycle: r.lifecycle,
187
- stats: r.stats ?? null,
193
+ id: e.id,
194
+ title: e.title,
195
+ lifecycle: e.lifecycle,
196
+ stats: typeof e.stats === 'object' ? JSON.stringify(e.stats) : null,
188
197
  quality_grade: qualityObj.grade,
189
198
  quality_score: qualityObj.score,
190
- created_at: r.createdAt !== undefined ? Number(r.createdAt) : null,
199
+ created_at: e.createdAt ?? null,
191
200
  };
192
201
  });
193
202
  }
@@ -240,61 +249,58 @@ export class DecayDetector {
240
249
  const authority = Math.min(1, authorityRaw / 100);
241
250
  return { freshness, usage, quality, authority };
242
251
  }
243
- #hasSymbolDrift(recipeId) {
252
+ async #hasSymbolDrift(recipeId) {
244
253
  try {
245
- // 查找 audit_logs 中 ReverseGuard 为此 recipe 发过 drift 信号
246
- const row = this.#db
247
- .prepare(`SELECT 1 FROM audit_logs
248
- WHERE action LIKE '%ReverseGuard%'
249
- AND json_extract(details, '$.target') = ?
250
- LIMIT 1`)
251
- .get(recipeId);
254
+ if (!this.#drizzle) {
255
+ return false;
256
+ }
257
+ const row = this.#drizzle
258
+ .select({ id: auditLogs.id })
259
+ .from(auditLogs)
260
+ .where(and(like(auditLogs.action, '%ReverseGuard%'), sql `json_extract(${auditLogs.operationData}, '$.target') = ${recipeId}`))
261
+ .limit(1)
262
+ .get();
252
263
  return !!row;
253
264
  }
254
265
  catch {
255
266
  return false;
256
267
  }
257
268
  }
258
- #getStaleSourceRefCount(recipeId) {
269
+ async #getStaleSourceRefCount(recipeId) {
259
270
  try {
260
- const row = this.#db
261
- .prepare(`SELECT COUNT(*) AS cnt FROM recipe_source_refs
262
- WHERE recipe_id = ? AND status = 'stale'`)
263
- .get(recipeId);
264
- return row?.cnt ?? 0;
271
+ if (!this.#sourceRefRepo) {
272
+ return 0;
273
+ }
274
+ const refs = this.#sourceRefRepo.findByRecipeId(recipeId);
275
+ return refs.filter((r) => r.status === 'stale').length;
265
276
  }
266
277
  catch {
267
- // recipe_source_refs 表可能不存在
268
278
  return 0;
269
279
  }
270
280
  }
271
- /** stale / total 比率(0-1),无 ref 时返回 0(无惩罚) */
272
- #getSourceRefStaleRatio(recipeId) {
281
+ async #getSourceRefStaleRatio(recipeId) {
273
282
  try {
274
- const row = this.#db
275
- .prepare(`SELECT
276
- SUM(CASE WHEN status = 'stale' THEN 1 ELSE 0 END) AS stale,
277
- COUNT(*) AS total
278
- FROM recipe_source_refs
279
- WHERE recipe_id = ?`)
280
- .get(recipeId);
281
- if (!row || row.total === 0) {
283
+ if (!this.#sourceRefRepo) {
282
284
  return 0;
283
285
  }
284
- return row.stale / row.total;
286
+ const refs = this.#sourceRefRepo.findByRecipeId(recipeId);
287
+ if (refs.length === 0) {
288
+ return 0;
289
+ }
290
+ const stale = refs.filter((r) => r.status === 'stale').length;
291
+ return stale / refs.length;
285
292
  }
286
293
  catch {
287
294
  return 0;
288
295
  }
289
296
  }
290
- #isSuperseded(recipeId) {
297
+ async #isSuperseded(recipeId) {
291
298
  try {
292
- const row = this.#db
293
- .prepare(`SELECT 1 FROM knowledge_edges
294
- WHERE source_id = ? AND relation_type = 'deprecated_by'
295
- LIMIT 1`)
296
- .get(recipeId);
297
- return !!row;
299
+ if (!this.#edgeRepo) {
300
+ return false;
301
+ }
302
+ const edges = await this.#edgeRepo.findByRelation(recipeId, 'recipe', 'deprecated_by');
303
+ return edges.length > 0;
298
304
  }
299
305
  catch {
300
306
  return false;
@@ -9,12 +9,7 @@
9
9
  */
10
10
  import type { ReportStore } from '../../infrastructure/report/ReportStore.js';
11
11
  import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
12
- interface DatabaseLike {
13
- prepare(sql: string): {
14
- all(...params: unknown[]): Record<string, unknown>[];
15
- get(...params: unknown[]): Record<string, unknown> | undefined;
16
- };
17
- }
12
+ import type KnowledgeRepositoryImpl from '../../repository/knowledge/KnowledgeRepository.impl.js';
18
13
  export type EnhancementType = 'missing_code_example' | 'low_adoption' | 'low_authority' | 'deprecated_reference';
19
14
  export interface EnhancementSuggestion {
20
15
  recipeId: string;
@@ -26,13 +21,12 @@ export interface EnhancementSuggestion {
26
21
  }
27
22
  export declare class EnhancementSuggester {
28
23
  #private;
29
- constructor(db: DatabaseLike, options?: {
24
+ constructor(knowledgeRepo: KnowledgeRepositoryImpl, options?: {
30
25
  signalBus?: SignalBus;
31
26
  reportStore?: ReportStore;
32
27
  });
33
28
  /**
34
29
  * 运行全部 4 种增强策略
35
30
  */
36
- analyzeAll(): EnhancementSuggestion[];
31
+ analyzeAll(): Promise<EnhancementSuggestion[]>;
37
32
  }
38
- export {};
@@ -7,6 +7,7 @@
7
7
  * ③ 同类知识中 authority 偏低 → 建议补充 whenClause
8
8
  * ④ 关联 Recipe 已 deprecated → 建议检查引用是否过时
9
9
  */
10
+ import { Lifecycle, PUBLISHED_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
10
11
  import Logger from '../../infrastructure/logging/Logger.js';
11
12
  /* ────────────────────── Constants ────────────────────── */
12
13
  const GUARD_HIT_THRESHOLD = 5;
@@ -14,24 +15,25 @@ const SEARCH_HIT_THRESHOLD = 10;
14
15
  const LOW_AUTHORITY_PERCENTILE = 0.25;
15
16
  /* ────────────────────── Class ────────────────────── */
16
17
  export class EnhancementSuggester {
17
- #db;
18
+ #knowledgeRepo;
18
19
  #signalBus;
19
20
  #reportStore;
20
21
  #logger = Logger.getInstance();
21
- constructor(db, options = {}) {
22
- this.#db = db;
22
+ constructor(knowledgeRepo, options = {}) {
23
+ this.#knowledgeRepo = knowledgeRepo;
23
24
  this.#signalBus = options.signalBus ?? null;
24
25
  this.#reportStore = options.reportStore ?? null;
25
26
  }
26
27
  /**
27
28
  * 运行全部 4 种增强策略
28
29
  */
29
- analyzeAll() {
30
+ async analyzeAll() {
31
+ const entries = await this.#knowledgeRepo.findAllByLifecycles(PUBLISHED_LIFECYCLES);
30
32
  const suggestions = [
31
- ...this.#checkMissingCodeExamples(),
32
- ...this.#checkLowAdoption(),
33
- ...this.#checkLowAuthority(),
34
- ...this.#checkDeprecatedReferences(),
33
+ ...this.#checkMissingCodeExamples(entries),
34
+ ...this.#checkLowAdoption(entries),
35
+ ...this.#checkLowAuthority(entries),
36
+ ...(await this.#checkDeprecatedReferences(entries)),
35
37
  ];
36
38
  if (this.#reportStore && suggestions.length > 0) {
37
39
  void this.#reportStore.write({
@@ -49,30 +51,20 @@ export class EnhancementSuggester {
49
51
  return suggestions;
50
52
  }
51
53
  /* ── Strategy ①: Guard 频繁命中但无 coreCode ── */
52
- #checkMissingCodeExamples() {
53
- const rows = this.#db
54
- .prepare(`SELECT id, title, coreCode, stats
55
- FROM knowledge_entries
56
- WHERE lifecycle IN ('active', 'staging') AND kind = 'rule'`)
57
- .all();
54
+ #checkMissingCodeExamples(entries) {
55
+ const rules = entries.filter((e) => e.kind === 'rule');
58
56
  const suggestions = [];
59
- for (const row of rows) {
60
- const hasCode = row.coreCode && row.coreCode.trim().length > 10;
57
+ for (const entry of rules) {
58
+ const hasCode = entry.coreCode && entry.coreCode.trim().length > 10;
61
59
  if (hasCode) {
62
60
  continue;
63
61
  }
64
- let stats = {};
65
- try {
66
- stats = JSON.parse(row.stats || '{}');
67
- }
68
- catch {
69
- continue;
70
- }
62
+ const stats = (entry.stats ?? {});
71
63
  const guardHits = stats.guardHits || 0;
72
64
  if (guardHits >= GUARD_HIT_THRESHOLD) {
73
65
  suggestions.push({
74
- recipeId: row.id,
75
- title: row.title,
66
+ recipeId: entry.id,
67
+ title: entry.title,
76
68
  type: 'missing_code_example',
77
69
  description: `Guard 已命中 ${guardHits} 次但无代码示例,建议补充 coreCode 帮助开发者理解正确用法`,
78
70
  priority: guardHits >= GUARD_HIT_THRESHOLD * 3 ? 'high' : 'medium',
@@ -83,27 +75,16 @@ export class EnhancementSuggester {
83
75
  return suggestions;
84
76
  }
85
77
  /* ── Strategy ②: Search 高频命中但 adoptions=0 ── */
86
- #checkLowAdoption() {
87
- const rows = this.#db
88
- .prepare(`SELECT id, title, stats
89
- FROM knowledge_entries
90
- WHERE lifecycle IN ('active', 'staging')`)
91
- .all();
78
+ #checkLowAdoption(entries) {
92
79
  const suggestions = [];
93
- for (const row of rows) {
94
- let stats = {};
95
- try {
96
- stats = JSON.parse(row.stats || '{}');
97
- }
98
- catch {
99
- continue;
100
- }
80
+ for (const entry of entries) {
81
+ const stats = (entry.stats ?? {});
101
82
  const searchHits = stats.searchHits || 0;
102
83
  const adoptions = stats.adoptions || 0;
103
84
  if (searchHits >= SEARCH_HIT_THRESHOLD && adoptions === 0) {
104
85
  suggestions.push({
105
- recipeId: row.id,
106
- title: row.title,
86
+ recipeId: entry.id,
87
+ title: entry.title,
107
88
  type: 'low_adoption',
108
89
  description: `搜索命中 ${searchHits} 次但采纳为 0,建议改善 usageGuide 或 whenClause 使知识更具可操作性`,
109
90
  priority: searchHits >= SEARCH_HIT_THRESHOLD * 3 ? 'high' : 'medium',
@@ -114,28 +95,16 @@ export class EnhancementSuggester {
114
95
  return suggestions;
115
96
  }
116
97
  /* ── Strategy ③: 同类知识中 authority 偏低 ── */
117
- #checkLowAuthority() {
118
- const rows = this.#db
119
- .prepare(`SELECT id, title, category, stats
120
- FROM knowledge_entries
121
- WHERE lifecycle IN ('active', 'staging')`)
122
- .all();
123
- // 按 category 分组计算 authority 分位
98
+ #checkLowAuthority(entries) {
124
99
  const byCategory = new Map();
125
- for (const row of rows) {
126
- let stats = {};
127
- try {
128
- stats = JSON.parse(row.stats || '{}');
129
- }
130
- catch {
131
- continue;
132
- }
100
+ for (const entry of entries) {
101
+ const stats = (entry.stats ?? {});
133
102
  const authority = stats.authority || 0;
134
- const cat = row.category || 'general';
103
+ const cat = entry.category || 'general';
135
104
  if (!byCategory.has(cat)) {
136
105
  byCategory.set(cat, []);
137
106
  }
138
- byCategory.get(cat).push({ id: row.id, title: row.title, authority });
107
+ byCategory.get(cat)?.push({ id: entry.id, title: entry.title, authority });
139
108
  }
140
109
  const suggestions = [];
141
110
  for (const [category, entries] of byCategory) {
@@ -163,22 +132,10 @@ export class EnhancementSuggester {
163
132
  return suggestions;
164
133
  }
165
134
  /* ── Strategy ④: 关联 Recipe 已 deprecated ── */
166
- #checkDeprecatedReferences() {
167
- const rows = this.#db
168
- .prepare(`SELECT id, title, relations
169
- FROM knowledge_entries
170
- WHERE lifecycle IN ('active', 'staging')`)
171
- .all();
135
+ async #checkDeprecatedReferences(entries) {
172
136
  const suggestions = [];
173
- for (const row of rows) {
174
- let relations = {};
175
- try {
176
- relations = JSON.parse(row.relations || '{}');
177
- }
178
- catch {
179
- continue;
180
- }
181
- // 检查 related, depends_on 等关系桶中的 ID
137
+ for (const entry of entries) {
138
+ const relations = (entry.relations ?? {});
182
139
  const relatedIds = [];
183
140
  for (const [bucket, ids] of Object.entries(relations)) {
184
141
  if (bucket === 'deprecated_by') {
@@ -192,19 +149,18 @@ export class EnhancementSuggester {
192
149
  continue;
193
150
  }
194
151
  // 批量检查关联条目的 lifecycle
195
- const placeholders = relatedIds.map(() => '?').join(',');
196
- const deprecated = this.#db
197
- .prepare(`SELECT id, title FROM knowledge_entries WHERE id IN (${placeholders}) AND lifecycle = 'deprecated'`)
198
- .all(...relatedIds);
199
- for (const dep of deprecated) {
200
- suggestions.push({
201
- recipeId: row.id,
202
- title: row.title,
203
- type: 'deprecated_reference',
204
- description: `引用了已废弃的 Recipe "${dep.title}" (${dep.id}),建议检查引用是否过时`,
205
- priority: 'high',
206
- evidence: [`referenced: ${dep.id}`, `referenced_title: ${dep.title}`],
207
- });
152
+ for (const relId of relatedIds) {
153
+ const relEntry = await this.#knowledgeRepo.findById(relId);
154
+ if (relEntry && relEntry.lifecycle === Lifecycle.DEPRECATED) {
155
+ suggestions.push({
156
+ recipeId: entry.id,
157
+ title: entry.title,
158
+ type: 'deprecated_reference',
159
+ description: `引用了已废弃的 Recipe "${relEntry.title}" (${relEntry.id}),建议检查引用是否过时`,
160
+ priority: 'high',
161
+ evidence: [`referenced: ${relEntry.id}`, `referenced_title: ${relEntry.title}`],
162
+ });
163
+ }
208
164
  }
209
165
  }
210
166
  return suggestions;
@@ -68,17 +68,17 @@ export declare class KnowledgeMetabolism {
68
68
  /**
69
69
  * 执行完整治理周期
70
70
  */
71
- runFullCycle(): MetabolismReport;
71
+ runFullCycle(): Promise<MetabolismReport>;
72
72
  /**
73
73
  * 只执行衰退扫描
74
74
  */
75
- checkDecay(): DecayScoreResult[];
75
+ checkDecay(): Promise<DecayScoreResult[]>;
76
76
  /**
77
77
  * 只执行矛盾检测
78
78
  */
79
- checkContradictions(): ContradictionResult[];
79
+ checkContradictions(): Promise<ContradictionResult[]>;
80
80
  /**
81
81
  * 只执行冗余分析
82
82
  */
83
- checkRedundancy(): RedundancyResult[];
83
+ checkRedundancy(): Promise<RedundancyResult[]>;
84
84
  }