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
@@ -0,0 +1,361 @@
1
+ /**
2
+ * CodeEntityRepository — AST 代码实体的仓储实现
3
+ *
4
+ * 从 CodeEntityGraph 和 PanoramaScanner 提取的数据操作,
5
+ * 使用 Drizzle 类型安全 API。
6
+ */
7
+ import { and, count, eq, inArray, isNotNull, like, ne, sql } from 'drizzle-orm';
8
+ import { codeEntities } from '../../infrastructure/database/drizzle/schema.js';
9
+ import { unixNow } from '../../shared/utils/common.js';
10
+ import { RepositoryBase } from '../base/RepositoryBase.js';
11
+ /* ═══ Repository 实现 ═══ */
12
+ export class CodeEntityRepositoryImpl extends RepositoryBase {
13
+ constructor(drizzle) {
14
+ super(drizzle, codeEntities);
15
+ }
16
+ /* ─── CRUD ─── */
17
+ async findById(id) {
18
+ const rows = this.drizzle.select().from(this.table).where(eq(this.table.id, id)).limit(1).all();
19
+ return rows.length > 0 ? this.#mapRow(rows[0]) : null;
20
+ }
21
+ async create(data) {
22
+ return this.upsert(data);
23
+ }
24
+ async delete(id) {
25
+ const result = this.drizzle.delete(this.table).where(eq(this.table.id, id)).run();
26
+ return result.changes > 0;
27
+ }
28
+ /* ─── 核心操作 ─── */
29
+ /** UPSERT — 按 (entityId, entityType, projectRoot) 唯一约束 */
30
+ async upsert(entity) {
31
+ const now = unixNow();
32
+ const protocolsJson = JSON.stringify(entity.protocols ?? []);
33
+ const metaJson = JSON.stringify(entity.metadata ?? {});
34
+ this.drizzle
35
+ .insert(this.table)
36
+ .values({
37
+ entityId: entity.entityId,
38
+ entityType: entity.entityType,
39
+ projectRoot: entity.projectRoot,
40
+ name: entity.name,
41
+ filePath: entity.filePath ?? null,
42
+ lineNumber: entity.lineNumber ?? null,
43
+ superclass: entity.superclass ?? null,
44
+ protocols: protocolsJson,
45
+ metadataJson: metaJson,
46
+ createdAt: now,
47
+ updatedAt: now,
48
+ })
49
+ .onConflictDoUpdate({
50
+ target: [this.table.entityId, this.table.entityType, this.table.projectRoot],
51
+ set: {
52
+ name: entity.name,
53
+ filePath: sql `${entity.filePath ?? null}`,
54
+ lineNumber: sql `${entity.lineNumber ?? null}`,
55
+ superclass: sql `${entity.superclass ?? null}`,
56
+ protocols: protocolsJson,
57
+ metadataJson: metaJson,
58
+ updatedAt: now,
59
+ },
60
+ })
61
+ .run();
62
+ // 返回 upserted 行
63
+ const rows = this.drizzle
64
+ .select()
65
+ .from(this.table)
66
+ .where(and(eq(this.table.entityId, entity.entityId), eq(this.table.entityType, entity.entityType), eq(this.table.projectRoot, entity.projectRoot)))
67
+ .limit(1)
68
+ .all();
69
+ return this.#mapRow(rows[0]);
70
+ }
71
+ /** 批量 UPSERT */
72
+ async batchUpsert(entities) {
73
+ if (entities.length === 0) {
74
+ return 0;
75
+ }
76
+ let upserted = 0;
77
+ this.transaction((tx) => {
78
+ const now = unixNow();
79
+ for (const entity of entities) {
80
+ tx.insert(this.table)
81
+ .values({
82
+ entityId: entity.entityId,
83
+ entityType: entity.entityType,
84
+ projectRoot: entity.projectRoot,
85
+ name: entity.name,
86
+ filePath: entity.filePath ?? null,
87
+ lineNumber: entity.lineNumber ?? null,
88
+ superclass: entity.superclass ?? null,
89
+ protocols: JSON.stringify(entity.protocols ?? []),
90
+ metadataJson: JSON.stringify(entity.metadata ?? {}),
91
+ createdAt: now,
92
+ updatedAt: now,
93
+ })
94
+ .onConflictDoUpdate({
95
+ target: [this.table.entityId, this.table.entityType, this.table.projectRoot],
96
+ set: {
97
+ name: entity.name,
98
+ filePath: sql `${entity.filePath ?? null}`,
99
+ lineNumber: sql `${entity.lineNumber ?? null}`,
100
+ superclass: sql `${entity.superclass ?? null}`,
101
+ protocols: JSON.stringify(entity.protocols ?? []),
102
+ metadataJson: JSON.stringify(entity.metadata ?? {}),
103
+ updatedAt: now,
104
+ },
105
+ })
106
+ .run();
107
+ upserted++;
108
+ }
109
+ });
110
+ return upserted;
111
+ }
112
+ /* ─── 查询 ─── */
113
+ /** 按文件路径查询 */
114
+ async findByFile(filePath, projectRoot) {
115
+ const rows = this.drizzle
116
+ .select()
117
+ .from(this.table)
118
+ .where(and(eq(this.table.filePath, filePath), eq(this.table.projectRoot, projectRoot)))
119
+ .all();
120
+ return rows.map((r) => this.#mapRow(r));
121
+ }
122
+ /** 按实体类型列表 */
123
+ async listByType(entityType, projectRoot, limit = 100) {
124
+ const rows = this.drizzle
125
+ .select()
126
+ .from(this.table)
127
+ .where(and(eq(this.table.entityType, entityType), eq(this.table.projectRoot, projectRoot)))
128
+ .orderBy(this.table.name)
129
+ .limit(limit)
130
+ .all();
131
+ return rows.map((r) => this.#mapRow(r));
132
+ }
133
+ /** 按名称搜索 */
134
+ async searchByName(query, projectRoot, options = {}) {
135
+ const { entityType, limit = 50 } = options;
136
+ const conditions = [
137
+ eq(this.table.projectRoot, projectRoot),
138
+ like(this.table.name, `%${query}%`),
139
+ ];
140
+ if (entityType) {
141
+ conditions.push(eq(this.table.entityType, entityType));
142
+ }
143
+ const rows = this.drizzle
144
+ .select()
145
+ .from(this.table)
146
+ .where(and(...conditions))
147
+ .orderBy(this.table.name)
148
+ .limit(limit)
149
+ .all();
150
+ return rows.map((r) => this.#mapRow(r));
151
+ }
152
+ /** 按 entityId + entityType + projectRoot 精确查找 */
153
+ async findByEntityId(entityId, entityType, projectRoot) {
154
+ const rows = this.drizzle
155
+ .select()
156
+ .from(this.table)
157
+ .where(and(eq(this.table.entityId, entityId), eq(this.table.entityType, entityType), eq(this.table.projectRoot, projectRoot)))
158
+ .limit(1)
159
+ .all();
160
+ return rows.length > 0 ? this.#mapRow(rows[0]) : null;
161
+ }
162
+ /** 删除指定项目的所有实体 */
163
+ async clearProject(projectRoot) {
164
+ const result = this.drizzle
165
+ .delete(this.table)
166
+ .where(eq(this.table.projectRoot, projectRoot))
167
+ .run();
168
+ return result.changes;
169
+ }
170
+ /** 删除指定文件的实体(用于增量更新调用图) */
171
+ async deleteByFile(filePath, projectRoot) {
172
+ const result = this.drizzle
173
+ .delete(this.table)
174
+ .where(and(eq(this.table.filePath, filePath), eq(this.table.projectRoot, projectRoot)))
175
+ .run();
176
+ return result.changes;
177
+ }
178
+ /** 获取实体总数 */
179
+ async getEntityCount(projectRoot) {
180
+ const condition = projectRoot ? eq(this.table.projectRoot, projectRoot) : undefined;
181
+ const [row] = this.drizzle.select({ cnt: count() }).from(this.table).where(condition).all();
182
+ return row?.cnt ?? 0;
183
+ }
184
+ /** 按类型统计实体数 */
185
+ async countByType(projectRoot) {
186
+ const rows = this.drizzle
187
+ .select({
188
+ entityType: this.table.entityType,
189
+ cnt: count(),
190
+ })
191
+ .from(this.table)
192
+ .where(eq(this.table.projectRoot, projectRoot))
193
+ .groupBy(this.table.entityType)
194
+ .all();
195
+ const result = {};
196
+ for (const row of rows) {
197
+ result[row.entityType] = row.cnt;
198
+ }
199
+ return result;
200
+ }
201
+ /** 按文件路径和实体类型删除 */
202
+ async deleteByFileAndType(filePath, entityType, projectRoot) {
203
+ const result = this.drizzle
204
+ .delete(this.table)
205
+ .where(and(eq(this.table.filePath, filePath), eq(this.table.entityType, entityType), eq(this.table.projectRoot, projectRoot)))
206
+ .run();
207
+ return result.changes;
208
+ }
209
+ /** 按 entityId + projectRoot 查找(不限 entityType) */
210
+ async findByEntityIdOnly(entityId, projectRoot) {
211
+ const rows = this.drizzle
212
+ .select()
213
+ .from(this.table)
214
+ .where(and(eq(this.table.entityId, entityId), eq(this.table.projectRoot, projectRoot)))
215
+ .limit(1)
216
+ .all();
217
+ return rows.length > 0 ? this.#mapRow(rows[0]) : null;
218
+ }
219
+ /* ─── Panorama 域查询 (Phase 5e) ─── */
220
+ /** 查询非 module 实体的 (entityId, filePath) 去重列表 */
221
+ async findDistinctEntityIdsWithFilePath(projectRoot) {
222
+ const rows = this.drizzle
223
+ .selectDistinct({
224
+ entityId: this.table.entityId,
225
+ filePath: this.table.filePath,
226
+ })
227
+ .from(this.table)
228
+ .where(and(eq(this.table.projectRoot, projectRoot), isNotNull(this.table.filePath), ne(this.table.entityType, 'module')))
229
+ .all();
230
+ return rows.filter((r) => r.filePath !== null);
231
+ }
232
+ /** 查询本地模块 (排除 external/host nodeType) */
233
+ async findLocalModules(projectRoot) {
234
+ const rows = this.drizzle
235
+ .selectDistinct({
236
+ entityId: this.table.entityId,
237
+ name: this.table.name,
238
+ })
239
+ .from(this.table)
240
+ .where(and(eq(this.table.entityType, 'module'), eq(this.table.projectRoot, projectRoot), sql `COALESCE(json_extract(${this.table.metadataJson}, '$.nodeType'), 'local') NOT IN ('external', 'host')`))
241
+ .all();
242
+ return rows;
243
+ }
244
+ /** 查询指定 nodeType 的模块实体 */
245
+ async findModulesByNodeTypes(projectRoot, nodeTypes) {
246
+ if (nodeTypes.length === 0) {
247
+ return [];
248
+ }
249
+ const placeholders = nodeTypes.map((t) => `'${t.replace(/'/g, "''")}'`).join(', ');
250
+ const rows = this.drizzle
251
+ .select()
252
+ .from(this.table)
253
+ .where(and(eq(this.table.entityType, 'module'), eq(this.table.projectRoot, projectRoot), sql `json_extract(${this.table.metadataJson}, '$.nodeType') IN (${sql.raw(placeholders)})`))
254
+ .all();
255
+ return rows.map((r) => this.#mapRow(r));
256
+ }
257
+ /** 统计指定 nodeType 的模块数量 */
258
+ async countModulesByNodeType(projectRoot, nodeType) {
259
+ const [row] = this.drizzle
260
+ .select({ cnt: count() })
261
+ .from(this.table)
262
+ .where(and(eq(this.table.entityType, 'module'), eq(this.table.projectRoot, projectRoot), sql `json_extract(${this.table.metadataJson}, '$.nodeType') = ${nodeType}`))
263
+ .all();
264
+ return row?.cnt ?? 0;
265
+ }
266
+ /** 按 projectRoot + filePaths 批量查询实体 */
267
+ async findByProjectAndFilePaths(projectRoot, filePaths) {
268
+ if (filePaths.length === 0) {
269
+ return [];
270
+ }
271
+ const rows = this.drizzle
272
+ .select()
273
+ .from(this.table)
274
+ .where(and(eq(this.table.projectRoot, projectRoot), inArray(this.table.filePath, filePaths)))
275
+ .all();
276
+ return rows.map((r) => this.#mapRow(r));
277
+ }
278
+ /** 查询非 module 实体的去重文件路径列表 */
279
+ async findDistinctFilePaths(projectRoot, limit = 2000) {
280
+ const rows = this.drizzle
281
+ .selectDistinct({ filePath: this.table.filePath })
282
+ .from(this.table)
283
+ .where(and(eq(this.table.projectRoot, projectRoot), isNotNull(this.table.filePath), ne(this.table.entityType, 'module')))
284
+ .limit(limit)
285
+ .all();
286
+ return rows.filter((r) => r.filePath !== null).map((r) => r.filePath);
287
+ }
288
+ /** 批量 INSERT OR IGNORE (不更新已存在的行) */
289
+ async batchInsertIgnore(entities) {
290
+ if (entities.length === 0) {
291
+ return 0;
292
+ }
293
+ let inserted = 0;
294
+ const now = unixNow();
295
+ this.transaction((tx) => {
296
+ for (const entity of entities) {
297
+ tx.insert(this.table)
298
+ .values({
299
+ entityId: entity.entityId,
300
+ entityType: entity.entityType,
301
+ projectRoot: entity.projectRoot,
302
+ name: entity.name,
303
+ filePath: entity.filePath ?? null,
304
+ lineNumber: entity.lineNumber ?? null,
305
+ superclass: entity.superclass ?? null,
306
+ protocols: JSON.stringify(entity.protocols ?? []),
307
+ metadataJson: JSON.stringify(entity.metadata ?? {}),
308
+ createdAt: now,
309
+ updatedAt: now,
310
+ })
311
+ .onConflictDoNothing()
312
+ .run();
313
+ inserted++;
314
+ }
315
+ });
316
+ return inserted;
317
+ }
318
+ /**
319
+ * 符号名是否存在 (ReverseGuard.#symbolExists)
320
+ */
321
+ existsByName(name) {
322
+ const row = this.drizzle
323
+ .select({ name: this.table.name })
324
+ .from(this.table)
325
+ .where(eq(this.table.name, name))
326
+ .limit(1)
327
+ .get();
328
+ return row != null;
329
+ }
330
+ /* ─── 内部辅助 ─── */
331
+ #mapRow(row) {
332
+ let protocols = [];
333
+ let metadata = {};
334
+ try {
335
+ protocols = JSON.parse(row.protocols ?? '[]');
336
+ }
337
+ catch {
338
+ /* ignore */
339
+ }
340
+ try {
341
+ metadata = JSON.parse(row.metadataJson ?? '{}');
342
+ }
343
+ catch {
344
+ /* ignore */
345
+ }
346
+ return {
347
+ id: row.id,
348
+ entityId: row.entityId,
349
+ entityType: row.entityType,
350
+ projectRoot: row.projectRoot,
351
+ name: row.name,
352
+ filePath: row.filePath,
353
+ lineNumber: row.lineNumber,
354
+ superclass: row.superclass,
355
+ protocols,
356
+ metadata,
357
+ createdAt: row.createdAt,
358
+ updatedAt: row.updatedAt,
359
+ };
360
+ }
361
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * DeliveryRepoAdapter — CursorDeliveryPipeline 用的仓储适配器
3
+ *
4
+ * 将 call graph 分析中的 raw SQL 查询封装在 lib/repository/ 层。
5
+ */
6
+ type RawDb = {
7
+ prepare(sql: string): {
8
+ all(...args: unknown[]): Array<Record<string, unknown>>;
9
+ };
10
+ };
11
+ /** CursorDeliveryPipeline call graph 分析所需的最小接口 */
12
+ export interface CallGraphRepo {
13
+ /** 查询 phase5 调用边 */
14
+ findCallEdges(): Array<{
15
+ from_id: string;
16
+ to_id: string;
17
+ metadata_json: string;
18
+ }>;
19
+ /** 查询方法级代码实体的 entity_id + file_path */
20
+ findMethodEntities(): Array<{
21
+ entity_id: string;
22
+ file_path: string;
23
+ }>;
24
+ }
25
+ /** Raw-db 适配器:实现 CallGraphRepo 接口 */
26
+ export declare class RawDbCallGraphAdapter implements CallGraphRepo {
27
+ #private;
28
+ constructor(db: RawDb);
29
+ findCallEdges(): Array<{
30
+ from_id: string;
31
+ to_id: string;
32
+ metadata_json: string;
33
+ }>;
34
+ findMethodEntities(): Array<{
35
+ entity_id: string;
36
+ file_path: string;
37
+ }>;
38
+ }
39
+ export {};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * DeliveryRepoAdapter — CursorDeliveryPipeline 用的仓储适配器
3
+ *
4
+ * 将 call graph 分析中的 raw SQL 查询封装在 lib/repository/ 层。
5
+ */
6
+ /** Raw-db 适配器:实现 CallGraphRepo 接口 */
7
+ export class RawDbCallGraphAdapter {
8
+ #db;
9
+ constructor(db) {
10
+ this.#db = db;
11
+ }
12
+ findCallEdges() {
13
+ return this.#db
14
+ .prepare(`SELECT from_id, to_id, metadata_json FROM knowledge_edges
15
+ WHERE relation = 'calls' AND metadata_json LIKE '%phase5%'`)
16
+ .all();
17
+ }
18
+ findMethodEntities() {
19
+ return this.#db
20
+ .prepare(`SELECT entity_id, file_path FROM code_entities WHERE entity_type = 'method'`)
21
+ .all();
22
+ }
23
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * LifecycleEventRepository — lifecycle_transition_events 表 CRUD (Drizzle ORM)
3
+ *
4
+ * 操作 lifecycle_transition_events 表,存储 Recipe 生命周期状态转移事件。
5
+ *
6
+ * Drizzle 迁移策略:
7
+ * - 替代 RecipeLifecycleSupervisor 中的所有 rawDb.prepare() 调用
8
+ * - 消除 12 个 escape-hatch 注解
9
+ */
10
+ import type { DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
11
+ import type { TransitionEvent, TransitionEvidence } from '../../types/evolution.js';
12
+ export interface RecordEventInput {
13
+ id: string;
14
+ recipeId: string;
15
+ fromState: string;
16
+ toState: string;
17
+ trigger: string;
18
+ operatorId: string;
19
+ evidence: TransitionEvidence | null;
20
+ proposalId: string | null;
21
+ createdAt: number;
22
+ }
23
+ export interface TransitionEventRow {
24
+ id: string;
25
+ recipeId: string;
26
+ fromState: string;
27
+ toState: string;
28
+ trigger: TransitionEvent['trigger'];
29
+ operatorId: string;
30
+ evidence: TransitionEvidence | null;
31
+ proposalId: string | null;
32
+ createdAt: number;
33
+ }
34
+ export declare class LifecycleEventRepository {
35
+ #private;
36
+ constructor(drizzle: DrizzleDB);
37
+ record(input: RecordEventInput): void;
38
+ /** 获取指定 Recipe 的转移历史(按时间倒序) */
39
+ getHistory(recipeId: string, limit?: number): TransitionEvent[];
40
+ /** 统计指定时间之后的事件数量 */
41
+ countSince(since: number): number;
42
+ /** 按 trigger 分组统计(限定时间窗口,按数量倒序前 N) */
43
+ topTriggersSince(since: number, limit?: number): {
44
+ trigger: string;
45
+ count: number;
46
+ }[];
47
+ /** 按 trigger 值统计数量 */
48
+ countByTrigger(trigger: string): number;
49
+ /** 按多个 trigger 值统计数量 */
50
+ countByTriggers(triggers: string[]): number;
51
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * LifecycleEventRepository — lifecycle_transition_events 表 CRUD (Drizzle ORM)
3
+ *
4
+ * 操作 lifecycle_transition_events 表,存储 Recipe 生命周期状态转移事件。
5
+ *
6
+ * Drizzle 迁移策略:
7
+ * - 替代 RecipeLifecycleSupervisor 中的所有 rawDb.prepare() 调用
8
+ * - 消除 12 个 escape-hatch 注解
9
+ */
10
+ import { count, desc, eq, gt, sql } from 'drizzle-orm';
11
+ import { lifecycleTransitionEvents } from '../../infrastructure/database/drizzle/schema.js';
12
+ /* ────────────────────── Class ────────────────────── */
13
+ export class LifecycleEventRepository {
14
+ #drizzle;
15
+ constructor(drizzle) {
16
+ this.#drizzle = drizzle;
17
+ }
18
+ /* ═══════════════════ Write ═══════════════════ */
19
+ record(input) {
20
+ this.#drizzle
21
+ .insert(lifecycleTransitionEvents)
22
+ .values({
23
+ id: input.id,
24
+ recipeId: input.recipeId,
25
+ fromState: input.fromState,
26
+ toState: input.toState,
27
+ trigger: input.trigger,
28
+ operatorId: input.operatorId,
29
+ evidenceJson: input.evidence ? JSON.stringify(input.evidence) : null,
30
+ proposalId: input.proposalId,
31
+ createdAt: input.createdAt,
32
+ })
33
+ .run();
34
+ }
35
+ /* ═══════════════════ Read ═══════════════════ */
36
+ /** 获取指定 Recipe 的转移历史(按时间倒序) */
37
+ getHistory(recipeId, limit = 50) {
38
+ const rows = this.#drizzle
39
+ .select()
40
+ .from(lifecycleTransitionEvents)
41
+ .where(eq(lifecycleTransitionEvents.recipeId, recipeId))
42
+ .orderBy(desc(lifecycleTransitionEvents.createdAt))
43
+ .limit(limit)
44
+ .all();
45
+ return rows.map((r) => this.#mapRow(r));
46
+ }
47
+ /** 统计指定时间之后的事件数量 */
48
+ countSince(since) {
49
+ const result = this.#drizzle
50
+ .select({ cnt: count() })
51
+ .from(lifecycleTransitionEvents)
52
+ .where(gt(lifecycleTransitionEvents.createdAt, since))
53
+ .get();
54
+ return result?.cnt ?? 0;
55
+ }
56
+ /** 按 trigger 分组统计(限定时间窗口,按数量倒序前 N) */
57
+ topTriggersSince(since, limit = 5) {
58
+ const rows = this.#drizzle
59
+ .select({
60
+ trigger: lifecycleTransitionEvents.trigger,
61
+ cnt: count(),
62
+ })
63
+ .from(lifecycleTransitionEvents)
64
+ .where(gt(lifecycleTransitionEvents.createdAt, since))
65
+ .groupBy(lifecycleTransitionEvents.trigger)
66
+ .orderBy(sql `count(*) desc`)
67
+ .limit(limit)
68
+ .all();
69
+ return rows.map((r) => ({ trigger: r.trigger, count: r.cnt }));
70
+ }
71
+ /** 按 trigger 值统计数量 */
72
+ countByTrigger(trigger) {
73
+ const result = this.#drizzle
74
+ .select({ cnt: count() })
75
+ .from(lifecycleTransitionEvents)
76
+ .where(eq(lifecycleTransitionEvents.trigger, trigger))
77
+ .get();
78
+ return result?.cnt ?? 0;
79
+ }
80
+ /** 按多个 trigger 值统计数量 */
81
+ countByTriggers(triggers) {
82
+ if (triggers.length === 0) {
83
+ return 0;
84
+ }
85
+ // Build OR condition for multiple triggers
86
+ const result = this.#drizzle
87
+ .select({ cnt: count() })
88
+ .from(lifecycleTransitionEvents)
89
+ .where(sql `${lifecycleTransitionEvents.trigger} IN (${sql.join(triggers.map((t) => sql `${t}`), sql `, `)})`)
90
+ .get();
91
+ return result?.cnt ?? 0;
92
+ }
93
+ /* ═══════════════════ Internal ═══════════════════ */
94
+ #mapRow(row) {
95
+ return {
96
+ id: row.id,
97
+ recipeId: row.recipeId,
98
+ fromState: row.fromState,
99
+ toState: row.toState,
100
+ trigger: row.trigger,
101
+ operatorId: row.operatorId,
102
+ evidence: row.evidenceJson ? safeJsonParse(row.evidenceJson, null) : null,
103
+ proposalId: row.proposalId ?? null,
104
+ createdAt: row.createdAt,
105
+ };
106
+ }
107
+ }
108
+ /* ────────────────────── Util ────────────────────── */
109
+ function safeJsonParse(json, fallback) {
110
+ if (!json) {
111
+ return fallback;
112
+ }
113
+ try {
114
+ return JSON.parse(json);
115
+ }
116
+ catch {
117
+ return fallback;
118
+ }
119
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * ProposalRepository — evolution_proposals 表 CRUD
2
+ * ProposalRepository — evolution_proposals 表 CRUD (Drizzle ORM)
3
3
  *
4
4
  * 操作 evolution_proposals 表,存储进化提案(merge/supersede/enhance/deprecate/
5
5
  * reorganize/contradiction/correction)。
@@ -8,16 +8,12 @@
8
8
  * - 去重:同 target + 同 type 不允许多个 observing 状态的 Proposal
9
9
  * - Rate Limit:同一 target 不允许同时存在多个相同类型的 observing Proposal
10
10
  * - JSON 字段(evidence/related_recipe_ids)序列化/反序列化
11
+ *
12
+ * Drizzle 迁移策略 (Phase 5a):
13
+ * - 全部 raw SQL → Drizzle 类型安全 API
14
+ * - 构造器接收 DrizzleDB(不再需要 raw Database)
11
15
  */
12
- interface DatabaseLike {
13
- prepare(sql: string): {
14
- all(...params: unknown[]): Record<string, unknown>[];
15
- get(...params: unknown[]): Record<string, unknown> | undefined;
16
- run(...params: unknown[]): {
17
- changes: number;
18
- };
19
- };
20
- }
16
+ import type { DrizzleDB } from '../../infrastructure/database/drizzle/index.js';
21
17
  /** Proposal 类型 — 统一标准 */
22
18
  export type ProposalType = 'merge' | 'supersede' | 'enhance' | 'deprecate' | 'reorganize' | 'contradiction' | 'correction';
23
19
  /** Proposal 来源 */
@@ -63,7 +59,7 @@ export interface ProposalFilter {
63
59
  }
64
60
  export declare class ProposalRepository {
65
61
  #private;
66
- constructor(db: DatabaseLike);
62
+ constructor(drizzle: DrizzleDB);
67
63
  /**
68
64
  * 创建 Proposal 并写入 DB。
69
65
  *
@@ -93,7 +89,8 @@ export declare class ProposalRepository {
93
89
  markExpired(id: string): boolean;
94
90
  /** 更新 evidence(用于追加观察期指标快照) */
95
91
  updateEvidence(id: string, evidence: Record<string, unknown>[]): boolean;
92
+ /** 按 target Recipe ID 删除所有 Proposal(用于知识删除时清理关联提案) */
93
+ deleteByTargetRecipeId(targetRecipeId: string): number;
96
94
  /** 统计各状态的 Proposal 数量 */
97
95
  stats(): Record<ProposalStatus, number>;
98
96
  }
99
- export {};