autosnippet 3.3.7 → 3.3.9
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-DEU4tJtP.js +112 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -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 +8 -2
- 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/cli/SetupService.js +5 -4
- 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/McpServer.js +19 -2
- 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/mock-pipeline.js +10 -29
- 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/DatabaseConnection.js +7 -6
- 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 +21 -9
- 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/PathGuard.js +16 -10
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/isOwnDevRepo.d.ts +29 -4
- package/dist/lib/shared/isOwnDevRepo.js +64 -4
- 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
|
@@ -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
|
|
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
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
ceg
|
|
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
|
|
283
|
-
|
|
284
|
-
|
|
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
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
const
|
|
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
|
|
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
|
|
659
|
+
const panoramaService = ctx.container.get('panoramaService');
|
|
644
660
|
if (panoramaService &&
|
|
645
661
|
typeof panoramaService.invalidate === 'function') {
|
|
646
|
-
const
|
|
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
|
|
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() -
|
|
672
|
+
ms: Date.now() - pPanoStart,
|
|
657
673
|
};
|
|
658
674
|
}
|
|
659
675
|
}
|
|
660
676
|
}
|
|
661
677
|
catch (err) {
|
|
662
|
-
warnings.push(`Phase
|
|
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
|
|
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
|
|
118
|
+
panoramaResult: snapshot.panorama, // §M1: Phase 2.2 全景数据
|
|
119
119
|
localPackageModules, // 本地子包模块信息
|
|
120
120
|
});
|
|
121
121
|
// 附加 warnings
|
|
@@ -273,7 +273,7 @@ export async function dimensionComplete(ctx, args) {
|
|
|
273
273
|
if (knowledgeGraphService && keyFindings.length > 0) {
|
|
274
274
|
// 将每个 keyFinding 创建为知识图谱中的实体
|
|
275
275
|
for (const finding of keyFindings) {
|
|
276
|
-
knowledgeGraphService.addEdge(dimensionId, 'dimension', finding.substring(0, 80), 'finding', 'discovered_in', { source: 'external-agent-bootstrap', sessionId: session.id });
|
|
276
|
+
await knowledgeGraphService.addEdge(dimensionId, 'dimension', finding.substring(0, 80), 'finding', 'discovered_in', { source: 'external-agent-bootstrap', sessionId: session.id });
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
}
|
|
@@ -351,7 +351,7 @@ export async function dimensionComplete(ctx, args) {
|
|
|
351
351
|
if (panoramaService &&
|
|
352
352
|
typeof panoramaService.rescan === 'function') {
|
|
353
353
|
await panoramaService.rescan();
|
|
354
|
-
const overview = panoramaService.getOverview();
|
|
354
|
+
const overview = await panoramaService.getOverview();
|
|
355
355
|
logger.info(`[DimensionComplete] Panorama refreshed — ${overview.moduleCount} modules, ${overview.gapCount} gaps`);
|
|
356
356
|
}
|
|
357
357
|
}
|
|
@@ -388,7 +388,11 @@ export async function dimensionComplete(ctx, args) {
|
|
|
388
388
|
const db = ctx.container.get?.('database') ?? ctx.container.get?.('db');
|
|
389
389
|
if (db && session.sessionStore) {
|
|
390
390
|
const { PersistentMemory } = await import('#agent/memory/PersistentMemory.js');
|
|
391
|
-
const
|
|
391
|
+
const { MemoryEmbeddingStore } = await import('#agent/memory/MemoryEmbeddingStore.js');
|
|
392
|
+
const semanticMemory = new PersistentMemory(db, {
|
|
393
|
+
logger,
|
|
394
|
+
embeddingStore: new MemoryEmbeddingStore(projectRoot),
|
|
395
|
+
});
|
|
392
396
|
const consolidator = new EpisodicConsolidator(semanticMemory, { logger });
|
|
393
397
|
const result = await consolidator.consolidate(session.sessionStore, {
|
|
394
398
|
bootstrapSession: session.id,
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import type { ServiceContainer } from '#inject/ServiceContainer.js';
|
|
16
16
|
import type { EvolveInput } from '#shared/schemas/mcp-tools.js';
|
|
17
17
|
/** MCP handler context */
|
|
18
|
+
/** MCP handler context */
|
|
18
19
|
interface McpContext {
|
|
19
20
|
container: ServiceContainer;
|
|
20
21
|
logger: {
|
|
@@ -46,15 +46,12 @@ export async function evolveExternal(ctx, args) {
|
|
|
46
46
|
const proposalRepo = ctx.container.get('proposalRepository');
|
|
47
47
|
const knowledgeService = ctx.container.get('knowledgeService');
|
|
48
48
|
const supervisor = ctx.container.get('lifecycleSupervisor');
|
|
49
|
-
const
|
|
50
|
-
const rawDb = dbConn?.db ?? null;
|
|
49
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
51
50
|
for (const decision of decisions) {
|
|
52
51
|
try {
|
|
53
52
|
// O4: Recipe 存在性前置检查
|
|
54
|
-
if (
|
|
55
|
-
const exists =
|
|
56
|
-
.prepare('SELECT 1 FROM knowledge_entries WHERE id = ?')
|
|
57
|
-
.get(decision.recipeId);
|
|
53
|
+
if (knowledgeRepo) {
|
|
54
|
+
const exists = await knowledgeRepo.findById(decision.recipeId);
|
|
58
55
|
if (!exists) {
|
|
59
56
|
result.errors.push({ recipeId: decision.recipeId, error: 'Recipe not found' });
|
|
60
57
|
result.processed++;
|
|
@@ -111,7 +108,7 @@ export async function evolveExternal(ctx, args) {
|
|
|
111
108
|
// O1: 优先通过 RecipeLifecycleSupervisor 执行,回退到 KnowledgeService
|
|
112
109
|
const reason = decision.reason || 'IDE Agent confirmed deprecation';
|
|
113
110
|
if (supervisor) {
|
|
114
|
-
const transResult = supervisor.transition({
|
|
111
|
+
const transResult = await supervisor.transition({
|
|
115
112
|
recipeId: decision.recipeId,
|
|
116
113
|
targetState: 'deprecated',
|
|
117
114
|
trigger: 'manual-deprecation',
|
|
@@ -167,17 +164,17 @@ export async function evolveExternal(ctx, args) {
|
|
|
167
164
|
break;
|
|
168
165
|
}
|
|
169
166
|
case 'skip': {
|
|
170
|
-
if (decision.skipReason === 'still_valid' &&
|
|
167
|
+
if (decision.skipReason === 'still_valid' && knowledgeRepo) {
|
|
171
168
|
// P4: 更新 stats.lastVerifiedAt 而非 updated_at
|
|
172
169
|
try {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
.
|
|
180
|
-
|
|
170
|
+
const entry = await knowledgeRepo.findById(decision.recipeId);
|
|
171
|
+
if (entry) {
|
|
172
|
+
const stats = (typeof entry.stats === 'object'
|
|
173
|
+
? entry.stats
|
|
174
|
+
: {});
|
|
175
|
+
stats.lastVerifiedAt = Date.now();
|
|
176
|
+
await knowledgeRepo.updateStats(decision.recipeId, stats);
|
|
177
|
+
}
|
|
181
178
|
result.refreshed++;
|
|
182
179
|
}
|
|
183
180
|
catch {
|
|
@@ -211,7 +211,7 @@ export async function guardReview(ctx, args) {
|
|
|
211
211
|
});
|
|
212
212
|
}
|
|
213
213
|
// 2. 预加载 rule recipe 缓存
|
|
214
|
-
const recipeMap = _loadRuleRecipes(ctx);
|
|
214
|
+
const recipeMap = await _loadRuleRecipes(ctx);
|
|
215
215
|
// 3. 创建引擎,注入 Enhancement Pack
|
|
216
216
|
const engine = _getOrCreateEngine(ctx, GuardCheckEngine);
|
|
217
217
|
await _injectEnhancementGuardRules(engine, ctx);
|
|
@@ -355,24 +355,17 @@ export async function guardReview(ctx, args) {
|
|
|
355
355
|
* 预加载所有 rule 类型 recipe 的修复字段
|
|
356
356
|
* 构建 guardId → recipe 映射
|
|
357
357
|
*/
|
|
358
|
-
function _loadRuleRecipes(ctx) {
|
|
358
|
+
async function _loadRuleRecipes(ctx) {
|
|
359
359
|
const map = new Map();
|
|
360
360
|
try {
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
const rows = db
|
|
365
|
-
.prepare(`
|
|
366
|
-
SELECT id, title, doClause, dontClause, coreCode, constraints
|
|
367
|
-
FROM knowledge_entries
|
|
368
|
-
WHERE (kind = 'rule' OR knowledgeType = 'boundary-constraint')
|
|
369
|
-
AND lifecycle = 'active'
|
|
370
|
-
`)
|
|
371
|
-
.all();
|
|
372
|
-
for (const row of rows) {
|
|
361
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
362
|
+
const entries = await knowledgeRepo.findActiveGuardRecipes();
|
|
363
|
+
for (const row of entries) {
|
|
373
364
|
try {
|
|
374
|
-
const constraints =
|
|
375
|
-
|
|
365
|
+
const constraints = typeof row.constraints === 'object' && row.constraints
|
|
366
|
+
? row.constraints
|
|
367
|
+
: JSON.parse(row.constraints || '{}');
|
|
368
|
+
const guards = (constraints.guards || []);
|
|
376
369
|
for (const g of guards) {
|
|
377
370
|
if (g.id) {
|
|
378
371
|
map.set(g.id, {
|
|
@@ -675,8 +668,7 @@ export async function guardReverseAudit(ctx, args) {
|
|
|
675
668
|
reverseGuard = ctx.container.get('reverseGuard');
|
|
676
669
|
}
|
|
677
670
|
catch {
|
|
678
|
-
|
|
679
|
-
reverseGuard = new ReverseGuard(db.getDb());
|
|
671
|
+
reverseGuard = new ReverseGuard(ctx.container.get('knowledgeRepository'), ctx.container.get('codeEntityRepository'), ctx.container.get('recipeSourceRefRepository'));
|
|
680
672
|
}
|
|
681
673
|
const maxFiles = args.maxFiles || 200;
|
|
682
674
|
const projectFiles = await collectSourceFilesWithContent(projectRoot, { maxFiles });
|
|
@@ -717,8 +709,7 @@ export async function guardCoverageMatrix(ctx, _args) {
|
|
|
717
709
|
analyzer = ctx.container.get('coverageAnalyzer');
|
|
718
710
|
}
|
|
719
711
|
catch {
|
|
720
|
-
|
|
721
|
-
analyzer = new CoverageAnalyzer(db.getDb());
|
|
712
|
+
analyzer = new CoverageAnalyzer(ctx.container.get('knowledgeRepository'), ctx.container.get('guardViolationRepository'));
|
|
722
713
|
}
|
|
723
714
|
// 构建 moduleFiles 映射 — 从 Panorama 或目录结构推断
|
|
724
715
|
const moduleFiles = await _buildModuleFiles(ctx, projectRoot);
|
|
@@ -798,11 +789,11 @@ async function _buildModuleFiles(ctx, projectRoot) {
|
|
|
798
789
|
const moduleFiles = new Map();
|
|
799
790
|
try {
|
|
800
791
|
const panorama = ctx.container.get('panoramaService');
|
|
801
|
-
const
|
|
802
|
-
if (
|
|
803
|
-
for (const mod of
|
|
792
|
+
const result = await panorama.getResult();
|
|
793
|
+
if (result?.modules) {
|
|
794
|
+
for (const [name, mod] of result.modules) {
|
|
804
795
|
if (mod.files?.length > 0) {
|
|
805
|
-
moduleFiles.set(
|
|
796
|
+
moduleFiles.set(name, mod.files);
|
|
806
797
|
}
|
|
807
798
|
}
|
|
808
799
|
}
|
|
@@ -31,7 +31,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
31
31
|
await panoramaService.ensureData();
|
|
32
32
|
switch (op) {
|
|
33
33
|
case 'overview': {
|
|
34
|
-
const overview = panoramaService.getOverview();
|
|
34
|
+
const overview = await panoramaService.getOverview();
|
|
35
35
|
return envelope({
|
|
36
36
|
success: true,
|
|
37
37
|
data: overview,
|
|
@@ -47,7 +47,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
47
47
|
meta: { tool: 'autosnippet_panorama' },
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
|
-
const detail = panoramaService.getModule(moduleName);
|
|
50
|
+
const detail = await panoramaService.getModule(moduleName);
|
|
51
51
|
if (!detail) {
|
|
52
52
|
return envelope({
|
|
53
53
|
success: false,
|
|
@@ -62,7 +62,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
case 'gaps': {
|
|
65
|
-
const gaps = panoramaService.getGaps();
|
|
65
|
+
const gaps = await panoramaService.getGaps();
|
|
66
66
|
return envelope({
|
|
67
67
|
success: true,
|
|
68
68
|
data: { gaps },
|
|
@@ -70,7 +70,7 @@ export async function panoramaHandler(ctx, args) {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
case 'health': {
|
|
73
|
-
const health = panoramaService.getHealth();
|
|
73
|
+
const health = await panoramaService.getHealth();
|
|
74
74
|
return envelope({
|
|
75
75
|
success: true,
|
|
76
76
|
data: health,
|
|
@@ -94,7 +94,7 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
94
94
|
meta: { tool: 'autosnippet_panorama' },
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
|
-
const report = metabolism.runFullCycle();
|
|
97
|
+
const report = await metabolism.runFullCycle();
|
|
98
98
|
return envelope({
|
|
99
99
|
success: true,
|
|
100
100
|
data: report,
|
|
@@ -110,7 +110,7 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
110
110
|
meta: { tool: 'autosnippet_panorama' },
|
|
111
111
|
});
|
|
112
112
|
}
|
|
113
|
-
const results = decayDetector.scanAll();
|
|
113
|
+
const results = await decayDetector.scanAll();
|
|
114
114
|
return envelope({
|
|
115
115
|
success: true,
|
|
116
116
|
data: { results },
|
|
@@ -126,8 +126,8 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
126
126
|
meta: { tool: 'autosnippet_panorama' },
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
|
-
const checkResult = stagingManager.checkAndPromote();
|
|
130
|
-
const currentStaging = stagingManager.listStaging();
|
|
129
|
+
const checkResult = await stagingManager.checkAndPromote();
|
|
130
|
+
const currentStaging = await stagingManager.listStaging();
|
|
131
131
|
return envelope({
|
|
132
132
|
success: true,
|
|
133
133
|
data: { checkResult, currentStaging },
|
|
@@ -143,7 +143,7 @@ async function handleGovernanceOps(ctx, op) {
|
|
|
143
143
|
meta: { tool: 'autosnippet_panorama' },
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
-
const suggestions = suggester.analyzeAll();
|
|
146
|
+
const suggestions = await suggester.analyzeAll();
|
|
147
147
|
return envelope({
|
|
148
148
|
success: true,
|
|
149
149
|
data: { suggestions },
|
|
@@ -65,10 +65,7 @@ export async function rescanExternal(ctx, args) {
|
|
|
65
65
|
? ctx.container.get('knowledgeSyncService')
|
|
66
66
|
: null;
|
|
67
67
|
if (syncService) {
|
|
68
|
-
const
|
|
69
|
-
? db.getDb()
|
|
70
|
-
: db;
|
|
71
|
-
const syncReport = syncService.sync(rawDb, {
|
|
68
|
+
const syncReport = syncService.sync(db, {
|
|
72
69
|
force: true,
|
|
73
70
|
});
|
|
74
71
|
ctx.logger.info('[Rescan] KnowledgeSyncService sync complete', {
|
|
@@ -117,7 +114,11 @@ export async function rescanExternal(ctx, args) {
|
|
|
117
114
|
// Step 4: Recipe 证据验证 + 快速衰退
|
|
118
115
|
// ═══════════════════════════════════════════════════════════
|
|
119
116
|
const auditor = new RecipeRelevanceAuditor({
|
|
120
|
-
|
|
117
|
+
knowledgeRepo: ctx.container.get('knowledgeRepository'),
|
|
118
|
+
proposalRepo: ctx.container.singletons
|
|
119
|
+
?.proposalRepository
|
|
120
|
+
? ctx.container.get('proposalRepository')
|
|
121
|
+
: undefined,
|
|
121
122
|
logger: ctx.logger,
|
|
122
123
|
});
|
|
123
124
|
const codeEntities = extractCodeEntities(astProjectSummary);
|
|
@@ -132,7 +133,7 @@ export async function rescanExternal(ctx, args) {
|
|
|
132
133
|
// ═══════════════════════════════════════════════════════════
|
|
133
134
|
// 按需过滤维度
|
|
134
135
|
const dimensions = args.dimensions?.length
|
|
135
|
-
? allDimensions.filter((d) => args.dimensions
|
|
136
|
+
? allDimensions.filter((d) => args.dimensions?.includes(d.id))
|
|
136
137
|
: allDimensions;
|
|
137
138
|
// 创建 Session
|
|
138
139
|
const sessionManager = getOrCreateSessionManager(ctx.container);
|
|
@@ -71,10 +71,7 @@ export async function rescanInternal(ctx, args) {
|
|
|
71
71
|
/* not registered */
|
|
72
72
|
}
|
|
73
73
|
if (syncService) {
|
|
74
|
-
const
|
|
75
|
-
? db.getDb()
|
|
76
|
-
: db;
|
|
77
|
-
const syncReport = syncService.sync(rawDb, {
|
|
74
|
+
const syncReport = syncService.sync(db, {
|
|
78
75
|
force: true,
|
|
79
76
|
});
|
|
80
77
|
ctx.logger.info('[Rescan-Internal] KnowledgeSyncService sync complete', {
|
|
@@ -119,7 +116,14 @@ export async function rescanInternal(ctx, args) {
|
|
|
119
116
|
// ═══════════════════════════════════════════════════════════
|
|
120
117
|
// Step 4: Recipe 证据验证 + 快速衰退
|
|
121
118
|
// ═══════════════════════════════════════════════════════════
|
|
122
|
-
const auditor = new RecipeRelevanceAuditor({
|
|
119
|
+
const auditor = new RecipeRelevanceAuditor({
|
|
120
|
+
knowledgeRepo: ctx.container.get('knowledgeRepository'),
|
|
121
|
+
proposalRepo: ctx.container.singletons
|
|
122
|
+
?.proposalRepository
|
|
123
|
+
? ctx.container.get('proposalRepository')
|
|
124
|
+
: undefined,
|
|
125
|
+
logger: ctx.logger,
|
|
126
|
+
});
|
|
123
127
|
const codeEntities = extractCodeEntities(astProjectSummary);
|
|
124
128
|
const dependencyEdges = extractDependencyEdges(depGraphData);
|
|
125
129
|
const auditSummary = await auditor.audit(recipeSnapshot.entries, {
|
|
@@ -30,7 +30,9 @@ function getSearchEngine(ctx) {
|
|
|
30
30
|
async function getFallbackEngine(ctx) {
|
|
31
31
|
const { SearchEngine } = await import('#service/search/SearchEngine.js');
|
|
32
32
|
const db = ctx.container.get('database');
|
|
33
|
-
|
|
33
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
34
|
+
const sourceRefRepo = ctx.container.get('recipeSourceRefRepository');
|
|
35
|
+
return new SearchEngine(db, { knowledgeRepo, sourceRefRepo });
|
|
34
36
|
}
|
|
35
37
|
/** 根据 kind 参数过滤 items */
|
|
36
38
|
function filterByKind(items, kind) {
|
|
@@ -648,11 +648,11 @@ export async function suggestSkills(ctx) {
|
|
|
648
648
|
}
|
|
649
649
|
// ── Fallback: 直接使用 SkillAdvisor ──
|
|
650
650
|
const { SkillAdvisor } = await import('#service/skills/SkillAdvisor.js');
|
|
651
|
-
const dbConn = ctx?.container?.get?.('database') || null;
|
|
652
|
-
const database = dbConn?.getDb?.() || dbConn || null;
|
|
653
651
|
const projectRoot = resolveProjectRoot(ctx?.container);
|
|
654
|
-
const
|
|
655
|
-
const
|
|
652
|
+
const knowledgeRepo = ctx?.container?.get?.('knowledgeRepository') || null;
|
|
653
|
+
const auditRepo = ctx?.container?.get?.('auditRepository') || null;
|
|
654
|
+
const advisor = new SkillAdvisor(projectRoot, { knowledgeRepo, auditRepo });
|
|
655
|
+
const result = await advisor.suggest();
|
|
656
656
|
return JSON.stringify({
|
|
657
657
|
success: true,
|
|
658
658
|
data: result,
|
|
@@ -236,7 +236,7 @@ export async function getTargetMetadata(ctx, args) {
|
|
|
236
236
|
try {
|
|
237
237
|
const graphService = ctx.container?.get('knowledgeGraphService');
|
|
238
238
|
if (graphService) {
|
|
239
|
-
const edges = graphService.getEdges(target.name, 'module', 'both');
|
|
239
|
+
const edges = await graphService.getEdges(target.name, 'module', 'both');
|
|
240
240
|
meta.graphEdges = {
|
|
241
241
|
outgoing: (edges.outgoing || []).map((e) => ({
|
|
242
242
|
toId: e.toId,
|
|
@@ -270,10 +270,10 @@ export async function graphQuery(ctx, args) {
|
|
|
270
270
|
let data;
|
|
271
271
|
try {
|
|
272
272
|
if (args.relation) {
|
|
273
|
-
data = graphService.getRelated(args.nodeId, nodeType, args.relation);
|
|
273
|
+
data = await graphService.getRelated(args.nodeId, nodeType, args.relation);
|
|
274
274
|
}
|
|
275
275
|
else {
|
|
276
|
-
data = graphService.getEdges(args.nodeId, nodeType, direction);
|
|
276
|
+
data = await graphService.getEdges(args.nodeId, nodeType, direction);
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
catch (err) {
|
|
@@ -302,7 +302,7 @@ export async function graphImpact(ctx, args) {
|
|
|
302
302
|
const nodeType = args.nodeType || 'recipe';
|
|
303
303
|
let impacted;
|
|
304
304
|
try {
|
|
305
|
-
impacted = graphService.getImpactAnalysis(args.nodeId, nodeType, args.maxDepth ?? 3);
|
|
305
|
+
impacted = await graphService.getImpactAnalysis(args.nodeId, nodeType, args.maxDepth ?? 3);
|
|
306
306
|
}
|
|
307
307
|
catch (err) {
|
|
308
308
|
// knowledge_edges 表不存在时 graceful 降级
|
|
@@ -360,9 +360,7 @@ async function _fallbackRelationsFromRecipe(ctx, nodeId, relation, direction) {
|
|
|
360
360
|
const incoming = [];
|
|
361
361
|
if (direction === 'both' || direction === 'in') {
|
|
362
362
|
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
363
|
-
const reverseRows = knowledgeRepo.
|
|
364
|
-
.prepare(`SELECT id, relations FROM knowledge_entries WHERE relations LIKE ? AND id != ?`)
|
|
365
|
-
.all(`%${nodeId}%`, nodeId);
|
|
363
|
+
const reverseRows = await knowledgeRepo.findByRelationLike(nodeId, nodeId);
|
|
366
364
|
for (const row of reverseRows) {
|
|
367
365
|
try {
|
|
368
366
|
const rels = JSON.parse(row.relations || '{}');
|
|
@@ -399,9 +397,7 @@ async function _fallbackRelationsFromRecipe(ctx, nodeId, relation, direction) {
|
|
|
399
397
|
async function _fallbackImpactFromRecipe(ctx, nodeId) {
|
|
400
398
|
try {
|
|
401
399
|
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
402
|
-
const rows = knowledgeRepo.
|
|
403
|
-
.prepare(`SELECT id, title, relations FROM knowledge_entries WHERE relations LIKE ? AND id != ?`)
|
|
404
|
-
.all(`%${nodeId}%`, nodeId);
|
|
400
|
+
const rows = await knowledgeRepo.findByRelationLike(nodeId, nodeId);
|
|
405
401
|
const impacted = [];
|
|
406
402
|
for (const row of rows) {
|
|
407
403
|
try {
|
|
@@ -448,7 +444,7 @@ export async function graphPath(ctx, args) {
|
|
|
448
444
|
const maxDepth = Math.min(Math.max(args.maxDepth ?? 5, 1), 10);
|
|
449
445
|
let result;
|
|
450
446
|
try {
|
|
451
|
-
result = graphService.findPath(args.fromId, fromType, args.toId, toType, maxDepth);
|
|
447
|
+
result = await graphService.findPath(args.fromId, fromType, args.toId, toType, maxDepth);
|
|
452
448
|
}
|
|
453
449
|
catch (err) {
|
|
454
450
|
if (err instanceof Error && err.message?.includes('no such table')) {
|
|
@@ -568,7 +564,7 @@ export async function graphStats(ctx) {
|
|
|
568
564
|
}
|
|
569
565
|
let stats;
|
|
570
566
|
try {
|
|
571
|
-
stats = graphService.getStats();
|
|
567
|
+
stats = await graphService.getStats();
|
|
572
568
|
}
|
|
573
569
|
catch (err) {
|
|
574
570
|
if (err instanceof Error && err.message?.includes('no such table')) {
|
|
@@ -22,46 +22,22 @@ export async function health(ctx) {
|
|
|
22
22
|
}
|
|
23
23
|
// 2) Database 连通性 + 知识库统计
|
|
24
24
|
try {
|
|
25
|
-
const
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
const db = typeof dbConn.getDb === 'function' ? dbConn.getDb() : dbConn;
|
|
29
|
-
db.prepare('SELECT 1').get();
|
|
25
|
+
const knowledgeRepo = ctx.container.get('knowledgeRepository');
|
|
26
|
+
if (knowledgeRepo) {
|
|
27
|
+
const stats = (await knowledgeRepo.getStats());
|
|
30
28
|
checks.database = true;
|
|
31
|
-
|
|
32
|
-
try {
|
|
33
|
-
// V3: knowledge_entries 统一表(lifecycle 替代 status)
|
|
34
|
-
const rStats = db
|
|
35
|
-
.prepare(`
|
|
36
|
-
SELECT COUNT(*) as total,
|
|
37
|
-
SUM(CASE WHEN lifecycle='active' THEN 1 ELSE 0 END) as active,
|
|
38
|
-
SUM(CASE WHEN kind='rule' THEN 1 ELSE 0 END) as rules,
|
|
39
|
-
SUM(CASE WHEN kind='pattern' THEN 1 ELSE 0 END) as patterns,
|
|
40
|
-
SUM(CASE WHEN kind='fact' THEN 1 ELSE 0 END) as facts
|
|
41
|
-
FROM knowledge_entries
|
|
42
|
-
`)
|
|
43
|
-
.get();
|
|
44
|
-
const cPending = db
|
|
45
|
-
.prepare(`
|
|
46
|
-
SELECT COUNT(*) as total,
|
|
47
|
-
SUM(CASE WHEN lifecycle='pending' THEN 1 ELSE 0 END) as pending
|
|
48
|
-
FROM knowledge_entries
|
|
49
|
-
`)
|
|
50
|
-
.get();
|
|
29
|
+
if (stats) {
|
|
51
30
|
knowledgeBase = {
|
|
52
31
|
recipes: {
|
|
53
|
-
total:
|
|
54
|
-
active:
|
|
55
|
-
rules:
|
|
56
|
-
patterns:
|
|
57
|
-
facts:
|
|
32
|
+
total: stats.total,
|
|
33
|
+
active: stats.active,
|
|
34
|
+
rules: stats.rules,
|
|
35
|
+
patterns: stats.patterns,
|
|
36
|
+
facts: stats.facts,
|
|
58
37
|
},
|
|
59
|
-
candidates: { total:
|
|
38
|
+
candidates: { total: stats.total, pending: stats.pending },
|
|
60
39
|
};
|
|
61
40
|
}
|
|
62
|
-
catch {
|
|
63
|
-
/* 统计查询失败不影响 health */
|
|
64
|
-
}
|
|
65
41
|
}
|
|
66
42
|
}
|
|
67
43
|
catch (e) {
|