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
@@ -8,12 +8,16 @@
8
8
  * 4. 提供增量 diff 计算
9
9
  *
10
10
  * 存储: SQLite bootstrap_snapshots + bootstrap_dim_files 表
11
+ * 所有操作使用 Drizzle 类型安全 API。
11
12
  *
12
13
  * @module pipeline/BootstrapSnapshot
13
14
  */
14
15
  import { createHash, randomUUID } from 'node:crypto';
15
16
  import { readFileSync } from 'node:fs';
16
17
  import { relative } from 'node:path';
18
+ import { and, desc, eq, sql } from 'drizzle-orm';
19
+ import { getDrizzle } from '../../../../../infrastructure/database/drizzle/index.js';
20
+ import { bootstrapDimFiles, bootstrapSnapshots, } from '../../../../../infrastructure/database/drizzle/schema.js';
17
21
  // ──────────────────────────────────────────────────────────────
18
22
  // 常量
19
23
  // ──────────────────────────────────────────────────────────────
@@ -25,21 +29,18 @@ const FULL_REBUILD_THRESHOLD = 0.5;
25
29
  // BootstrapSnapshot 类
26
30
  // ──────────────────────────────────────────────────────────────
27
31
  export class BootstrapSnapshot {
28
- #db;
32
+ #drizzle;
29
33
  #logger;
30
- #stmts;
31
- /** @param db better-sqlite3 实例 */
34
+ /** @param db DatabaseConnection 或 better-sqlite3 实例 */
32
35
  constructor(db, { logger } = {}) {
33
36
  if (!db) {
34
37
  throw new Error('BootstrapSnapshot requires a database instance');
35
38
  }
36
- this.#db =
37
- typeof db?.getDb === 'function'
38
- ? db.getDb()
39
- : db;
39
+ this.#drizzle =
40
+ typeof db?.getDrizzle === 'function'
41
+ ? db.getDrizzle()
42
+ : getDrizzle();
40
43
  this.#logger = logger || null;
41
- this.#ensureTable();
42
- this.#prepareStatements();
43
44
  }
44
45
  // ─── 快照保存 ─────────────────────────────────────────
45
46
  /**
@@ -77,28 +78,30 @@ export class BootstrapSnapshot {
77
78
  durationMs: stat.durationMs || 0,
78
79
  };
79
80
  }
80
- // 事务保存
81
- const saveTransaction = this.#db.transaction(() => {
81
+ // 事务保存(Drizzle 类型安全)
82
+ this.#drizzle.transaction((tx) => {
82
83
  // 主记录
83
- this.#stmts.insertSnapshot.run({
84
+ tx.insert(bootstrapSnapshots)
85
+ .values({
84
86
  id,
85
- session_id: sessionId || null,
86
- project_root: projectRoot,
87
- created_at: now,
88
- duration_ms: meta.durationMs || 0,
89
- file_count: allFiles.length,
90
- dimension_count: Object.keys(dimensionStats || {}).length,
91
- candidate_count: meta.candidateCount || 0,
92
- primary_lang: meta.primaryLang || null,
93
- file_hashes: JSON.stringify(fileHashes),
94
- dimension_meta: JSON.stringify(dimensionMeta),
95
- episodic_data: episodicData ? JSON.stringify(episodicData) : null,
96
- is_incremental: isIncremental ? 1 : 0,
97
- parent_id: parentId,
98
- changed_files: JSON.stringify(changedFiles),
99
- affected_dims: JSON.stringify(affectedDims),
87
+ sessionId: sessionId || null,
88
+ projectRoot,
89
+ createdAt: now,
90
+ durationMs: meta.durationMs || 0,
91
+ fileCount: allFiles.length,
92
+ dimensionCount: Object.keys(dimensionStats || {}).length,
93
+ candidateCount: meta.candidateCount || 0,
94
+ primaryLang: meta.primaryLang || null,
95
+ fileHashes: JSON.stringify(fileHashes),
96
+ dimensionMeta: JSON.stringify(dimensionMeta),
97
+ episodicData: episodicData ? JSON.stringify(episodicData) : null,
98
+ isIncremental: isIncremental ? 1 : 0,
99
+ parentId: parentId,
100
+ changedFiles: JSON.stringify(changedFiles),
101
+ affectedDims: JSON.stringify(affectedDims),
100
102
  status: 'complete',
101
- });
103
+ })
104
+ .run();
102
105
  // 维度-文件关联
103
106
  for (const [dimId, stat] of Object.entries(dimensionStats || {})) {
104
107
  const refFiles = stat.referencedFilesList || [];
@@ -108,18 +111,20 @@ export class BootstrapSnapshot {
108
111
  ? relative(projectRoot, filePath)
109
112
  : filePath
110
113
  : filePath;
111
- this.#stmts.insertDimFile.run({
112
- snapshot_id: id,
113
- dim_id: dimId,
114
- file_path: rel,
114
+ tx.insert(bootstrapDimFiles)
115
+ .values({
116
+ snapshotId: id,
117
+ dimId,
118
+ filePath: rel,
115
119
  role: 'referenced',
116
- });
120
+ })
121
+ .onConflictDoNothing()
122
+ .run();
117
123
  }
118
124
  }
119
125
  // 容量控制: 保留最新 N 个
120
- this.#enforceCapacity(projectRoot);
126
+ this.#enforceCapacity(projectRoot, tx);
121
127
  });
122
- saveTransaction();
123
128
  this.#log(`Snapshot saved: ${id} (${allFiles.length} files, ${Object.keys(dimensionStats || {}).length} dims)`);
124
129
  return id;
125
130
  }
@@ -127,9 +132,13 @@ export class BootstrapSnapshot {
127
132
  /** 清除项目的所有快照 — 用于手动重新冷启动时强制全量 */
128
133
  clearProject(projectRoot) {
129
134
  try {
130
- const rows = this.#stmts.listByProject.all(projectRoot, 9999);
135
+ const rows = this.#drizzle
136
+ .select({ id: bootstrapSnapshots.id })
137
+ .from(bootstrapSnapshots)
138
+ .where(eq(bootstrapSnapshots.projectRoot, projectRoot))
139
+ .all();
131
140
  for (const row of rows) {
132
- this.#stmts.deleteById.run(row.id);
141
+ this.#drizzle.delete(bootstrapSnapshots).where(eq(bootstrapSnapshots.id, row.id)).run();
133
142
  }
134
143
  this.#log(`Cleared ${rows.length} snapshots for project`);
135
144
  }
@@ -144,7 +153,13 @@ export class BootstrapSnapshot {
144
153
  * @returns 快照数据
145
154
  */
146
155
  getLatest(projectRoot) {
147
- const row = this.#stmts.getLatest.get(projectRoot);
156
+ const row = this.#drizzle
157
+ .select()
158
+ .from(bootstrapSnapshots)
159
+ .where(and(eq(bootstrapSnapshots.projectRoot, projectRoot), eq(bootstrapSnapshots.status, 'complete')))
160
+ .orderBy(desc(bootstrapSnapshots.createdAt))
161
+ .limit(1)
162
+ .get();
148
163
  if (!row) {
149
164
  return null;
150
165
  }
@@ -152,7 +167,11 @@ export class BootstrapSnapshot {
152
167
  }
153
168
  /** 根据 ID 加载快照 */
154
169
  getById(id) {
155
- const row = this.#stmts.getById.get(id);
170
+ const row = this.#drizzle
171
+ .select()
172
+ .from(bootstrapSnapshots)
173
+ .where(eq(bootstrapSnapshots.id, id))
174
+ .get();
156
175
  if (!row) {
157
176
  return null;
158
177
  }
@@ -160,8 +179,13 @@ export class BootstrapSnapshot {
160
179
  }
161
180
  /** 获取项目的所有快照 (按时间降序) */
162
181
  list(projectRoot, limit = 10) {
163
- return this.#stmts.listByProject
164
- .all(projectRoot, limit)
182
+ return this.#drizzle
183
+ .select()
184
+ .from(bootstrapSnapshots)
185
+ .where(eq(bootstrapSnapshots.projectRoot, projectRoot))
186
+ .orderBy(desc(bootstrapSnapshots.createdAt))
187
+ .limit(limit)
188
+ .all()
165
189
  .map((r) => this.#deserialize(r));
166
190
  }
167
191
  // ─── 增量 Diff 计算 ──────────────────────────────────
@@ -277,13 +301,20 @@ export class BootstrapSnapshot {
277
301
  // ─── 维度-文件映射查询 ──────────────────────────────
278
302
  /** 获取某个快照中每个维度引用的文件集合 */
279
303
  #getDimFileMap(snapshotId) {
280
- const rows = this.#stmts.getDimFiles.all(snapshotId);
304
+ const rows = this.#drizzle
305
+ .select({
306
+ dimId: bootstrapDimFiles.dimId,
307
+ filePath: bootstrapDimFiles.filePath,
308
+ })
309
+ .from(bootstrapDimFiles)
310
+ .where(eq(bootstrapDimFiles.snapshotId, snapshotId))
311
+ .all();
281
312
  const map = {};
282
313
  for (const row of rows) {
283
- if (!map[row.dim_id]) {
284
- map[row.dim_id] = new Set();
314
+ if (!map[row.dimId]) {
315
+ map[row.dimId] = new Set();
285
316
  }
286
- map[row.dim_id].add(row.file_path);
317
+ map[row.dimId].add(row.filePath);
287
318
  }
288
319
  return map;
289
320
  }
@@ -367,9 +398,17 @@ export class BootstrapSnapshot {
367
398
  return '';
368
399
  }
369
400
  }
370
- #enforceCapacity(projectRoot) {
401
+ #enforceCapacity(projectRoot, db = this.#drizzle) {
371
402
  try {
372
- this.#stmts.enforceCapacity.run(projectRoot, projectRoot, MAX_SNAPSHOTS);
403
+ db.delete(bootstrapSnapshots)
404
+ .where(sql `${bootstrapSnapshots.projectRoot} = ${projectRoot}
405
+ AND ${bootstrapSnapshots.id} NOT IN (
406
+ SELECT ${bootstrapSnapshots.id} FROM ${bootstrapSnapshots}
407
+ WHERE ${bootstrapSnapshots.projectRoot} = ${projectRoot}
408
+ ORDER BY ${bootstrapSnapshots.createdAt} DESC
409
+ LIMIT ${MAX_SNAPSHOTS}
410
+ )`)
411
+ .run();
373
412
  }
374
413
  catch (err) {
375
414
  const msg = err instanceof Error ? err.message : String(err);
@@ -379,22 +418,22 @@ export class BootstrapSnapshot {
379
418
  #deserialize(row) {
380
419
  return {
381
420
  id: row.id,
382
- sessionId: row.session_id ?? null,
383
- projectRoot: row.project_root,
384
- createdAt: row.created_at,
385
- durationMs: row.duration_ms,
386
- fileCount: row.file_count,
387
- dimensionCount: row.dimension_count,
388
- candidateCount: row.candidate_count,
389
- primaryLang: row.primary_lang ?? null,
390
- fileHashes: this.#safeParseJSON(row.file_hashes, {}),
391
- dimensionMeta: this.#safeParseJSON(row.dimension_meta, {}),
392
- episodicData: this.#safeParseJSON(row.episodic_data, null),
393
- isIncremental: !!row.is_incremental,
394
- parentId: row.parent_id ?? null,
395
- changedFiles: this.#safeParseJSON(row.changed_files, []),
396
- affectedDims: this.#safeParseJSON(row.affected_dims, []),
397
- status: row.status,
421
+ sessionId: row.sessionId ?? null,
422
+ projectRoot: row.projectRoot,
423
+ createdAt: row.createdAt,
424
+ durationMs: row.durationMs ?? 0,
425
+ fileCount: row.fileCount ?? 0,
426
+ dimensionCount: row.dimensionCount ?? 0,
427
+ candidateCount: row.candidateCount ?? 0,
428
+ primaryLang: row.primaryLang ?? null,
429
+ fileHashes: this.#safeParseJSON(row.fileHashes, {}),
430
+ dimensionMeta: this.#safeParseJSON(row.dimensionMeta, {}),
431
+ episodicData: this.#safeParseJSON(row.episodicData, null),
432
+ isIncremental: !!row.isIncremental,
433
+ parentId: row.parentId ?? null,
434
+ changedFiles: this.#safeParseJSON(row.changedFiles, []),
435
+ affectedDims: this.#safeParseJSON(row.affectedDims, []),
436
+ status: row.status ?? 'complete',
398
437
  };
399
438
  }
400
439
  #safeParseJSON(str, fallback) {
@@ -410,95 +449,5 @@ export class BootstrapSnapshot {
410
449
  this.#logger[level](`[BootstrapSnapshot] ${msg}`);
411
450
  }
412
451
  }
413
- // ─── 初始化 ───────────────────────────────────────────
414
- #ensureTable() {
415
- this.#db.exec(`
416
- CREATE TABLE IF NOT EXISTS bootstrap_snapshots (
417
- id TEXT PRIMARY KEY,
418
- session_id TEXT,
419
- project_root TEXT NOT NULL,
420
- created_at TEXT NOT NULL,
421
- duration_ms INTEGER DEFAULT 0,
422
- file_count INTEGER DEFAULT 0,
423
- dimension_count INTEGER DEFAULT 0,
424
- candidate_count INTEGER DEFAULT 0,
425
- primary_lang TEXT,
426
- file_hashes TEXT NOT NULL DEFAULT '{}',
427
- dimension_meta TEXT NOT NULL DEFAULT '{}',
428
- episodic_data TEXT,
429
- is_incremental INTEGER DEFAULT 0,
430
- parent_id TEXT,
431
- changed_files TEXT DEFAULT '[]',
432
- affected_dims TEXT DEFAULT '[]',
433
- status TEXT DEFAULT 'complete'
434
- );
435
-
436
- CREATE TABLE IF NOT EXISTS bootstrap_dim_files (
437
- snapshot_id TEXT NOT NULL,
438
- dim_id TEXT NOT NULL,
439
- file_path TEXT NOT NULL,
440
- role TEXT DEFAULT 'referenced',
441
- PRIMARY KEY (snapshot_id, dim_id, file_path),
442
- FOREIGN KEY (snapshot_id) REFERENCES bootstrap_snapshots(id) ON DELETE CASCADE
443
- );
444
-
445
- CREATE INDEX IF NOT EXISTS idx_snapshots_project
446
- ON bootstrap_snapshots(project_root, created_at DESC);
447
- CREATE INDEX IF NOT EXISTS idx_dim_files_file
448
- ON bootstrap_dim_files(file_path);
449
- `);
450
- }
451
- #prepareStatements() {
452
- this.#stmts = {
453
- insertSnapshot: this.#db.prepare(`
454
- INSERT INTO bootstrap_snapshots
455
- (id, session_id, project_root, created_at, duration_ms,
456
- file_count, dimension_count, candidate_count, primary_lang,
457
- file_hashes, dimension_meta, episodic_data,
458
- is_incremental, parent_id, changed_files, affected_dims, status)
459
- VALUES
460
- (@id, @session_id, @project_root, @created_at, @duration_ms,
461
- @file_count, @dimension_count, @candidate_count, @primary_lang,
462
- @file_hashes, @dimension_meta, @episodic_data,
463
- @is_incremental, @parent_id, @changed_files, @affected_dims, @status)
464
- `),
465
- insertDimFile: this.#db.prepare(`
466
- INSERT OR IGNORE INTO bootstrap_dim_files (snapshot_id, dim_id, file_path, role)
467
- VALUES (@snapshot_id, @dim_id, @file_path, @role)
468
- `),
469
- getLatest: this.#db.prepare(`
470
- SELECT * FROM bootstrap_snapshots
471
- WHERE project_root = ? AND status = 'complete'
472
- ORDER BY created_at DESC
473
- LIMIT 1
474
- `),
475
- getById: this.#db.prepare(`
476
- SELECT * FROM bootstrap_snapshots WHERE id = ?
477
- `),
478
- listByProject: this.#db.prepare(`
479
- SELECT * FROM bootstrap_snapshots
480
- WHERE project_root = ?
481
- ORDER BY created_at DESC
482
- LIMIT ?
483
- `),
484
- getDimFiles: this.#db.prepare(`
485
- SELECT dim_id, file_path FROM bootstrap_dim_files
486
- WHERE snapshot_id = ?
487
- `),
488
- enforceCapacity: this.#db.prepare(`
489
- DELETE FROM bootstrap_snapshots
490
- WHERE project_root = ?
491
- AND id NOT IN (
492
- SELECT id FROM bootstrap_snapshots
493
- WHERE project_root = ?
494
- ORDER BY created_at DESC
495
- LIMIT ?
496
- )
497
- `),
498
- deleteById: this.#db.prepare(`
499
- DELETE FROM bootstrap_snapshots WHERE id = ?
500
- `),
501
- };
502
- }
503
452
  }
504
453
  export default BootstrapSnapshot;
@@ -20,6 +20,7 @@ import { ExplorationTracker } from '#agent/context/ExplorationTracker.js';
20
20
  import { EpisodicConsolidator } from '#agent/domain/EpisodicConsolidator.js';
21
21
  import { ANALYST_BUDGET } from '#agent/domain/insight-analyst.js';
22
22
  import { MemoryCoordinator } from '#agent/memory/MemoryCoordinator.js';
23
+ import { MemoryEmbeddingStore } from '#agent/memory/MemoryEmbeddingStore.js';
23
24
  import { PersistentMemory } from '#agent/memory/PersistentMemory.js';
24
25
  import { SessionStore } from '#agent/memory/SessionStore.js';
25
26
  import { PRESETS } from '#agent/presets.js';
@@ -159,7 +160,7 @@ export async function fillDimensionsV3(view, dimensions) {
159
160
  timeoutMs: 15_000,
160
161
  })) ?? null;
161
162
  if (projectGraph) {
162
- const overview = projectGraph.getOverview();
163
+ const overview = await projectGraph.getOverview();
163
164
  logger.info(`[Insight-v3] ProjectGraph: ${overview.totalClasses} classes, ${overview.totalProtocols} protocols (${overview.buildTimeMs}ms)`);
164
165
  }
165
166
  }
@@ -233,7 +234,11 @@ export async function fillDimensionsV3(view, dimensions) {
233
234
  catch {
234
235
  // EmbedProvider 不可用时 fallback 到无向量模式
235
236
  }
236
- semanticMemory = new PersistentMemory(db, { logger, embeddingFn });
237
+ semanticMemory = new PersistentMemory(db, {
238
+ logger,
239
+ embeddingFn,
240
+ embeddingStore: new MemoryEmbeddingStore(projectRoot),
241
+ });
237
242
  const smStats = semanticMemory.getStats();
238
243
  if (smStats.total > 0) {
239
244
  logger.info(`[Insight-v3] Loaded ${smStats.total} semantic memories from previous bootstrap ` +
@@ -248,10 +253,11 @@ export async function fillDimensionsV3(view, dimensions) {
248
253
  let codeEntityGraphInst = null;
249
254
  try {
250
255
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
251
- const db = ctx.container.get('database');
252
- if (db) {
253
- codeEntityGraphInst = new CodeEntityGraph(db, { projectRoot, logger });
254
- const topo = codeEntityGraphInst.getTopology();
256
+ const entityRepo = ctx.container.get('codeEntityRepository');
257
+ const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
258
+ if (entityRepo && edgeRepo) {
259
+ codeEntityGraphInst = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
260
+ const topo = await codeEntityGraphInst.getTopology();
255
261
  if (topo.totalEntities > 0) {
256
262
  logger.info(`[Insight-v3] CodeEntityGraph: ${topo.totalEntities} entities, ${topo.totalEdges} edges`);
257
263
  }
@@ -319,6 +325,7 @@ export async function fillDimensionsV3(view, dimensions) {
319
325
  // ── 跨维度去重集合 (实例级持久化,等效旧 ChatAgent.#globalSubmittedTitles/Patterns) ──
320
326
  const globalSubmittedTitles = new Set();
321
327
  const globalSubmittedPatterns = new Set();
328
+ const globalSubmittedTriggers = new Set();
322
329
  // ── Rescan 模式: 预种已有 recipe 标题到去重集合,防止重复创建 ──
323
330
  const existingRecipesList = existingRecipes;
324
331
  if (existingRecipesList && existingRecipesList.length > 0) {
@@ -327,8 +334,12 @@ export async function fillDimensionsV3(view, dimensions) {
327
334
  if (r.title && r.status !== 'decaying') {
328
335
  globalSubmittedTitles.add(r.title.toLowerCase().trim());
329
336
  }
337
+ // ★ trigger 全部预种(含 decaying),防止 trigger 冲突
338
+ if (r.trigger) {
339
+ globalSubmittedTriggers.add(r.trigger.toLowerCase().trim());
340
+ }
330
341
  }
331
- logger.info(`[Insight-v3] Rescan mode: seeded ${globalSubmittedTitles.size} existing recipe titles into dedup set`);
342
+ logger.info(`[Insight-v3] Rescan mode: seeded ${globalSubmittedTitles.size} titles + ${globalSubmittedTriggers.size} triggers into dedup set`);
332
343
  }
333
344
  // 构建 rescanContext 供 Analyst/Producer prompt 使用(区分 healthy/decaying)
334
345
  const rescanContext = existingRecipesList
@@ -597,6 +608,7 @@ export async function fillDimensionsV3(view, dimensions) {
597
608
  sharedState: {
598
609
  submittedTitles: globalSubmittedTitles,
599
610
  submittedPatterns: globalSubmittedPatterns,
611
+ submittedTriggers: globalSubmittedTriggers,
600
612
  _dimensionMeta: {
601
613
  id: dimId,
602
614
  outputType: dimConfig.outputType || 'candidate',
@@ -994,9 +1006,10 @@ export async function fillDimensionsV3(view, dimensions) {
994
1006
  // ═══════════════════════════════════════════════════════════
995
1007
  try {
996
1008
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
997
- const db = ctx.container.get('database');
998
- if (db) {
999
- const ceg = new CodeEntityGraph(db, { projectRoot, logger });
1009
+ const entityRepo = ctx.container.get('codeEntityRepository');
1010
+ const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
1011
+ if (entityRepo && edgeRepo) {
1012
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
1000
1013
  // 收集所有维度产出的候选 (从 Producer toolCalls 中提取)
1001
1014
  const allCandidates = [];
1002
1015
  for (const dimData of Object.values(dimensionCandidates)) {
@@ -1015,7 +1028,7 @@ export async function fillDimensionsV3(view, dimensions) {
1015
1028
  }
1016
1029
  }
1017
1030
  if (allCandidates.length > 0) {
1018
- const relResult = ceg.populateFromCandidateRelations(allCandidates);
1031
+ const relResult = await ceg.populateFromCandidateRelations(allCandidates);
1019
1032
  logger.info(`[Insight-v3] Code Entity Graph relations: ${relResult.edgesCreated} edges from ${allCandidates.length} candidates (${relResult.durationMs}ms)`);
1020
1033
  }
1021
1034
  }
@@ -1033,7 +1046,10 @@ export async function fillDimensionsV3(view, dimensions) {
1033
1046
  try {
1034
1047
  const db = ctx.container.get('database');
1035
1048
  if (db) {
1036
- const semanticMemory = new PersistentMemory(db, { logger });
1049
+ const semanticMemory = new PersistentMemory(db, {
1050
+ logger,
1051
+ embeddingStore: new MemoryEmbeddingStore(projectRoot),
1052
+ });
1037
1053
  const consolidator = new EpisodicConsolidator(semanticMemory, { logger });
1038
1054
  consolidationResult = consolidator.consolidate(sessionStore, {
1039
1055
  bootstrapSession: sessionId,
@@ -1152,10 +1168,11 @@ export async function fillDimensionsV3(view, dimensions) {
1152
1168
  // Phase E: 附加 Code Entity Graph 拓扑到报告
1153
1169
  try {
1154
1170
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
1155
- const db = ctx.container.get('database');
1156
- if (db) {
1157
- const ceg = new CodeEntityGraph(db, { projectRoot, logger });
1158
- const topo = ceg.getTopology();
1171
+ const entityRepo = ctx.container.get('codeEntityRepository');
1172
+ const edgeRepo = ctx.container.get('knowledgeEdgeRepository');
1173
+ if (entityRepo && edgeRepo) {
1174
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot, logger });
1175
+ const topo = await ceg.getTopology();
1159
1176
  report.codeEntityGraph = {
1160
1177
  entities: topo.entities,
1161
1178
  edges: topo.edges,
@@ -9,7 +9,7 @@
9
9
  * Phase 1 → 文件收集(DiscovererRegistry → 多语言项目类型检测)
10
10
  * Phase 1.5 → AST 代码结构分析(tree-sitter + SFC 预处理)
11
11
  * Phase 1.6 → Code Entity Graph(代码实体关系图谱)
12
- * Phase 1.8 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
12
+ * Phase 2.2 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
13
13
  * Phase 2 → 依赖关系 → knowledge_edges
14
14
  * Phase 2.1 → Module 实体写入 Entity Graph
15
15
  * Phase 3 → Guard 规则审计
@@ -9,7 +9,7 @@
9
9
  * Phase 1 → 文件收集(DiscovererRegistry → 多语言项目类型检测)
10
10
  * Phase 1.5 → AST 代码结构分析(tree-sitter + SFC 预处理)
11
11
  * Phase 1.6 → Code Entity Graph(代码实体关系图谱)
12
- * Phase 1.8 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
12
+ * Phase 2.2 → Panorama 全景汇总(RoleRefiner + CouplingAnalyzer + LayerInferrer)
13
13
  * Phase 2 → 依赖关系 → knowledge_edges
14
14
  * Phase 2.1 → Module 实体写入 Entity Graph
15
15
  * Phase 3 → Guard 规则审计
@@ -218,12 +218,13 @@ export async function runPhase1_6_EntityGraph(astProjectSummary, projectRoot, co
218
218
  if (astProjectSummary) {
219
219
  try {
220
220
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
221
- const db = container.get('database');
222
- if (db) {
223
- const ceg = new CodeEntityGraph(db, { projectRoot });
224
- ceg.clearProject();
221
+ const entityRepo = container.get('codeEntityRepository');
222
+ const edgeRepo = container.get('knowledgeEdgeRepository');
223
+ if (entityRepo && edgeRepo) {
224
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot });
225
+ await ceg.clearProject();
225
226
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- ProjectAnalysisResult structurally compatible at runtime
226
- codeEntityResult = ceg.populateFromAst(astProjectSummary);
227
+ codeEntityResult = await ceg.populateFromAst(astProjectSummary);
227
228
  logger.info(`[Bootstrap] Entity Graph: ${codeEntityResult.entitiesUpserted} entities, ${codeEntityResult.edgesCreated} edges`);
228
229
  }
229
230
  }
@@ -279,14 +280,15 @@ export async function runPhase1_7_CallGraph(astProjectSummary, projectRoot, cont
279
280
  minConfidence: 0.5,
280
281
  });
281
282
  // 写入 CodeEntityGraph
282
- const db = container.get('database');
283
- if (db && result && result.callEdges.length > 0) {
284
- const ceg = new CodeEntityGraph(db, { projectRoot });
283
+ const entityRepo = container.get('codeEntityRepository');
284
+ const edgeRepo = container.get('knowledgeEdgeRepository');
285
+ if (entityRepo && edgeRepo && result && result.callEdges.length > 0) {
286
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot });
285
287
  // 增量模式: 先删除变更文件的旧边
286
288
  if (isIncremental) {
287
- ceg.clearCallGraphForFiles(changedFiles ?? null);
289
+ await ceg.clearCallGraphForFiles(changedFiles ?? null);
288
290
  }
289
- callGraphResult = ceg.populateCallGraph(result.callEdges, result.dataFlowEdges);
291
+ callGraphResult = await ceg.populateCallGraph(result.callEdges, result.dataFlowEdges);
290
292
  const partialTag = result.stats.partial ? ' [partial]' : '';
291
293
  const incrTag = isIncremental ? ' [incremental]' : '';
292
294
  logger.info(`[Bootstrap] Call Graph${incrTag}${partialTag}: ${result.callEdges.length} call edges, ` +
@@ -321,7 +323,7 @@ export async function runPhase2_DependencyGraph(discoverer, container, logger, s
321
323
  depGraphData = await discoverer.getDependencyGraph();
322
324
  if (knowledgeGraphService) {
323
325
  for (const edge of depGraphData.edges || []) {
324
- const result = knowledgeGraphService.addEdge(edge.from, 'module', edge.to, 'module', 'depends_on', { weight: 1.0, source: `${discoverer.id}-${sourceTag}` });
326
+ const result = await knowledgeGraphService.addEdge(edge.from, 'module', edge.to, 'module', 'depends_on', { weight: 1.0, source: `${discoverer.id}-${sourceTag}` });
325
327
  if (result?.success) {
326
328
  depEdgesWritten++;
327
329
  }
@@ -346,10 +348,11 @@ export async function runPhase2_1_ModuleEntities(depGraphData, projectRoot, cont
346
348
  }
347
349
  try {
348
350
  const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
349
- const db = container.get('database');
350
- if (db) {
351
- const ceg = new CodeEntityGraph(db, { projectRoot });
352
- const result = ceg.populateFromSpm(depGraphData);
351
+ const entityRepo = container.get('codeEntityRepository');
352
+ const edgeRepo = container.get('knowledgeEdgeRepository');
353
+ if (entityRepo && edgeRepo) {
354
+ const ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot });
355
+ const result = await ceg.populateFromSpm(depGraphData);
353
356
  logger.info(`[Bootstrap] Entity Graph modules: ${result.entitiesUpserted} entities`);
354
357
  }
355
358
  }
@@ -637,42 +640,43 @@ export async function runAllPhases(projectRoot, ctx, options = {}) {
637
640
  if (report) {
638
641
  report.phases.callGraph = { result: phase1_7.callGraphResult, ms: Date.now() - p17Start };
639
642
  }
640
- // ── Phase 1.8: Panorama 全景汇总 ──
643
+ // ── Phase 2: 依赖图 ──
644
+ const p2Start = Date.now();
645
+ const phase2 = await runPhase2_DependencyGraph(discoverer, ctx.container, ctx.logger, options.sourceTag || 'bootstrap');
646
+ warnings.push(...phase2.warnings);
647
+ if (report) {
648
+ report.phases.depGraph = {
649
+ edgesWritten: phase2.depEdgesWritten || 0,
650
+ ms: Date.now() - p2Start,
651
+ };
652
+ }
653
+ // ── Phase 2.1: Module 实体 ──
654
+ await runPhase2_1_ModuleEntities(phase2.depGraphData, projectRoot, ctx.container, ctx.logger);
655
+ // ── Phase 2.2: Panorama 全景汇总 ──
656
+ // 必须在 Phase 2.1 之后:此时 code_entities 中已有 module 记录
641
657
  let panoramaResult = null;
642
658
  try {
643
- const panoramaService = ctx.container?.resolve?.('panoramaService');
659
+ const panoramaService = ctx.container.get('panoramaService');
644
660
  if (panoramaService &&
645
661
  typeof panoramaService.invalidate === 'function') {
646
- const p18Start = Date.now();
662
+ const pPanoStart = Date.now();
647
663
  panoramaService.invalidate();
648
- const result = panoramaService.getResult();
664
+ const result = await panoramaService.getResult();
649
665
  panoramaResult = result;
650
- ctx.logger.info(`[Bootstrap] Phase 1.8: Panorama computed in ${Date.now() - p18Start}ms`);
666
+ ctx.logger.info(`[Bootstrap] Phase 2.2: Panorama computed in ${Date.now() - pPanoStart}ms`);
651
667
  if (report) {
652
- const overview = panoramaService.getOverview();
668
+ const overview = await panoramaService.getOverview();
653
669
  report.phases.panorama = {
654
670
  moduleCount: overview.moduleCount ?? 0,
655
671
  layerCount: overview.layerCount ?? 0,
656
- ms: Date.now() - p18Start,
672
+ ms: Date.now() - pPanoStart,
657
673
  };
658
674
  }
659
675
  }
660
676
  }
661
677
  catch (err) {
662
- warnings.push(`Phase 1.8 panorama failed (non-blocking): ${err instanceof Error ? err.message : String(err)}`);
678
+ warnings.push(`Phase 2.2 panorama failed (non-blocking): ${err instanceof Error ? err.message : String(err)}`);
663
679
  }
664
- // ── Phase 2: 依赖图 ──
665
- const p2Start = Date.now();
666
- const phase2 = await runPhase2_DependencyGraph(discoverer, ctx.container, ctx.logger, options.sourceTag || 'bootstrap');
667
- warnings.push(...phase2.warnings);
668
- if (report) {
669
- report.phases.depGraph = {
670
- edgesWritten: phase2.depEdgesWritten || 0,
671
- ms: Date.now() - p2Start,
672
- };
673
- }
674
- // ── Phase 2.1: Module 实体 ──
675
- await runPhase2_1_ModuleEntities(phase2.depGraphData, projectRoot, ctx.container, ctx.logger);
676
680
  // ── Phase 3: Guard 审计 ──
677
681
  const p3Start = Date.now();
678
682
  const phase3 = await runPhase3_GuardAudit(allFiles, ctx.container, ctx.logger, {
@@ -766,7 +770,7 @@ export async function runAllPhases(projectRoot, ctx, options = {}) {
766
770
  warnings,
767
771
  report, // NEW: Phase 级报告 (null if generateReport=false)
768
772
  incrementalPlan, // NEW: 增量评估结果 (null if incremental=false)
769
- panoramaResult, // Phase 1.8: 全景汇总 (null if panoramaService unavailable)
773
+ panoramaResult, // Phase 2.2: 全景汇总 (null if panoramaService unavailable)
770
774
  isEmpty: false,
771
775
  };
772
776
  }
@@ -115,7 +115,7 @@ export async function bootstrapExternal(ctx) {
115
115
  session,
116
116
  languageExtension: buildLanguageExtension(primaryLang), // §7.1
117
117
  languageStats: langStats,
118
- panoramaResult: snapshot.panorama, // §M1: Phase 1.8 全景数据
118
+ panoramaResult: snapshot.panorama, // §M1: Phase 2.2 全景数据
119
119
  localPackageModules, // 本地子包模块信息
120
120
  });
121
121
  // 附加 warnings