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
@@ -1,10 +1,12 @@
1
- import { and, eq, sql } from 'drizzle-orm';
1
+ import { and, count, desc, eq, gt, inArray, isNotNull, like, ne, or, sql } from 'drizzle-orm';
2
2
  import { inferKind, KnowledgeEntry } from '../../domain/knowledge/index.js';
3
+ import { COUNTABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
3
4
  import { getDrizzle } from '../../infrastructure/database/drizzle/index.js';
4
5
  import { knowledgeEntries } from '../../infrastructure/database/drizzle/schema.js';
5
6
  import Logger from '../../infrastructure/logging/Logger.js';
6
7
  import { safeJsonParse, safeJsonStringify, unixNow } from '../../shared/utils/common.js';
7
- import { BaseRepository } from '../base/BaseRepository.js';
8
+ /** Only allow safe SQL identifier characters */
9
+ const SAFE_IDENTIFIER_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
8
10
  /**
9
11
  * KnowledgeRepositoryImpl — 统一知识实体仓储实现 (Drizzle ORM)
10
12
  *
@@ -15,14 +17,62 @@ import { BaseRepository } from '../base/BaseRepository.js';
15
17
  * - CRUD (create/findById/update/delete/findActiveRules) → drizzle 类型安全 API
16
18
  * - 复杂动态查询 (findWithPagination/getStats) → 保留 raw SQL→渐进迁移
17
19
  */
18
- export class KnowledgeRepositoryImpl extends BaseRepository {
20
+ export class KnowledgeRepositoryImpl {
21
+ /** Raw DB for complex dynamic queries (ORM limitation — used within repository layer) */
22
+ db;
23
+ logger;
19
24
  #drizzle;
25
+ /** Lazily-populated column whitelist for SQL-injection prevention */
26
+ #columnWhitelist = null;
20
27
  constructor(database, drizzle) {
21
- super(database, 'knowledge_entries');
28
+ this.db = database.getDb();
22
29
  this.logger = Logger.getInstance();
23
30
  this.#drizzle = drizzle ?? getDrizzle();
24
31
  }
32
+ /**
33
+ * Validate column name is safe for SQL interpolation (copied from retired BaseRepository).
34
+ * Rejects anything that doesn't match /^[a-zA-Z_]\w*$/ or is not a real column.
35
+ */
36
+ _assertSafeColumn(key) {
37
+ if (!SAFE_IDENTIFIER_RE.test(key)) {
38
+ throw new Error(`Invalid column name: ${key}`);
39
+ }
40
+ if (!this.#columnWhitelist) {
41
+ try {
42
+ const cols = this.db
43
+ .prepare('PRAGMA table_info(knowledge_entries)')
44
+ .all();
45
+ this.#columnWhitelist = new Set(cols.map((c) => c.name));
46
+ }
47
+ catch {
48
+ this.#columnWhitelist = new Set();
49
+ }
50
+ }
51
+ if (this.#columnWhitelist.size > 0 && !this.#columnWhitelist.has(key)) {
52
+ throw new Error(`Unknown column "${key}" for table knowledge_entries`);
53
+ }
54
+ }
25
55
  /* ═══ CRUD ═══════════════════════════════════════════ */
56
+ /**
57
+ * 按 ID 查找
58
+ * ★ Drizzle 类型安全 SELECT
59
+ */
60
+ async findById(id) {
61
+ try {
62
+ const row = this.#drizzle
63
+ .select()
64
+ .from(knowledgeEntries)
65
+ .where(eq(knowledgeEntries.id, id))
66
+ .limit(1)
67
+ .get();
68
+ return row ? this._rowToEntity(row) : null;
69
+ }
70
+ catch (error) {
71
+ const message = error instanceof Error ? error.message : String(error);
72
+ this.logger.error('Error finding knowledge entry by id', { id, error: message });
73
+ throw error;
74
+ }
75
+ }
26
76
  /**
27
77
  * 创建 KnowledgeEntry
28
78
  * ★ Drizzle 类型安全 INSERT — 列名拼写编译期检查
@@ -116,6 +166,30 @@ export class KnowledgeRepositoryImpl extends BaseRepository {
116
166
  }
117
167
  }
118
168
  /* ═══ 查询 ═══════════════════════════════════════════ */
169
+ /**
170
+ * 更新生命周期状态
171
+ * ★ Drizzle 类型安全 UPDATE — 供 RecipeLifecycleSupervisor / ProposalExecutor 使用
172
+ */
173
+ async updateLifecycle(id, lifecycle) {
174
+ const result = this.#drizzle
175
+ .update(knowledgeEntries)
176
+ .set({ lifecycle, updatedAt: unixNow() })
177
+ .where(eq(knowledgeEntries.id, id))
178
+ .run();
179
+ return result.changes > 0;
180
+ }
181
+ /**
182
+ * 更新 stats JSON 字段
183
+ * ★ Drizzle 类型安全 UPDATE — 供 HitRecorder / RecipeLifecycleSupervisor 使用
184
+ */
185
+ async updateStats(id, stats) {
186
+ const result = this.#drizzle
187
+ .update(knowledgeEntries)
188
+ .set({ stats: safeJsonStringify(stats), updatedAt: unixNow() })
189
+ .where(eq(knowledgeEntries.id, id))
190
+ .run();
191
+ return result.changes > 0;
192
+ }
119
193
  /**
120
194
  * 分页查询
121
195
  * @override
@@ -127,8 +201,15 @@ export class KnowledgeRepositoryImpl extends BaseRepository {
127
201
  const params = [];
128
202
  const { _tagLike, _search, lifecycle: lcFilter, ...normalFilters } = filters;
129
203
  if (lcFilter) {
130
- conditions.push(`lifecycle = ?`);
131
- params.push(lcFilter);
204
+ if (Array.isArray(lcFilter)) {
205
+ const placeholders = lcFilter.map(() => '?').join(', ');
206
+ conditions.push(`lifecycle IN (${placeholders})`);
207
+ params.push(...lcFilter);
208
+ }
209
+ else {
210
+ conditions.push(`lifecycle = ?`);
211
+ params.push(lcFilter);
212
+ }
132
213
  }
133
214
  for (const [key, value] of Object.entries(normalFilters)) {
134
215
  if (value == null) {
@@ -195,6 +276,123 @@ export class KnowledgeRepositoryImpl extends BaseRepository {
195
276
  throw error;
196
277
  }
197
278
  }
279
+ /**
280
+ * Guard 专用:active 的 rule + boundary-constraint
281
+ * ★ Phase 5b: supply guard.ts _loadRuleRecipes
282
+ */
283
+ async findActiveGuardRecipes() {
284
+ const rows = this.#drizzle
285
+ .select()
286
+ .from(knowledgeEntries)
287
+ .where(and(eq(knowledgeEntries.lifecycle, 'active'), or(eq(knowledgeEntries.kind, 'rule'), eq(knowledgeEntries.knowledgeType, 'boundary-constraint'))))
288
+ .all();
289
+ return rows
290
+ .map((row) => this._rowToEntity(row))
291
+ .filter(Boolean);
292
+ }
293
+ /**
294
+ * 按 source 字段查询 ID 列表
295
+ * ★ Phase 5b: supply ai.ts mock cleanup
296
+ */
297
+ async findIdsBySource(source) {
298
+ const rows = this.#drizzle
299
+ .select({ id: knowledgeEntries.id })
300
+ .from(knowledgeEntries)
301
+ .where(eq(knowledgeEntries.source, source))
302
+ .all();
303
+ return rows.map((r) => r.id);
304
+ }
305
+ /**
306
+ * 统计指定 lifecycle 集合中的条目数量
307
+ * ★ Phase 5b: supply recipes.ts pre-check
308
+ */
309
+ async countByLifecycles(lifecycles) {
310
+ const rows = this.#drizzle
311
+ .select({ cnt: count() })
312
+ .from(knowledgeEntries)
313
+ .where(inArray(knowledgeEntries.lifecycle, lifecycles))
314
+ .all();
315
+ return Number(rows[0]?.cnt ?? 0);
316
+ }
317
+ /**
318
+ * 查询指定 lifecycle 集合中的所有条目(不分页)
319
+ * ★ Phase 5c: supply Evolution domain services (ContradictionDetector, RedundancyAnalyzer, etc.)
320
+ */
321
+ async findAllByLifecycles(lifecycles) {
322
+ const rows = this.#drizzle
323
+ .select()
324
+ .from(knowledgeEntries)
325
+ .where(inArray(knowledgeEntries.lifecycle, lifecycles))
326
+ .all();
327
+ return rows
328
+ .map((row) => this._rowToEntity(row))
329
+ .filter(Boolean);
330
+ }
331
+ /**
332
+ * 查询指定 lifecycle + category 的条目(带 limit)
333
+ * ★ Phase 5c: supply ConsolidationAdvisor category-filtered query
334
+ */
335
+ async findAllByLifecyclesAndCategory(lifecycles, category, limit) {
336
+ const rows = this.#drizzle
337
+ .select()
338
+ .from(knowledgeEntries)
339
+ .where(and(inArray(knowledgeEntries.lifecycle, lifecycles), eq(knowledgeEntries.category, category)))
340
+ .limit(limit)
341
+ .all();
342
+ return rows
343
+ .map((row) => this._rowToEntity(row))
344
+ .filter(Boolean);
345
+ }
346
+ /**
347
+ * 查询指定 lifecycle 中 trigger 匹配前缀且排除指定 category 的条目
348
+ * ★ Phase 5c: supply ConsolidationAdvisor trigger-prefix fallback
349
+ */
350
+ async findByLifecyclesAndTriggerPrefix(lifecycles, excludeCategory, triggerPrefix, limit) {
351
+ const rows = this.#drizzle
352
+ .select()
353
+ .from(knowledgeEntries)
354
+ .where(and(inArray(knowledgeEntries.lifecycle, lifecycles), ne(knowledgeEntries.category, excludeCategory), like(knowledgeEntries.trigger, `${triggerPrefix}%`)))
355
+ .limit(limit)
356
+ .all();
357
+ return rows
358
+ .map((row) => this._rowToEntity(row))
359
+ .filter(Boolean);
360
+ }
361
+ /**
362
+ * 按 lifecycle 分组统计全部条目数量
363
+ * ★ Phase 5c: supply RecipeLifecycleSupervisor health summary
364
+ */
365
+ async countGroupByLifecycle() {
366
+ const rows = this.#drizzle
367
+ .select({
368
+ lifecycle: knowledgeEntries.lifecycle,
369
+ cnt: count(),
370
+ })
371
+ .from(knowledgeEntries)
372
+ .groupBy(knowledgeEntries.lifecycle)
373
+ .all();
374
+ const result = {};
375
+ for (const row of rows) {
376
+ result[row.lifecycle ?? ''] = Number(row.cnt);
377
+ }
378
+ return result;
379
+ }
380
+ /**
381
+ * 反向查找 relations JSON 中包含指定 nodeId 的条目
382
+ * ★ Phase 5b: supply structure.ts relation graph
383
+ */
384
+ async findByRelationLike(nodeId, excludeId) {
385
+ const rows = this.#drizzle
386
+ .select({
387
+ id: knowledgeEntries.id,
388
+ title: knowledgeEntries.title,
389
+ relations: knowledgeEntries.relations,
390
+ })
391
+ .from(knowledgeEntries)
392
+ .where(and(like(knowledgeEntries.relations, `%${nodeId}%`), ne(knowledgeEntries.id, excludeId)))
393
+ .all();
394
+ return rows.map((r) => ({ id: r.id, title: r.title ?? '', relations: r.relations ?? '{}' }));
395
+ }
198
396
  /** 根据语言查询 */
199
397
  async findByLanguage(language, pagination = {}) {
200
398
  return this.findWithPagination({ language }, pagination);
@@ -233,6 +431,306 @@ export class KnowledgeRepositoryImpl extends BaseRepository {
233
431
  throw error;
234
432
  }
235
433
  }
434
+ /**
435
+ * Find all entries with non-empty reasoning (for SourceRefReconciler)
436
+ * ★ Drizzle 类型安全 SELECT — 仅返回 id + reasoning
437
+ */
438
+ async findAllIdAndReasoning() {
439
+ const rows = this.#drizzle
440
+ .select({
441
+ id: knowledgeEntries.id,
442
+ reasoning: knowledgeEntries.reasoning,
443
+ })
444
+ .from(knowledgeEntries)
445
+ .where(and(sql `${knowledgeEntries.reasoning} IS NOT NULL`, sql `${knowledgeEntries.reasoning} != '{}'`))
446
+ .all();
447
+ return rows
448
+ .filter((r) => r.reasoning != null)
449
+ .map((r) => ({ id: r.id, reasoning: r.reasoning }));
450
+ }
451
+ /**
452
+ * Find sourceFile and reasoning for a single entry (for SourceRefReconciler.applyRepairs)
453
+ * ★ Drizzle 类型安全 SELECT — 仅返回 sourceFile + reasoning
454
+ */
455
+ async findSourceFileAndReasoning(id) {
456
+ const row = this.#drizzle
457
+ .select({
458
+ sourceFile: knowledgeEntries.sourceFile,
459
+ reasoning: knowledgeEntries.reasoning,
460
+ })
461
+ .from(knowledgeEntries)
462
+ .where(eq(knowledgeEntries.id, id))
463
+ .limit(1)
464
+ .get();
465
+ if (!row) {
466
+ return null;
467
+ }
468
+ return { sourceFile: row.sourceFile ?? null, reasoning: row.reasoning ?? null };
469
+ }
470
+ /**
471
+ * Update reasoning JSON field directly (for SourceRefReconciler.applyRepairs)
472
+ * ★ Drizzle 类型安全 UPDATE — 精确更新 reasoning + updatedAt
473
+ */
474
+ async updateReasoning(id, reasoning, updatedAt) {
475
+ const result = this.#drizzle
476
+ .update(knowledgeEntries)
477
+ .set({ reasoning, updatedAt })
478
+ .where(eq(knowledgeEntries.id, id))
479
+ .run();
480
+ return result.changes > 0;
481
+ }
482
+ /* ─── Panorama 域查询 (Phase 5e) ─── */
483
+ /**
484
+ * 获取活跃 Recipe 的元数据 (title, category, topicHint, kind)
485
+ * 用于 DimensionAnalyzer 维度分类分析
486
+ */
487
+ async findRecipeMetadata(lifecycles) {
488
+ const rows = this.#drizzle
489
+ .select({
490
+ title: knowledgeEntries.title,
491
+ category: knowledgeEntries.category,
492
+ topicHint: knowledgeEntries.topicHint,
493
+ kind: knowledgeEntries.kind,
494
+ })
495
+ .from(knowledgeEntries)
496
+ .where(inArray(knowledgeEntries.lifecycle, lifecycles))
497
+ .all();
498
+ return rows.map((r) => ({
499
+ title: r.title ?? '',
500
+ category: r.category ?? '',
501
+ topicHint: r.topicHint ?? '',
502
+ kind: r.kind ?? '',
503
+ }));
504
+ }
505
+ /**
506
+ * 按模块相关关键词搜索 Recipe (PanoramaService.#findModuleRecipes)
507
+ * @param lifecycles - 活跃生命周期
508
+ * @param moduleName - 模块名
509
+ * @param categories - 角色关联的分类列表
510
+ * @param limit - 结果上限
511
+ */
512
+ async findModuleRecipes(lifecycles, moduleName, categories, limit = 20) {
513
+ const conditions = [
514
+ or(like(knowledgeEntries.title, `%${moduleName}%`), like(knowledgeEntries.trigger, `%${moduleName}%`), ...categories.map((cat) => eq(knowledgeEntries.category, cat))),
515
+ ];
516
+ const rows = this.#drizzle
517
+ .select({
518
+ id: knowledgeEntries.id,
519
+ title: knowledgeEntries.title,
520
+ trigger: knowledgeEntries.trigger,
521
+ kind: knowledgeEntries.kind,
522
+ })
523
+ .from(knowledgeEntries)
524
+ .where(and(inArray(knowledgeEntries.lifecycle, lifecycles), ...conditions))
525
+ .orderBy(knowledgeEntries.lifecycle)
526
+ .limit(limit)
527
+ .all();
528
+ return rows.map((r) => ({
529
+ id: r.id ?? '',
530
+ title: r.title ?? '',
531
+ trigger: r.trigger ?? '',
532
+ kind: r.kind ?? '',
533
+ }));
534
+ }
535
+ /**
536
+ * 统计 COUNTABLE_LIFECYCLES 范围内的知识条目数 (PanoramaAggregator.#getProjectRecipeCount)
537
+ */
538
+ async countByCountableLifecycles() {
539
+ const rows = this.#drizzle
540
+ .select({ cnt: count() })
541
+ .from(knowledgeEntries)
542
+ .where(inArray(knowledgeEntries.lifecycle, COUNTABLE_LIFECYCLES))
543
+ .all();
544
+ return Number(rows[0]?.cnt ?? 0);
545
+ }
546
+ /* ═══ Guard / Skills 用查询 ═══════════════════════════ */
547
+ /**
548
+ * Guard 规则查询 — kind='rule' OR knowledgeType='boundary-constraint' + lifecycle 过滤
549
+ * (GuardCheckEngine._loadCustomRules)
550
+ */
551
+ findGuardRulesSync(lifecycles) {
552
+ return this.#drizzle
553
+ .select({
554
+ id: knowledgeEntries.id,
555
+ title: knowledgeEntries.title,
556
+ description: knowledgeEntries.description,
557
+ language: knowledgeEntries.language,
558
+ scope: knowledgeEntries.scope,
559
+ constraints: knowledgeEntries.constraints,
560
+ lifecycle: knowledgeEntries.lifecycle,
561
+ })
562
+ .from(knowledgeEntries)
563
+ .where(and(or(eq(knowledgeEntries.kind, 'rule'), eq(knowledgeEntries.knowledgeType, 'boundary-constraint')), inArray(knowledgeEntries.lifecycle, lifecycles)))
564
+ .all();
565
+ }
566
+ /**
567
+ * Guard 命中次数递增 — stats.guardHits += count
568
+ * (GuardCheckEngine._recordHits)
569
+ */
570
+ incrementGuardHitsSync(id, hits) {
571
+ this.#drizzle
572
+ .update(knowledgeEntries)
573
+ .set({
574
+ stats: sql `json_set(COALESCE(${knowledgeEntries.stats}, '{}'), '$.guardHits', COALESCE(json_extract(${knowledgeEntries.stats}, '$.guardHits'), 0) + ${hits})`,
575
+ updatedAt: unixNow(),
576
+ })
577
+ .where(eq(knowledgeEntries.id, id))
578
+ .run();
579
+ }
580
+ /**
581
+ * 活跃规则 + content 中的 coreCode / pattern 字段 + stats
582
+ * (ReverseGuard.#loadActiveRules)
583
+ */
584
+ findActiveRulesWithContentSync() {
585
+ return this.#drizzle
586
+ .select({
587
+ id: knowledgeEntries.id,
588
+ title: knowledgeEntries.title,
589
+ coreCode: sql `json_extract(${knowledgeEntries.content}, '$.coreCode')`.as('coreCode'),
590
+ guardPattern: sql `json_extract(${knowledgeEntries.content}, '$.pattern')`.as('guardPattern'),
591
+ stats: knowledgeEntries.stats,
592
+ })
593
+ .from(knowledgeEntries)
594
+ .where(and(eq(knowledgeEntries.lifecycle, 'active'), eq(knowledgeEntries.kind, 'rule')))
595
+ .all();
596
+ }
597
+ /**
598
+ * 获取单条记录的 guardHits 数
599
+ * (ReverseGuard.#historicalGuardHits)
600
+ */
601
+ getGuardHitsSync(id) {
602
+ const row = this.#drizzle
603
+ .select({
604
+ hits: sql `json_extract(${knowledgeEntries.stats}, '$.guardHits')`.as('hits'),
605
+ })
606
+ .from(knowledgeEntries)
607
+ .where(eq(knowledgeEntries.id, id))
608
+ .get();
609
+ return Number(row?.hits ?? 0);
610
+ }
611
+ /**
612
+ * 活跃规则的 id + language (CoverageAnalyzer.#loadActiveRules) — sync
613
+ */
614
+ findActiveRuleIdsSync() {
615
+ return this.#drizzle
616
+ .select({
617
+ id: knowledgeEntries.id,
618
+ language: knowledgeEntries.language,
619
+ })
620
+ .from(knowledgeEntries)
621
+ .where(and(eq(knowledgeEntries.lifecycle, 'active'), eq(knowledgeEntries.kind, 'rule')))
622
+ .all();
623
+ }
624
+ /**
625
+ * 活跃条目按 category 分布
626
+ * (SkillAdvisor.#getKBDistribution)
627
+ */
628
+ async countGroupByCategory() {
629
+ return this.#drizzle
630
+ .select({
631
+ category: knowledgeEntries.category,
632
+ cnt: count(),
633
+ })
634
+ .from(knowledgeEntries)
635
+ .where(and(eq(knowledgeEntries.lifecycle, 'active'), isNotNull(knowledgeEntries.category), ne(knowledgeEntries.category, '')))
636
+ .groupBy(knowledgeEntries.category)
637
+ .orderBy(desc(count()))
638
+ .all();
639
+ }
640
+ /**
641
+ * 活跃条目按 language 分布
642
+ * (SkillAdvisor.#getKBDistribution)
643
+ */
644
+ async countGroupByLanguage() {
645
+ return this.#drizzle
646
+ .select({
647
+ language: knowledgeEntries.language,
648
+ cnt: count(),
649
+ })
650
+ .from(knowledgeEntries)
651
+ .where(and(eq(knowledgeEntries.lifecycle, 'active'), isNotNull(knowledgeEntries.language), ne(knowledgeEntries.language, '')))
652
+ .groupBy(knowledgeEntries.language)
653
+ .orderBy(desc(count()))
654
+ .all();
655
+ }
656
+ /**
657
+ * 高使用率活跃 Recipe (adoptions + applications >= minUsage)
658
+ * (SkillAdvisor.#getKBDistribution)
659
+ */
660
+ async findHotRecipesByUsage(minUsage, limit) {
661
+ return this.#drizzle
662
+ .select({
663
+ title: knowledgeEntries.title,
664
+ category: knowledgeEntries.category,
665
+ totalUsage: sql `(COALESCE(json_extract(${knowledgeEntries.stats}, '$.adoptions'), 0) + COALESCE(json_extract(${knowledgeEntries.stats}, '$.applications'), 0))`.as('totalUsage'),
666
+ })
667
+ .from(knowledgeEntries)
668
+ .where(and(eq(knowledgeEntries.lifecycle, 'active'), sql `(COALESCE(json_extract(${knowledgeEntries.stats}, '$.adoptions'), 0) + COALESCE(json_extract(${knowledgeEntries.stats}, '$.applications'), 0)) >= ${minUsage}`))
669
+ .orderBy(desc(sql `(COALESCE(json_extract(${knowledgeEntries.stats}, '$.adoptions'), 0) + COALESCE(json_extract(${knowledgeEntries.stats}, '$.applications'), 0))`))
670
+ .limit(limit)
671
+ .all();
672
+ }
673
+ /**
674
+ * 全库生命周期统计 (total / pending / deprecated)
675
+ * (SkillAdvisor.#getKBDistribution)
676
+ */
677
+ async getLifecycleCounts() {
678
+ const row = this.#drizzle
679
+ .select({
680
+ total: count(),
681
+ pending: sql `SUM(CASE WHEN ${knowledgeEntries.lifecycle} = 'pending' THEN 1 ELSE 0 END)`.as('pending'),
682
+ deprecated: sql `SUM(CASE WHEN ${knowledgeEntries.lifecycle} = 'deprecated' THEN 1 ELSE 0 END)`.as('deprecated'),
683
+ })
684
+ .from(knowledgeEntries)
685
+ .get();
686
+ return {
687
+ total: Number(row?.total ?? 0),
688
+ pending: Number(row?.pending ?? 0),
689
+ deprecated: Number(row?.deprecated ?? 0),
690
+ };
691
+ }
692
+ /**
693
+ * 活跃 Recipe 信号 (SignalCollector.#collectRecipeSignals)
694
+ */
695
+ async findActiveRecipeSignals(limit) {
696
+ return this.#drizzle
697
+ .select({
698
+ id: knowledgeEntries.id,
699
+ title: knowledgeEntries.title,
700
+ knowledgeType: knowledgeEntries.knowledgeType,
701
+ category: knowledgeEntries.category,
702
+ language: knowledgeEntries.language,
703
+ adoptionCount: sql `json_extract(${knowledgeEntries.stats}, '$.adoptions')`.as('adoptionCount'),
704
+ applicationCount: sql `json_extract(${knowledgeEntries.stats}, '$.applications')`.as('applicationCount'),
705
+ qualityOverall: sql `json_extract(${knowledgeEntries.quality}, '$.overall')`.as('qualityOverall'),
706
+ updatedAt: knowledgeEntries.updatedAt,
707
+ })
708
+ .from(knowledgeEntries)
709
+ .where(eq(knowledgeEntries.lifecycle, 'active'))
710
+ .orderBy(desc(knowledgeEntries.updatedAt))
711
+ .limit(limit)
712
+ .all();
713
+ }
714
+ /**
715
+ * 待审核 Candidate (SignalCollector.#collectCandidateSignals)
716
+ */
717
+ async findPendingCandidates(limit) {
718
+ return this.#drizzle
719
+ .select({
720
+ id: knowledgeEntries.id,
721
+ source: knowledgeEntries.source,
722
+ status: knowledgeEntries.lifecycle,
723
+ language: knowledgeEntries.language,
724
+ category: knowledgeEntries.category,
725
+ title: knowledgeEntries.title,
726
+ createdAt: knowledgeEntries.createdAt,
727
+ })
728
+ .from(knowledgeEntries)
729
+ .where(eq(knowledgeEntries.lifecycle, 'pending'))
730
+ .orderBy(desc(knowledgeEntries.createdAt))
731
+ .limit(limit)
732
+ .all();
733
+ }
236
734
  /* ═══ 行 ↔ 实体 映射 ═══════════════════════════════ */
237
735
  /** DB Row → KnowledgeEntry (camelCase 列名 = 属性名,直传) */
238
736
  _rowToEntity(row) {
@@ -257,7 +755,7 @@ export class KnowledgeRepositoryImpl extends BaseRepository {
257
755
  autoApprovable: !!row.autoApprovable,
258
756
  includeHeaders: !!row.includeHeaders,
259
757
  // Staging support
260
- stagingDeadline: row.staging_deadline || null,
758
+ stagingDeadline: row.stagingDeadline || null,
261
759
  });
262
760
  }
263
761
  /** KnowledgeEntry → DB Row (camelCase 列名 = 属性名,直传) */
@@ -310,12 +808,109 @@ export class KnowledgeRepositoryImpl extends BaseRepository {
310
808
  staging_deadline: e.stagingDeadline || null,
311
809
  };
312
810
  }
313
- /**
314
- * 覆写 BaseRepository 的 _mapRowToEntity
315
- * @override
316
- */
317
- _mapRowToEntity(row) {
318
- return this._rowToEntity(row);
811
+ /* ═══════════════════════════════════════════════════════
812
+ * SearchEngine 用同步方法
813
+ * ═══════════════════════════════════════════════════════ */
814
+ /** 查询所有非 deprecated 条目(buildIndex 用) */
815
+ findNonDeprecatedSync() {
816
+ return this.#drizzle
817
+ .select({
818
+ id: knowledgeEntries.id,
819
+ title: knowledgeEntries.title,
820
+ description: knowledgeEntries.description,
821
+ language: knowledgeEntries.language,
822
+ category: knowledgeEntries.category,
823
+ knowledgeType: knowledgeEntries.knowledgeType,
824
+ kind: knowledgeEntries.kind,
825
+ content: knowledgeEntries.content,
826
+ lifecycle: knowledgeEntries.lifecycle,
827
+ tags: knowledgeEntries.tags,
828
+ trigger: knowledgeEntries.trigger,
829
+ difficulty: knowledgeEntries.difficulty,
830
+ quality: knowledgeEntries.quality,
831
+ stats: knowledgeEntries.stats,
832
+ updatedAt: knowledgeEntries.updatedAt,
833
+ createdAt: knowledgeEntries.createdAt,
834
+ })
835
+ .from(knowledgeEntries)
836
+ .where(ne(knowledgeEntries.lifecycle, 'deprecated'))
837
+ .all();
838
+ }
839
+ /** LIKE 关键词搜索(_keywordSearch 用) */
840
+ keywordSearchSync(pattern, limit) {
841
+ return this.#drizzle
842
+ .select({
843
+ id: knowledgeEntries.id,
844
+ title: knowledgeEntries.title,
845
+ description: knowledgeEntries.description,
846
+ language: knowledgeEntries.language,
847
+ category: knowledgeEntries.category,
848
+ knowledgeType: knowledgeEntries.knowledgeType,
849
+ kind: knowledgeEntries.kind,
850
+ lifecycle: knowledgeEntries.lifecycle,
851
+ content: knowledgeEntries.content,
852
+ trigger: knowledgeEntries.trigger,
853
+ headers: knowledgeEntries.headers,
854
+ moduleName: knowledgeEntries.moduleName,
855
+ })
856
+ .from(knowledgeEntries)
857
+ .where(and(ne(knowledgeEntries.lifecycle, 'deprecated'), or(like(knowledgeEntries.title, pattern), like(knowledgeEntries.description, pattern), like(knowledgeEntries.trigger, pattern), like(knowledgeEntries.content, pattern))))
858
+ .limit(limit)
859
+ .all();
860
+ }
861
+ /** 按 ID 列表查询详情(_supplementDetails 用) */
862
+ findByIdsDetailSync(ids) {
863
+ if (ids.length === 0) {
864
+ return [];
865
+ }
866
+ return this.#drizzle
867
+ .select({
868
+ id: knowledgeEntries.id,
869
+ content: knowledgeEntries.content,
870
+ description: knowledgeEntries.description,
871
+ trigger: knowledgeEntries.trigger,
872
+ headers: knowledgeEntries.headers,
873
+ moduleName: knowledgeEntries.moduleName,
874
+ tags: knowledgeEntries.tags,
875
+ language: knowledgeEntries.language,
876
+ category: knowledgeEntries.category,
877
+ updatedAt: knowledgeEntries.updatedAt,
878
+ createdAt: knowledgeEntries.createdAt,
879
+ quality: knowledgeEntries.quality,
880
+ stats: knowledgeEntries.stats,
881
+ difficulty: knowledgeEntries.difficulty,
882
+ whenClause: knowledgeEntries.whenClause,
883
+ doClause: knowledgeEntries.doClause,
884
+ })
885
+ .from(knowledgeEntries)
886
+ .where(inArray(knowledgeEntries.id, ids))
887
+ .all();
888
+ }
889
+ /** 查询指定时间之后更新的条目(refreshIndex 用) */
890
+ findUpdatedSinceSync(sinceIso) {
891
+ const sinceEpoch = Math.floor(new Date(sinceIso).getTime() / 1000);
892
+ return this.#drizzle
893
+ .select({
894
+ id: knowledgeEntries.id,
895
+ title: knowledgeEntries.title,
896
+ description: knowledgeEntries.description,
897
+ language: knowledgeEntries.language,
898
+ category: knowledgeEntries.category,
899
+ knowledgeType: knowledgeEntries.knowledgeType,
900
+ kind: knowledgeEntries.kind,
901
+ content: knowledgeEntries.content,
902
+ lifecycle: knowledgeEntries.lifecycle,
903
+ tags: knowledgeEntries.tags,
904
+ trigger: knowledgeEntries.trigger,
905
+ difficulty: knowledgeEntries.difficulty,
906
+ quality: knowledgeEntries.quality,
907
+ stats: knowledgeEntries.stats,
908
+ updatedAt: knowledgeEntries.updatedAt,
909
+ createdAt: knowledgeEntries.createdAt,
910
+ })
911
+ .from(knowledgeEntries)
912
+ .where(gt(knowledgeEntries.updatedAt, sinceEpoch))
913
+ .all();
319
914
  }
320
915
  }
321
916
  export default KnowledgeRepositoryImpl;