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
@@ -20,27 +20,24 @@ const SILENT_LOGGER = {
20
20
  export class PanoramaScanner {
21
21
  #projectRoot;
22
22
  #container;
23
+ #entityRepo;
24
+ #edgeRepo;
23
25
  #logger;
24
26
  #hasScanned = false;
25
27
  constructor(opts) {
26
28
  this.#projectRoot = opts.projectRoot;
27
29
  this.#container = opts.container;
30
+ this.#entityRepo = opts.entityRepo;
31
+ this.#edgeRepo = opts.edgeRepo;
28
32
  this.#logger = opts.logger ?? SILENT_LOGGER;
29
33
  }
30
34
  /**
31
35
  * 检测 DB 中是否已有该项目的 code_entities 数据
32
36
  */
33
- hasData() {
37
+ async hasData() {
34
38
  try {
35
- const db = this.#container.get('database');
36
- const rawDb = db?.getDb ? db.getDb() : db;
37
- if (!rawDb?.prepare) {
38
- return false;
39
- }
40
- const row = rawDb
41
- .prepare(`SELECT COUNT(*) as cnt FROM code_entities WHERE project_root = ?`)
42
- .get(this.#projectRoot);
43
- return (row?.cnt ?? 0) > 0;
39
+ const cnt = await this.#entityRepo.getEntityCount(this.#projectRoot);
40
+ return cnt > 0;
44
41
  }
45
42
  catch {
46
43
  return false;
@@ -51,7 +48,7 @@ export class PanoramaScanner {
51
48
  * 幂等:扫描过一次后不再重复(重启进程或手动 reset 可重新触发)。
52
49
  */
53
50
  async ensureData() {
54
- if (this.#hasScanned || this.hasData()) {
51
+ if (this.#hasScanned || (await this.hasData())) {
55
52
  return null;
56
53
  }
57
54
  return this.scan();
@@ -135,7 +132,7 @@ export class PanoramaScanner {
135
132
  // 当 Phase 2.1 未产出 module 实体时(无 Package.swift / build.gradle 等),
136
133
  // 从已有 code_entities 按顶层目录分组写入 module 实体
137
134
  if (modules === 0 && entities > 0) {
138
- modules = this.#inferModulesFromDirectories();
135
+ modules = await this.#inferModulesFromDirectories();
139
136
  }
140
137
  }
141
138
  catch (err) {
@@ -157,25 +154,17 @@ export class PanoramaScanner {
157
154
  * 从 code_entities 中按顶层目录分组写入 module 实体 + is_part_of 边。
158
155
  * 仅在 Phase 2.1 未产出 module 时调用。
159
156
  */
160
- #inferModulesFromDirectories() {
157
+ async #inferModulesFromDirectories() {
161
158
  try {
162
- const db = this.#container.get('database');
163
- const rawDb = db?.getDb ? db.getDb() : db;
164
- if (!rawDb?.prepare) {
165
- return 0;
166
- }
167
159
  // 查询所有非 module 实体的文件路径
168
- const rows = rawDb
169
- .prepare(`SELECT DISTINCT entity_id, file_path FROM code_entities
170
- WHERE project_root = ? AND file_path IS NOT NULL AND entity_type != 'module'`)
171
- .all(this.#projectRoot);
160
+ const rows = await this.#entityRepo.findDistinctEntityIdsWithFilePath(this.#projectRoot);
172
161
  if (rows.length === 0) {
173
162
  return 0;
174
163
  }
175
164
  // 按顶层目录分组
176
165
  const groups = new Map();
177
166
  for (const row of rows) {
178
- const filePath = row.file_path;
167
+ const filePath = row.filePath;
179
168
  if (!filePath) {
180
169
  continue;
181
170
  }
@@ -189,22 +178,34 @@ export class PanoramaScanner {
189
178
  if (!groups.has(firstDir)) {
190
179
  groups.set(firstDir, []);
191
180
  }
192
- groups.get(firstDir).push(row.entity_id);
181
+ groups.get(firstDir).push(row.entityId);
193
182
  }
194
183
  if (groups.size === 0) {
195
184
  return 0;
196
185
  }
197
- // 写入 module 实体 + is_part_of 边
198
- const insertEntity = rawDb.prepare(`INSERT OR IGNORE INTO code_entities (entity_id, name, entity_type, file_path, project_root)
199
- VALUES (?, ?, 'module', NULL, ?)`);
200
- const insertEdge = rawDb.prepare(`INSERT OR IGNORE INTO knowledge_edges (from_id, from_type, to_id, to_type, relation, weight)
201
- VALUES (?, 'entity', ?, 'module', 'is_part_of', 1.0)`);
186
+ // 写入 module 实体
187
+ const moduleEntities = [...groups.keys()].map((dirName) => ({
188
+ entityId: dirName,
189
+ name: dirName,
190
+ entityType: 'module',
191
+ projectRoot: this.#projectRoot,
192
+ }));
193
+ await this.#entityRepo.batchInsertIgnore(moduleEntities);
194
+ // 写入 is_part_of 边
195
+ const edges = [];
202
196
  for (const [dirName, entityIds] of groups) {
203
- insertEntity.run(dirName, dirName, this.#projectRoot);
204
197
  for (const entityId of entityIds) {
205
- insertEdge.run(entityId, dirName);
198
+ edges.push({
199
+ fromId: entityId,
200
+ fromType: 'entity',
201
+ toId: dirName,
202
+ toType: 'module',
203
+ relation: 'is_part_of',
204
+ weight: 1.0,
205
+ });
206
206
  }
207
207
  }
208
+ await this.#edgeRepo.bulkInsertIgnore(edges);
208
209
  this.#logger.info(`[PanoramaScanner] Directory fallback: inferred ${groups.size} modules from top-level dirs`);
209
210
  return groups.size;
210
211
  }
@@ -13,13 +13,16 @@
13
13
  * @module PanoramaService
14
14
  */
15
15
  import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
16
- import { ModuleDiscoverer } from './ModuleDiscoverer.js';
16
+ import type { KnowledgeEdgeRepositoryImpl } from '../../repository/knowledge/KnowledgeEdgeRepository.js';
17
+ import type { KnowledgeRepositoryImpl } from '../../repository/knowledge/KnowledgeRepository.impl.js';
18
+ import type { ModuleDiscoverer } from './ModuleDiscoverer.js';
17
19
  import type { PanoramaAggregator } from './PanoramaAggregator.js';
18
20
  import type { PanoramaScanner } from './PanoramaScanner.js';
19
- import type { CeDbLike, HealthRadar, KnowledgeGap, PanoramaModule, PanoramaResult } from './PanoramaTypes.js';
21
+ import type { HealthRadar, KnowledgeGap, PanoramaModule, PanoramaResult } from './PanoramaTypes.js';
20
22
  export interface PanoramaServiceOptions {
21
23
  aggregator: PanoramaAggregator;
22
- db: CeDbLike;
24
+ edgeRepo: KnowledgeEdgeRepositoryImpl;
25
+ knowledgeRepo: KnowledgeRepositoryImpl;
23
26
  projectRoot: string;
24
27
  scanner?: PanoramaScanner;
25
28
  moduleDiscoverer?: ModuleDiscoverer;
@@ -92,23 +95,23 @@ export declare class PanoramaService {
92
95
  /**
93
96
  * 获取项目全景概览
94
97
  */
95
- getOverview(): PanoramaOverview;
98
+ getOverview(): Promise<PanoramaOverview>;
96
99
  /**
97
100
  * 获取单模块详情 (enriched with file groups, recipes, and summary)
98
101
  */
99
- getModule(moduleName: string): PanoramaModuleDetail | null;
102
+ getModule(moduleName: string): Promise<PanoramaModuleDetail | null>;
100
103
  /**
101
104
  * 获取知识空白区
102
105
  */
103
- getGaps(): KnowledgeGap[];
106
+ getGaps(): Promise<KnowledgeGap[]>;
104
107
  /**
105
108
  * 获取全景健康度
106
109
  */
107
- getHealth(): PanoramaHealth;
110
+ getHealth(): Promise<PanoramaHealth>;
108
111
  /**
109
112
  * 获取完整 PanoramaResult(内部使用或 Bootstrap 注入)
110
113
  */
111
- getResult(): PanoramaResult;
114
+ getResult(): Promise<PanoramaResult>;
112
115
  /**
113
116
  * 确保全景数据已就绪(无数据时自动扫描)
114
117
  * MCP handler / HTTP route 应在返回数据前调用此方法
@@ -12,13 +12,14 @@
12
12
  *
13
13
  * @module PanoramaService
14
14
  */
15
- import { ModuleDiscoverer } from './ModuleDiscoverer.js';
15
+ import { COUNTABLE_LIFECYCLES } from '../../domain/knowledge/Lifecycle.js';
16
16
  /* ═══ Constants ═══════════════════════════════════════════ */
17
17
  const STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000; // 24h
18
18
  /* ═══ PanoramaService Class ═══════════════════════════════ */
19
19
  export class PanoramaService {
20
20
  #aggregator;
21
- #db;
21
+ #edgeRepo;
22
+ #knowledgeRepo;
22
23
  #projectRoot;
23
24
  #scanner;
24
25
  #moduleDiscoverer;
@@ -28,11 +29,15 @@ export class PanoramaService {
28
29
  #lastOverview = null;
29
30
  constructor(opts) {
30
31
  this.#aggregator = opts.aggregator;
31
- this.#db = opts.db;
32
+ this.#edgeRepo = opts.edgeRepo;
33
+ this.#knowledgeRepo = opts.knowledgeRepo;
32
34
  this.#projectRoot = opts.projectRoot;
33
35
  this.#scanner = opts.scanner ?? null;
34
36
  this.#moduleDiscoverer =
35
- opts.moduleDiscoverer ?? new ModuleDiscoverer(opts.db, opts.projectRoot);
37
+ opts.moduleDiscoverer ??
38
+ (() => {
39
+ throw new Error('moduleDiscoverer is required');
40
+ })();
36
41
  this.#signalBus = opts.signalBus ?? null;
37
42
  // Phase 2: 订阅信号标记缓存失效
38
43
  if (this.#signalBus) {
@@ -45,8 +50,8 @@ export class PanoramaService {
45
50
  /**
46
51
  * 获取项目全景概览
47
52
  */
48
- getOverview() {
49
- const result = this.#getOrCompute();
53
+ async getOverview() {
54
+ const result = await this.#getOrCompute();
50
55
  const isStale = Date.now() - result.computedAt > STALE_THRESHOLD_MS;
51
56
  let totalFiles = 0;
52
57
  for (const [, mod] of result.modules) {
@@ -98,8 +103,8 @@ export class PanoramaService {
98
103
  /**
99
104
  * 获取单模块详情 (enriched with file groups, recipes, and summary)
100
105
  */
101
- getModule(moduleName) {
102
- const result = this.#getOrCompute();
106
+ async getModule(moduleName) {
107
+ const result = await this.#getOrCompute();
103
108
  const mod = result.modules.get(moduleName);
104
109
  if (!mod) {
105
110
  return null;
@@ -109,33 +114,27 @@ export class PanoramaService {
109
114
  // File groups: group by immediate subdirectory within the module
110
115
  const fileGroups = PanoramaService.#groupFilesBySubdir(mod.files);
111
116
  // Matched recipes from DB
112
- const recipes = this.#findModuleRecipes(moduleName, mod);
117
+ const recipes = await this.#findModuleRecipes(moduleName, mod);
113
118
  // Uncovered file count estimate
114
119
  const coveredFileCount = Math.min(recipes.length * 2, mod.fileCount); // rough heuristic
115
120
  const uncoveredFileCount = Math.max(0, mod.fileCount - coveredFileCount);
116
- // Neighbors from DB edges
121
+ // Neighbors from edge repo
117
122
  const neighbors = [];
118
- const outNeighbors = this.#db
119
- .prepare(`SELECT DISTINCT to_id, weight FROM knowledge_edges
120
- WHERE from_id = ? AND from_type = 'module' AND relation = 'depends_on'`)
121
- .all(moduleName);
122
- for (const n of outNeighbors) {
123
- neighbors.push({
124
- name: n.to_id,
125
- direction: 'out',
126
- weight: Number(n.weight ?? 1),
127
- });
123
+ const outEdges = await this.#edgeRepo.findOutgoingByRelation(moduleName, 'depends_on');
124
+ const seenOut = new Set();
125
+ for (const e of outEdges) {
126
+ if (!seenOut.has(e.toId)) {
127
+ seenOut.add(e.toId);
128
+ neighbors.push({ name: e.toId, direction: 'out', weight: e.weight });
129
+ }
128
130
  }
129
- const inNeighbors = this.#db
130
- .prepare(`SELECT DISTINCT from_id, weight FROM knowledge_edges
131
- WHERE to_id = ? AND to_type = 'module' AND relation = 'depends_on'`)
132
- .all(moduleName);
133
- for (const n of inNeighbors) {
134
- neighbors.push({
135
- name: n.from_id,
136
- direction: 'in',
137
- weight: Number(n.weight ?? 1),
138
- });
131
+ const inEdges = await this.#edgeRepo.findIncomingByRelation(moduleName, 'depends_on');
132
+ const seenIn = new Set();
133
+ for (const e of inEdges) {
134
+ if (!seenIn.has(e.fromId)) {
135
+ seenIn.add(e.fromId);
136
+ neighbors.push({ name: e.fromId, direction: 'in', weight: e.weight });
137
+ }
139
138
  }
140
139
  // Generate summary
141
140
  const summary = PanoramaService.#generateModuleSummary(mod, layerName, fileGroups, recipes, neighbors);
@@ -199,7 +198,7 @@ export class PanoramaService {
199
198
  return prefix;
200
199
  }
201
200
  /** Find recipes related to this module by category, trigger, or title match */
202
- #findModuleRecipes(moduleName, mod) {
201
+ async #findModuleRecipes(moduleName, mod) {
203
202
  try {
204
203
  // Map refined role to typical recipe categories
205
204
  const roleCategories = {
@@ -213,31 +212,7 @@ export class PanoramaService {
213
212
  feature: ['Feature'],
214
213
  };
215
214
  const categories = roleCategories[mod.refinedRole] ?? [];
216
- // Build a LIKE query that matches module name or related categories
217
- const conditions = [];
218
- const params = [];
219
- // Match by module name in title or trigger
220
- conditions.push('(title LIKE ? OR trigger LIKE ?)');
221
- params.push(`%${moduleName}%`, `%${moduleName}%`);
222
- // Match by category
223
- for (const cat of categories) {
224
- conditions.push('category = ?');
225
- params.push(cat);
226
- }
227
- const whereClause = conditions.join(' OR ');
228
- const rows = this.#db
229
- .prepare(`SELECT id, title, trigger, kind FROM knowledge_entries
230
- WHERE lifecycle IN ('active', 'staging', 'pending')
231
- AND (${whereClause})
232
- ORDER BY lifecycle ASC
233
- LIMIT 20`)
234
- .all(...params);
235
- return rows.map((r) => ({
236
- id: String(r.id ?? ''),
237
- title: String(r.title ?? ''),
238
- trigger: String(r.trigger ?? ''),
239
- kind: String(r.kind ?? ''),
240
- }));
215
+ return await this.#knowledgeRepo.findModuleRecipes(COUNTABLE_LIFECYCLES, moduleName, categories, 20);
241
216
  }
242
217
  catch {
243
218
  return [];
@@ -280,15 +255,15 @@ export class PanoramaService {
280
255
  /**
281
256
  * 获取知识空白区
282
257
  */
283
- getGaps() {
284
- const result = this.#getOrCompute();
258
+ async getGaps() {
259
+ const result = await this.#getOrCompute();
285
260
  return result.gaps;
286
261
  }
287
262
  /**
288
263
  * 获取全景健康度
289
264
  */
290
- getHealth() {
291
- const result = this.#getOrCompute();
265
+ async getHealth() {
266
+ const result = await this.#getOrCompute();
292
267
  let totalCoupling = 0;
293
268
  let count = 0;
294
269
  for (const [, mod] of result.modules) {
@@ -318,8 +293,8 @@ export class PanoramaService {
318
293
  /**
319
294
  * 获取完整 PanoramaResult(内部使用或 Bootstrap 注入)
320
295
  */
321
- getResult() {
322
- return this.#getOrCompute();
296
+ async getResult() {
297
+ return await this.#getOrCompute();
323
298
  }
324
299
  /**
325
300
  * 确保全景数据已就绪(无数据时自动扫描)
@@ -356,13 +331,13 @@ export class PanoramaService {
356
331
  }
357
332
  }
358
333
  /* ─── Cache + Compute ───────────────────────────── */
359
- #getOrCompute() {
334
+ async #getOrCompute() {
360
335
  if (this.#cache) {
361
336
  return this.#cache;
362
337
  }
363
- const candidates = this.#moduleDiscoverer.discover();
364
- const configLayers = this.#moduleDiscoverer.readConfigLayers();
365
- this.#cache = this.#aggregator.compute(candidates, { configLayers });
338
+ const candidates = await this.#moduleDiscoverer.discover();
339
+ const configLayers = await this.#moduleDiscoverer.readConfigLayers();
340
+ this.#cache = await this.#aggregator.compute(candidates, { configLayers });
366
341
  return this.#cache;
367
342
  }
368
343
  }
@@ -83,6 +83,8 @@ export interface LayerViolation {
83
83
  export interface LayerHierarchy {
84
84
  levels: LayerLevel[];
85
85
  violations: LayerViolation[];
86
+ /** 是否基于配置文件(如 Boxfile)声明的层级推断(而非纯拓扑) */
87
+ configBased?: boolean;
86
88
  }
87
89
  export interface CyclicDependency {
88
90
  cycle: string[];
@@ -154,6 +156,7 @@ export interface CallFlowSummary {
154
156
  dataProducers: string[];
155
157
  dataConsumers: string[];
156
158
  }
159
+ export type { ModuleRole } from '#shared/LanguageProfiles.js';
157
160
  export interface PanoramaResult {
158
161
  modules: Map<string, PanoramaModule>;
159
162
  layers: LayerHierarchy;
@@ -13,8 +13,11 @@
13
13
  *
14
14
  * @module RoleRefiner
15
15
  */
16
- import type { CeDbLike } from './PanoramaTypes.js';
17
- export type ModuleRole = 'core' | 'service' | 'ui' | 'networking' | 'storage' | 'test' | 'app' | 'routing' | 'utility' | 'model' | 'auth' | 'config' | 'feature';
16
+ import type { BootstrapRepositoryImpl } from '../../repository/bootstrap/BootstrapRepository.js';
17
+ import type { CodeEntityRepositoryImpl } from '../../repository/code/CodeEntityRepository.js';
18
+ import type { KnowledgeEdgeRepositoryImpl } from '../../repository/knowledge/KnowledgeEdgeRepository.js';
19
+ import type { ModuleRole } from './PanoramaTypes.js';
20
+ export type { ModuleRole } from './PanoramaTypes.js';
18
21
  export interface RoleSignal {
19
22
  role: ModuleRole;
20
23
  confidence: number;
@@ -38,13 +41,13 @@ export interface ModuleCandidate {
38
41
  }
39
42
  export declare class RoleRefiner {
40
43
  #private;
41
- constructor(db: CeDbLike, projectRoot: string);
44
+ constructor(bootstrapRepo: BootstrapRepositoryImpl, entityRepo: CodeEntityRepositoryImpl, edgeRepo: KnowledgeEdgeRepositoryImpl, projectRoot: string);
42
45
  /**
43
46
  * 精化单个模块的角色
44
47
  */
45
- refineRole(module: ModuleCandidate): RefinedRole;
48
+ refineRole(module: ModuleCandidate): Promise<RefinedRole>;
46
49
  /**
47
50
  * 批量精化所有模块
48
51
  */
49
- refineAll(modules: ModuleCandidate[]): Map<string, RefinedRole>;
52
+ refineAll(modules: ModuleCandidate[]): Promise<Map<string, RefinedRole>>;
50
53
  }