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.
- package/README.md +1 -0
- package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
- package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.js +7 -4
- package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
- package/dist/lib/agent/core/LoopContext.d.ts +1 -0
- package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
- package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
- package/dist/lib/agent/memory/ActiveContext.js +0 -2
- package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
- package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
- package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
- package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
- package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
- package/dist/lib/agent/memory/MemoryStore.js +196 -261
- package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
- package/dist/lib/agent/memory/PersistentMemory.js +4 -5
- package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
- package/dist/lib/agent/memory/SessionStore.js +0 -2
- package/dist/lib/agent/tools/ast-graph.js +21 -19
- package/dist/lib/agent/tools/infrastructure.js +3 -2
- package/dist/lib/agent/tools/project-access.d.ts +2 -2
- package/dist/lib/agent/tools/project-access.js +5 -4
- package/dist/lib/bootstrap.js +2 -1
- package/dist/lib/cli/AiScanService.js +4 -17
- package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
- package/dist/lib/cli/KnowledgeSyncService.js +23 -51
- package/dist/lib/core/ast/ProjectGraph.js +5 -27
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
- package/dist/lib/domain/dimension/DimensionSop.js +44 -33
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
- package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
- package/dist/lib/domain/knowledge/index.d.ts +2 -1
- package/dist/lib/domain/knowledge/index.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/panorama.js +9 -9
- package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
- package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
- package/dist/lib/external/mcp/handlers/search.js +3 -1
- package/dist/lib/external/mcp/handlers/skill.js +4 -4
- package/dist/lib/external/mcp/handlers/structure.js +8 -12
- package/dist/lib/external/mcp/handlers/system.js +10 -34
- package/dist/lib/http/routes/ai.js +11 -13
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +59 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
- package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
- package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
- package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
- package/dist/lib/injection/ServiceContainer.js +7 -4
- package/dist/lib/injection/ServiceMap.d.ts +20 -0
- package/dist/lib/injection/modules/AppModule.js +2 -1
- package/dist/lib/injection/modules/GuardModule.js +5 -5
- package/dist/lib/injection/modules/InfraModule.js +60 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
- package/dist/lib/injection/modules/PanoramaModule.js +16 -10
- package/dist/lib/injection/modules/VectorModule.js +3 -0
- package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
- package/dist/lib/repository/audit/AuditRepository.js +272 -0
- package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
- package/dist/lib/repository/base/RepositoryBase.js +32 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
- package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
- package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
- package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
- package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
- package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
- package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
- package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
- package/dist/lib/repository/memory/MemoryRepository.js +260 -0
- package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
- package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
- package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
- package/dist/lib/repository/session/SessionRepository.js +110 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
- package/dist/lib/service/cleanup/CleanupService.js +8 -4
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
- package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
- package/dist/lib/service/evolution/ContentPatcher.js +48 -19
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
- package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
- package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
- package/dist/lib/service/evolution/DecayDetector.js +63 -57
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
- package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
- package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
- package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
- package/dist/lib/service/evolution/StagingManager.js +37 -95
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
- package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
- package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
- package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
- package/dist/lib/service/guard/ReverseGuard.js +21 -31
- package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
- package/dist/lib/service/guard/ViolationsStore.js +75 -69
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
- package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
- package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
- package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
- package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
- package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
- package/dist/lib/service/panorama/LayerInferrer.js +1 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
- package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
- package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +41 -66
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
- package/dist/lib/service/panorama/RoleRefiner.js +52 -283
- package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
- package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
- package/dist/lib/service/quality/QualityScorer.js +157 -83
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +32 -37
- package/dist/lib/service/signal/HitRecorder.js +5 -5
- package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
- package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
- package/dist/lib/service/skills/SignalCollector.js +28 -55
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
- package/dist/lib/service/vector/SyncCoordinator.js +25 -3
- package/dist/lib/service/vector/VectorService.d.ts +2 -0
- package/dist/lib/service/vector/VectorService.js +3 -0
- package/dist/lib/service/wiki/WikiGenerator.js +1 -1
- package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
- package/dist/lib/shared/LanguageProfiles.js +939 -0
- package/dist/lib/shared/LanguageService.d.ts +6 -0
- package/dist/lib/shared/LanguageService.js +16 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
- package/dist/lib/types/project-snapshot-builder.js +0 -1
- package/dist/lib/types/project-snapshot.d.ts +0 -1
- package/dist/lib/types/project-snapshot.js +0 -1
- package/dist/lib/types/snapshot-views.d.ts +0 -2
- package/dist/lib/types/snapshot-views.js +0 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
- package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
- package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -39,7 +39,7 @@ export const getProjectOverview = {
|
|
|
39
39
|
if (!graph) {
|
|
40
40
|
return 'AST 分析不可用 — ProjectGraph 未构建。请检查 tree-sitter 是否已安装。';
|
|
41
41
|
}
|
|
42
|
-
const o = graph.getOverview();
|
|
42
|
+
const o = await graph.getOverview();
|
|
43
43
|
// §P2: 从文件扩展名统计语言分布
|
|
44
44
|
const langStats = {};
|
|
45
45
|
for (const filePath of graph.getAllFilePaths?.() || []) {
|
|
@@ -532,17 +532,18 @@ export const queryCodeGraph = {
|
|
|
532
532
|
let ceg = ctx?.container?.get?.('codeEntityGraph');
|
|
533
533
|
if (!ceg) {
|
|
534
534
|
const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
|
|
535
|
-
const
|
|
536
|
-
|
|
535
|
+
const entityRepo = ctx?.container?.get?.('codeEntityRepository');
|
|
536
|
+
const edgeRepo = ctx?.container?.get?.('knowledgeEdgeRepository');
|
|
537
|
+
if (!entityRepo || !edgeRepo) {
|
|
537
538
|
return '代码实体图谱不可用: 数据库未初始化';
|
|
538
539
|
}
|
|
539
540
|
const projectRoot = ctx?.projectRoot || process.env.ASD_PROJECT_DIR || '';
|
|
540
|
-
ceg = new CodeEntityGraph(
|
|
541
|
+
ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot });
|
|
541
542
|
}
|
|
542
543
|
const maxDepth = params.max_depth || 3;
|
|
543
544
|
switch (params.action) {
|
|
544
545
|
case 'search': {
|
|
545
|
-
const results = ceg.searchEntities(params.entity_id, {
|
|
546
|
+
const results = await ceg.searchEntities(params.entity_id, {
|
|
546
547
|
type: params.entity_type,
|
|
547
548
|
limit: 15,
|
|
548
549
|
});
|
|
@@ -556,7 +557,7 @@ export const queryCodeGraph = {
|
|
|
556
557
|
return lines.join('\n');
|
|
557
558
|
}
|
|
558
559
|
case 'inheritance_chain': {
|
|
559
|
-
const chain = ceg.getInheritanceChain(params.entity_id, maxDepth);
|
|
560
|
+
const chain = await ceg.getInheritanceChain(params.entity_id, maxDepth);
|
|
560
561
|
if (chain.length <= 1) {
|
|
561
562
|
return `\`${params.entity_id}\` 没有已知的继承关系。`;
|
|
562
563
|
}
|
|
@@ -564,7 +565,7 @@ export const queryCodeGraph = {
|
|
|
564
565
|
}
|
|
565
566
|
case 'descendants': {
|
|
566
567
|
const type = params.entity_type || 'class';
|
|
567
|
-
const desc = ceg.getDescendants(params.entity_id, type, maxDepth);
|
|
568
|
+
const desc = await ceg.getDescendants(params.entity_id, type, maxDepth);
|
|
568
569
|
if (desc.length === 0) {
|
|
569
570
|
return `\`${params.entity_id}\` 没有已知的子类/遵循者。`;
|
|
570
571
|
}
|
|
@@ -575,7 +576,7 @@ export const queryCodeGraph = {
|
|
|
575
576
|
return lines.join('\n');
|
|
576
577
|
}
|
|
577
578
|
case 'conformances': {
|
|
578
|
-
const protos = ceg.getConformances(params.entity_id);
|
|
579
|
+
const protos = await ceg.getConformances(params.entity_id);
|
|
579
580
|
if (protos.length === 0) {
|
|
580
581
|
return `\`${params.entity_id}\` 没有已知的协议遵循。`;
|
|
581
582
|
}
|
|
@@ -583,7 +584,7 @@ export const queryCodeGraph = {
|
|
|
583
584
|
}
|
|
584
585
|
case 'impact': {
|
|
585
586
|
const type = params.entity_type || 'class';
|
|
586
|
-
const impact = ceg.getImpactRadius(params.entity_id, type, maxDepth);
|
|
587
|
+
const impact = await ceg.getImpactRadius(params.entity_id, type, maxDepth);
|
|
587
588
|
if (impact.length === 0) {
|
|
588
589
|
return `修改 \`${params.entity_id}\` 没有检测到直接影响。`;
|
|
589
590
|
}
|
|
@@ -594,7 +595,7 @@ export const queryCodeGraph = {
|
|
|
594
595
|
return lines.join('\n');
|
|
595
596
|
}
|
|
596
597
|
case 'topology': {
|
|
597
|
-
const topo = ceg.getTopology();
|
|
598
|
+
const topo = await ceg.getTopology();
|
|
598
599
|
if (topo.totalEntities === 0) {
|
|
599
600
|
return '代码实体图谱为空。需先执行 Bootstrap。';
|
|
600
601
|
}
|
|
@@ -614,7 +615,7 @@ export const queryCodeGraph = {
|
|
|
614
615
|
}
|
|
615
616
|
case 'entity_edges': {
|
|
616
617
|
const type = params.entity_type || 'class';
|
|
617
|
-
const edges = ceg.getEntityEdges(params.entity_id, type);
|
|
618
|
+
const edges = await ceg.getEntityEdges(params.entity_id, type);
|
|
618
619
|
const total = edges.outgoing.length + edges.incoming.length;
|
|
619
620
|
if (total === 0) {
|
|
620
621
|
return `\`${params.entity_id}\` 没有已知的图谱边。`;
|
|
@@ -687,21 +688,22 @@ export const queryCallGraph = {
|
|
|
687
688
|
if (!ceg) {
|
|
688
689
|
// fallback: 手动构建
|
|
689
690
|
const { CodeEntityGraph } = await import('#service/knowledge/CodeEntityGraph.js');
|
|
690
|
-
const
|
|
691
|
-
|
|
691
|
+
const entityRepo = ctx?.container?.get?.('codeEntityRepository');
|
|
692
|
+
const edgeRepo = ctx?.container?.get?.('knowledgeEdgeRepository');
|
|
693
|
+
if (!entityRepo || !edgeRepo) {
|
|
692
694
|
return '调用图查询不可用: 数据库未初始化。';
|
|
693
695
|
}
|
|
694
696
|
const projectRoot = ctx?.projectRoot || process.env.ASD_PROJECT_DIR || '';
|
|
695
|
-
ceg = new CodeEntityGraph(
|
|
697
|
+
ceg = new CodeEntityGraph(entityRepo, edgeRepo, { projectRoot });
|
|
696
698
|
}
|
|
697
699
|
const direction = params.direction || 'both';
|
|
698
700
|
const maxDepth = Math.min(Math.max(Number(params.maxDepth || params.max_depth) || 2, 1), 5);
|
|
699
701
|
// search 模式: 按名称搜索方法实体
|
|
700
702
|
if (direction === 'search') {
|
|
701
|
-
const results = ceg.searchEntities(methodName, { type: 'method', limit: 15 });
|
|
703
|
+
const results = await ceg.searchEntities(methodName, { type: 'method', limit: 15 });
|
|
702
704
|
if (results.length === 0) {
|
|
703
705
|
// 降级: 不限类型搜索
|
|
704
|
-
const allResults = ceg.searchEntities(methodName, { limit: 15 });
|
|
706
|
+
const allResults = await ceg.searchEntities(methodName, { limit: 15 });
|
|
705
707
|
if (allResults.length === 0) {
|
|
706
708
|
return `未找到匹配 "${methodName}" 的实体。请确认 bootstrap 已完成。`;
|
|
707
709
|
}
|
|
@@ -721,7 +723,7 @@ export const queryCallGraph = {
|
|
|
721
723
|
}
|
|
722
724
|
// impact 模式
|
|
723
725
|
if (direction === 'impact') {
|
|
724
|
-
const impact = ceg.getCallImpactRadius(methodName);
|
|
726
|
+
const impact = await ceg.getCallImpactRadius(methodName);
|
|
725
727
|
const lines = [
|
|
726
728
|
`⚡ 修改 "${methodName}" 的影响半径:`,
|
|
727
729
|
` 直接调用者: ${impact.directCallers}`,
|
|
@@ -744,10 +746,10 @@ export const queryCallGraph = {
|
|
|
744
746
|
// callers / callees / both 模式
|
|
745
747
|
const result = {};
|
|
746
748
|
if (direction === 'callers' || direction === 'both') {
|
|
747
|
-
result.callers = ceg.getCallers(methodName, maxDepth);
|
|
749
|
+
result.callers = await ceg.getCallers(methodName, maxDepth);
|
|
748
750
|
}
|
|
749
751
|
if (direction === 'callees' || direction === 'both') {
|
|
750
|
-
result.callees = ceg.getCallees(methodName, maxDepth);
|
|
752
|
+
result.callees = await ceg.getCallees(methodName, maxDepth);
|
|
751
753
|
}
|
|
752
754
|
const totalCallers = result.callers?.length || 0;
|
|
753
755
|
const totalCallees = result.callees?.length || 0;
|
|
@@ -177,9 +177,10 @@ export const suggestSkills = {
|
|
|
177
177
|
},
|
|
178
178
|
handler: async (_params, ctx) => {
|
|
179
179
|
const { SkillAdvisor } = await import('#service/skills/SkillAdvisor.js');
|
|
180
|
-
const database = ctx?.container?.get?.('database') || null;
|
|
181
180
|
const projectRoot = ctx?.projectRoot || process.cwd();
|
|
182
|
-
const
|
|
181
|
+
const knowledgeRepo = ctx?.container?.get?.('knowledgeRepository') || null;
|
|
182
|
+
const auditRepo = ctx?.container?.get?.('auditRepository') || null;
|
|
183
|
+
const advisor = new SkillAdvisor(projectRoot, { knowledgeRepo, auditRepo });
|
|
183
184
|
return advisor.suggest();
|
|
184
185
|
},
|
|
185
186
|
};
|
|
@@ -115,9 +115,9 @@ export interface SemanticSearchParams {
|
|
|
115
115
|
category?: string;
|
|
116
116
|
language?: string;
|
|
117
117
|
}
|
|
118
|
-
/**
|
|
118
|
+
/** 三方库路径识别 — 从 LanguageProfiles 统一派生 */
|
|
119
119
|
export declare const THIRD_PARTY_RE: RegExp;
|
|
120
|
-
/** 源码文件扩展名 */
|
|
120
|
+
/** 源码文件扩展名 — 从 LanguageService 统一派生 */
|
|
121
121
|
export declare const SOURCE_EXT_RE: RegExp;
|
|
122
122
|
export declare const searchProjectCode: {
|
|
123
123
|
name: string;
|
|
@@ -9,12 +9,13 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import path from 'node:path';
|
|
12
|
+
import { LanguageProfiles } from '#shared/LanguageProfiles.js';
|
|
12
13
|
import { LanguageService } from '#shared/LanguageService.js';
|
|
13
14
|
// ─── 共享常量 ──────────────────────────────────────────────
|
|
14
|
-
/**
|
|
15
|
-
export const THIRD_PARTY_RE =
|
|
16
|
-
/** 源码文件扩展名 */
|
|
17
|
-
export const SOURCE_EXT_RE =
|
|
15
|
+
/** 三方库路径识别 — 从 LanguageProfiles 统一派生 */
|
|
16
|
+
export const THIRD_PARTY_RE = LanguageProfiles.thirdPartyPathRegex;
|
|
17
|
+
/** 源码文件扩展名 — 从 LanguageService 统一派生 */
|
|
18
|
+
export const SOURCE_EXT_RE = LanguageService.sourceExtRegex;
|
|
18
19
|
/** 声明行识别 — 用于对匹配行打分(与 bootstrap/shared/scanner.js 对齐) */
|
|
19
20
|
const DECL_RE = /^\s*(@property\b|@interface\b|@protocol\b|@class\b|@synthesize\b|@dynamic\b|@end\b|NS_ASSUME_NONNULL|#import\b|#include\b|#define\b)/;
|
|
20
21
|
const TYPE_DECL_RE = /^\s*\w[\w<>*\s]+[\s*]+_?\w+\s*;$/;
|
package/dist/lib/bootstrap.js
CHANGED
|
@@ -9,6 +9,7 @@ import AuditStore from './infrastructure/audit/AuditStore.js';
|
|
|
9
9
|
import ConfigLoader from './infrastructure/config/ConfigLoader.js';
|
|
10
10
|
import DatabaseConnection from './infrastructure/database/DatabaseConnection.js';
|
|
11
11
|
import Logger from './infrastructure/logging/Logger.js';
|
|
12
|
+
import { unwrapRawDb } from './repository/search/SearchRepoAdapter.js';
|
|
12
13
|
import { SkillHooks } from './service/skills/SkillHooks.js';
|
|
13
14
|
import pathGuard from './shared/PathGuard.js';
|
|
14
15
|
import { CONFIG_DIR, PACKAGE_ROOT } from './shared/package-root.js';
|
|
@@ -162,7 +163,7 @@ export class Bootstrap {
|
|
|
162
163
|
if (this.components.db) {
|
|
163
164
|
try {
|
|
164
165
|
// 刷盘 WAL — 确保所有待写入数据持久化后再关闭
|
|
165
|
-
const rawDb = this.components.db
|
|
166
|
+
const rawDb = unwrapRawDb(this.components.db);
|
|
166
167
|
rawDb.pragma('wal_checkpoint(TRUNCATE)');
|
|
167
168
|
}
|
|
168
169
|
catch {
|
|
@@ -190,21 +190,8 @@ export class AiScanService {
|
|
|
190
190
|
if (files.length >= maxFiles) {
|
|
191
191
|
return;
|
|
192
192
|
}
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
'.m',
|
|
196
|
-
'.mm',
|
|
197
|
-
'.h',
|
|
198
|
-
'.js',
|
|
199
|
-
'.ts',
|
|
200
|
-
'.tsx',
|
|
201
|
-
'.py',
|
|
202
|
-
'.java',
|
|
203
|
-
'.kt',
|
|
204
|
-
'.go',
|
|
205
|
-
'.rs',
|
|
206
|
-
'.rb',
|
|
207
|
-
]);
|
|
193
|
+
const sourceExts = LanguageService.sourceExts;
|
|
194
|
+
const skipDirs = LanguageService.scanSkipDirs;
|
|
208
195
|
let entries;
|
|
209
196
|
try {
|
|
210
197
|
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
@@ -221,12 +208,12 @@ export class AiScanService {
|
|
|
221
208
|
}
|
|
222
209
|
const fullPath = path.join(dir, entry.name);
|
|
223
210
|
if (entry.isDirectory()) {
|
|
224
|
-
if (
|
|
211
|
+
if (skipDirs.has(entry.name)) {
|
|
225
212
|
continue;
|
|
226
213
|
}
|
|
227
214
|
this._walkDir(fullPath, files, maxFiles, targetName);
|
|
228
215
|
}
|
|
229
|
-
else if (
|
|
216
|
+
else if (sourceExts.has(path.extname(entry.name).toLowerCase())) {
|
|
230
217
|
files.push({
|
|
231
218
|
name: entry.name,
|
|
232
219
|
path: fullPath,
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* - 内部: SetupService.stepDatabase() 委托调用(skipViolations = true)
|
|
15
15
|
*/
|
|
16
16
|
import Logger from '../infrastructure/logging/Logger.js';
|
|
17
|
-
import
|
|
18
|
-
import { SourceRefReconciler } from '../service/knowledge/SourceRefReconciler.js';
|
|
17
|
+
import { type SyncRepo } from '../repository/sync/SyncRepoAdapter.js';
|
|
18
|
+
import type { ApplyReport, ReconcileReport, RepairReport, SourceRefReconciler } from '../service/knowledge/SourceRefReconciler.js';
|
|
19
19
|
export interface SyncAllReport {
|
|
20
20
|
synced: number;
|
|
21
21
|
created: number;
|
|
@@ -55,19 +55,13 @@ export declare class KnowledgeSyncService {
|
|
|
55
55
|
*
|
|
56
56
|
* 同时扫描 candidates/ 和 recipes/ 两个目录。
|
|
57
57
|
*
|
|
58
|
-
* @param db better-sqlite3
|
|
58
|
+
* @param db better-sqlite3 原始句柄或 DatabaseConnection
|
|
59
59
|
* @param [opts.dryRun=false] 只报告不写入
|
|
60
60
|
* @param [opts.force=false] 忽略 hash,强制覆盖
|
|
61
61
|
* @param [opts.skipViolations=false] 跳过违规记录(setup 场景)
|
|
62
62
|
* @returns }
|
|
63
63
|
*/
|
|
64
|
-
sync(db: {
|
|
65
|
-
prepare: (sql: string) => {
|
|
66
|
-
run: (...args: unknown[]) => void;
|
|
67
|
-
get: (...args: unknown[]) => unknown;
|
|
68
|
-
all: () => Array<Record<string, unknown>>;
|
|
69
|
-
};
|
|
70
|
-
}, opts?: {
|
|
64
|
+
sync(db: unknown, opts?: {
|
|
71
65
|
dryRun?: boolean;
|
|
72
66
|
force?: boolean;
|
|
73
67
|
skipViolations?: boolean;
|
|
@@ -139,27 +133,8 @@ export declare class KnowledgeSyncService {
|
|
|
139
133
|
publishedBy: {} | null;
|
|
140
134
|
contentHash: string;
|
|
141
135
|
};
|
|
142
|
-
/**
|
|
143
|
-
|
|
144
|
-
prepare: (sql: string) => {
|
|
145
|
-
run: (...args: unknown[]) => void;
|
|
146
|
-
};
|
|
147
|
-
}): {
|
|
148
|
-
run: (...args: unknown[]) => void;
|
|
149
|
-
};
|
|
150
|
-
/** 检查 entry 是否已存在于 DB */
|
|
151
|
-
_entryExists(db: {
|
|
152
|
-
prepare: (sql: string) => {
|
|
153
|
-
get: (...args: unknown[]) => unknown;
|
|
154
|
-
};
|
|
155
|
-
}, id: string): boolean;
|
|
156
|
-
_prepareAuditInsert(db: {
|
|
157
|
-
prepare: (sql: string) => {
|
|
158
|
-
run: (...args: unknown[]) => void;
|
|
159
|
-
};
|
|
160
|
-
}): {
|
|
161
|
-
run: (...args: unknown[]) => void;
|
|
162
|
-
} | null;
|
|
136
|
+
/** UPSERT 使用的列名列表 */
|
|
137
|
+
_upsertCols(): string[];
|
|
163
138
|
_logViolation(stmt: {
|
|
164
139
|
run: (...args: unknown[]) => void;
|
|
165
140
|
}, entryId: string, filePath: string, expectedHash: string, actualHash: string): void;
|
|
@@ -167,11 +142,6 @@ export declare class KnowledgeSyncService {
|
|
|
167
142
|
* 检测 DB 中存在但 .md 已删除的 Entry → 标记 deprecated
|
|
168
143
|
* @returns 孤儿 entry id 列表
|
|
169
144
|
*/
|
|
170
|
-
_detectOrphans(
|
|
171
|
-
prepare: (sql: string) => {
|
|
172
|
-
run: (...args: unknown[]) => void;
|
|
173
|
-
all: () => Array<Record<string, unknown>>;
|
|
174
|
-
};
|
|
175
|
-
}, syncedIds: Set<string>, dryRun: boolean): string[];
|
|
145
|
+
_detectOrphans(repo: SyncRepo, syncedIds: Set<string>, dryRun: boolean): string[];
|
|
176
146
|
}
|
|
177
147
|
export default KnowledgeSyncService;
|
|
@@ -18,8 +18,9 @@ import fs from 'node:fs';
|
|
|
18
18
|
import path from 'node:path';
|
|
19
19
|
import { CANDIDATES_DIR, RECIPES_DIR } from '../infrastructure/config/Defaults.js';
|
|
20
20
|
import Logger from '../infrastructure/logging/Logger.js';
|
|
21
|
+
import { unwrapRawDb } from '../repository/search/SearchRepoAdapter.js';
|
|
22
|
+
import { RawDbSyncAdapter } from '../repository/sync/SyncRepoAdapter.js';
|
|
21
23
|
import { computeKnowledgeHash, parseKnowledgeMarkdown, } from '../service/knowledge/KnowledgeFileWriter.js';
|
|
22
|
-
import { SourceRefReconciler } from '../service/knowledge/SourceRefReconciler.js';
|
|
23
24
|
export class KnowledgeSyncService {
|
|
24
25
|
candidatesDir;
|
|
25
26
|
logger;
|
|
@@ -48,14 +49,17 @@ export class KnowledgeSyncService {
|
|
|
48
49
|
const report = { ...syncReport };
|
|
49
50
|
// 2. 填充/验证 recipe_source_refs 桥接表
|
|
50
51
|
try {
|
|
51
|
-
const reconciler = this.#sourceRefReconciler
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const reconciler = this.#sourceRefReconciler;
|
|
53
|
+
if (!reconciler) {
|
|
54
|
+
this.logger.warn('KnowledgeSyncService: sourceRefReconciler not available, skipping reconcile');
|
|
55
|
+
return report;
|
|
56
|
+
}
|
|
57
|
+
report.reconcileReport = await reconciler.reconcile({ force: opts.force });
|
|
54
58
|
// 3. git rename 修复
|
|
55
59
|
report.repairReport = await reconciler.repairRenames();
|
|
56
60
|
// 4. 写回修复
|
|
57
61
|
if (report.repairReport.renamed > 0) {
|
|
58
|
-
report.applyReport = reconciler.applyRepairs();
|
|
62
|
+
report.applyReport = await reconciler.applyRepairs();
|
|
59
63
|
}
|
|
60
64
|
}
|
|
61
65
|
catch (err) {
|
|
@@ -70,7 +74,7 @@ export class KnowledgeSyncService {
|
|
|
70
74
|
*
|
|
71
75
|
* 同时扫描 candidates/ 和 recipes/ 两个目录。
|
|
72
76
|
*
|
|
73
|
-
* @param db better-sqlite3
|
|
77
|
+
* @param db better-sqlite3 原始句柄或 DatabaseConnection
|
|
74
78
|
* @param [opts.dryRun=false] 只报告不写入
|
|
75
79
|
* @param [opts.force=false] 忽略 hash,强制覆盖
|
|
76
80
|
* @param [opts.skipViolations=false] 跳过违规记录(setup 场景)
|
|
@@ -95,9 +99,11 @@ export class KnowledgeSyncService {
|
|
|
95
99
|
this.logger.info('KnowledgeSyncService: no .md files found');
|
|
96
100
|
return report;
|
|
97
101
|
}
|
|
98
|
-
// ── 2.
|
|
99
|
-
const
|
|
100
|
-
const
|
|
102
|
+
// ── 2. 创建仓储适配器 ──
|
|
103
|
+
const rawDb = unwrapRawDb(db);
|
|
104
|
+
const repo = new RawDbSyncAdapter(rawDb);
|
|
105
|
+
const upsertStmt = dryRun ? null : repo.createUpsertStmt(this._upsertCols());
|
|
106
|
+
const auditStmt = dryRun || skipViolations ? null : repo.createAuditInsertStmt();
|
|
101
107
|
// ── 3. 逐文件同步 ──
|
|
102
108
|
const syncedIds = new Set();
|
|
103
109
|
for (const { absPath, relPath } of mdFiles) {
|
|
@@ -122,7 +128,7 @@ export class KnowledgeSyncService {
|
|
|
122
128
|
}
|
|
123
129
|
// ── upsert ──
|
|
124
130
|
if (!dryRun) {
|
|
125
|
-
const existed =
|
|
131
|
+
const existed = repo.entryExists(parsed.id);
|
|
126
132
|
const row = this._buildDbRow(parsed, relPath, content);
|
|
127
133
|
upsertStmt?.run(...Object.values(row));
|
|
128
134
|
if (existed) {
|
|
@@ -142,7 +148,7 @@ export class KnowledgeSyncService {
|
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
// ── 4. 检测孤儿 ──
|
|
145
|
-
report.orphaned = this._detectOrphans(
|
|
151
|
+
report.orphaned = this._detectOrphans(repo, syncedIds, dryRun);
|
|
146
152
|
this.logger.info('KnowledgeSyncService: sync complete', {
|
|
147
153
|
synced: report.synced,
|
|
148
154
|
created: report.created,
|
|
@@ -239,9 +245,9 @@ export class KnowledgeSyncService {
|
|
|
239
245
|
contentHash: contentHash,
|
|
240
246
|
};
|
|
241
247
|
}
|
|
242
|
-
/**
|
|
243
|
-
|
|
244
|
-
|
|
248
|
+
/** UPSERT 使用的列名列表 */
|
|
249
|
+
_upsertCols() {
|
|
250
|
+
return [
|
|
245
251
|
'id',
|
|
246
252
|
'title',
|
|
247
253
|
'trigger',
|
|
@@ -287,34 +293,8 @@ export class KnowledgeSyncService {
|
|
|
287
293
|
'publishedBy',
|
|
288
294
|
'contentHash',
|
|
289
295
|
];
|
|
290
|
-
// ON CONFLICT 更新除 id, createdBy, createdAt 以外的所有列
|
|
291
|
-
const updateCols = cols.filter((c) => !['id', 'createdBy', 'createdAt'].includes(c));
|
|
292
|
-
const setClauses = updateCols.map((c) => `${c} = excluded.${c}`).join(',\n ');
|
|
293
|
-
const sql = `
|
|
294
|
-
INSERT INTO knowledge_entries (${cols.join(', ')})
|
|
295
|
-
VALUES (${cols.map(() => '?').join(', ')})
|
|
296
|
-
ON CONFLICT(id) DO UPDATE SET
|
|
297
|
-
${setClauses}
|
|
298
|
-
`;
|
|
299
|
-
return db.prepare(sql);
|
|
300
|
-
}
|
|
301
|
-
/** 检查 entry 是否已存在于 DB */
|
|
302
|
-
_entryExists(db, id) {
|
|
303
|
-
const row = db.prepare('SELECT 1 FROM knowledge_entries WHERE id = ?').get(id);
|
|
304
|
-
return !!row;
|
|
305
296
|
}
|
|
306
297
|
/* ═══ 违规记录 ═══════════════════════════════════════════ */
|
|
307
|
-
_prepareAuditInsert(db) {
|
|
308
|
-
try {
|
|
309
|
-
return db.prepare(`
|
|
310
|
-
INSERT INTO audit_logs (id, timestamp, actor, actor_context, action, resource, operation_data, result, error_message, duration)
|
|
311
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
312
|
-
`);
|
|
313
|
-
}
|
|
314
|
-
catch {
|
|
315
|
-
return null;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
298
|
_logViolation(stmt, entryId, filePath, expectedHash, actualHash) {
|
|
319
299
|
try {
|
|
320
300
|
stmt.run(randomUUID(), Math.floor(Date.now() / 1000), 'sync', JSON.stringify({ source: 'cli' }), 'manual_knowledge_edit', entryId, JSON.stringify({ file: filePath, expectedHash, actualHash }), 'violation_detected', null, 0);
|
|
@@ -331,24 +311,16 @@ export class KnowledgeSyncService {
|
|
|
331
311
|
* 检测 DB 中存在但 .md 已删除的 Entry → 标记 deprecated
|
|
332
312
|
* @returns 孤儿 entry id 列表
|
|
333
313
|
*/
|
|
334
|
-
_detectOrphans(
|
|
314
|
+
_detectOrphans(repo, syncedIds, dryRun) {
|
|
335
315
|
const orphanIds = [];
|
|
336
316
|
try {
|
|
337
|
-
const rows =
|
|
338
|
-
.prepare(`SELECT id, sourceFile FROM knowledge_entries
|
|
339
|
-
WHERE lifecycle NOT IN ('deprecated')
|
|
340
|
-
AND sourceFile IS NOT NULL`)
|
|
341
|
-
.all();
|
|
317
|
+
const rows = repo.findActiveEntriesWithSourceFile();
|
|
342
318
|
for (const row of rows) {
|
|
343
319
|
if (!syncedIds.has(row.id)) {
|
|
344
320
|
orphanIds.push(row.id);
|
|
345
321
|
if (!dryRun) {
|
|
346
322
|
const now = Math.floor(Date.now() / 1000);
|
|
347
|
-
|
|
348
|
-
SET lifecycle = 'deprecated',
|
|
349
|
-
rejectionReason = ?,
|
|
350
|
-
updatedAt = ?
|
|
351
|
-
WHERE id = ?`).run('源文件已删除(孤儿条目)', now, row.id);
|
|
323
|
+
repo.deprecateEntry(row.id, '源文件已删除(孤儿条目)', now);
|
|
352
324
|
}
|
|
353
325
|
}
|
|
354
326
|
}
|
|
@@ -23,37 +23,15 @@ const DEFAULTS = {
|
|
|
23
23
|
maxFiles: 500,
|
|
24
24
|
maxFileSizeBytes: 500_000, // 500KB — 跳过超大文件
|
|
25
25
|
excludePatterns: [
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
'build/',
|
|
30
|
-
'.git/',
|
|
31
|
-
'dist/',
|
|
32
|
-
'out/',
|
|
33
|
-
// iOS
|
|
34
|
-
'Pods/',
|
|
35
|
-
'Carthage/',
|
|
36
|
-
'DerivedData/',
|
|
37
|
-
// Python
|
|
38
|
-
'__pycache__/',
|
|
39
|
-
'.venv/',
|
|
40
|
-
'venv/',
|
|
41
|
-
'.tox/',
|
|
42
|
-
'*.egg-info/',
|
|
43
|
-
// JVM
|
|
44
|
-
'target/',
|
|
45
|
-
'.gradle/',
|
|
46
|
-
'.idea/',
|
|
47
|
-
// Test
|
|
26
|
+
// 从 LanguageService 统一跳过目录派生(添加 '/' 后缀以匹配路径片段)
|
|
27
|
+
...[...LanguageService.scanSkipDirs].map((d) => `${d}/`),
|
|
28
|
+
// ProjectGraph 额外: 测试目录
|
|
48
29
|
'__tests__/',
|
|
49
30
|
'Tests/',
|
|
50
31
|
'test/',
|
|
51
32
|
'tests/',
|
|
52
|
-
//
|
|
53
|
-
'
|
|
54
|
-
'.fvm/',
|
|
55
|
-
// Misc
|
|
56
|
-
'vendor/',
|
|
33
|
+
// Glob-style (egg-info)
|
|
34
|
+
'*.egg-info/',
|
|
57
35
|
],
|
|
58
36
|
// 从 LanguageService 派生,仅覆盖 AST 解析需要区分 tsx 的场景
|
|
59
37
|
extensionToLang: {
|
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
* - Baidu EasyBox (Boxfile + *.boxspec)
|
|
11
11
|
* - Tuist (Project.swift)
|
|
12
12
|
* - XcodeGen (project.yml)
|
|
13
|
-
*
|
|
14
|
-
* 设计文档: docs/copilot/custom-config-discoverer-design.md
|
|
15
13
|
*/
|
|
16
14
|
import { type DependencyGraph, type DiscoveredFile, type DiscoveredTarget, ProjectDiscoverer } from './ProjectDiscoverer.js';
|
|
17
15
|
export declare class CustomConfigDiscoverer extends ProjectDiscoverer {
|
|
@@ -10,8 +10,6 @@
|
|
|
10
10
|
* - Baidu EasyBox (Boxfile + *.boxspec)
|
|
11
11
|
* - Tuist (Project.swift)
|
|
12
12
|
* - XcodeGen (project.yml)
|
|
13
|
-
*
|
|
14
|
-
* 设计文档: docs/copilot/custom-config-discoverer-design.md
|
|
15
13
|
*/
|
|
16
14
|
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
17
15
|
import { extname, join, relative } from 'node:path';
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* 这是整个系统中维度定义的唯一来源。
|
|
10
10
|
* Bootstrap / Panorama / Rescan / Dashboard 均从此模块消费维度元数据。
|
|
11
11
|
*
|
|
12
|
-
* 设计文档: docs/copilot/unified-dimension-design.md §4
|
|
13
|
-
*
|
|
14
12
|
* @module domain/dimension/DimensionRegistry
|
|
15
13
|
*/
|
|
16
14
|
import type { DimensionId, UnifiedDimension } from './UnifiedDimension.js';
|
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* 这是整个系统中维度定义的唯一来源。
|
|
10
10
|
* Bootstrap / Panorama / Rescan / Dashboard 均从此模块消费维度元数据。
|
|
11
11
|
*
|
|
12
|
-
* 设计文档: docs/copilot/unified-dimension-design.md §4
|
|
13
|
-
*
|
|
14
12
|
* @module domain/dimension/DimensionRegistry
|
|
15
13
|
*/
|
|
16
14
|
// ═══════════════════════════════════════════════════════════
|