autosnippet 3.3.6 → 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 +8 -4
- package/dist/lib/agent/AgentRuntime.d.ts +2 -2
- package/dist/lib/agent/AgentRuntime.js +26 -18
- 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/domain/ChatAgentTasks.js +4 -0
- package/dist/lib/agent/forced-summary.js +7 -2
- 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 +8 -21
- 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/ConfigWatcher.d.ts +64 -0
- package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +28 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1303 -0
- package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
- package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
- package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
- package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
- package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
- package/dist/lib/core/discovery/index.d.ts +2 -0
- package/dist/lib/core/discovery/index.js +4 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
- 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/KnowledgeEntry.d.ts +7 -1
- package/dist/lib/domain/knowledge/KnowledgeEntry.js +17 -3
- 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/ai/AiProvider.d.ts +12 -0
- package/dist/lib/external/ai/AiProvider.js +24 -0
- package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
- package/dist/lib/external/ai/AiProviderManager.js +193 -0
- package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
- package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
- package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
- package/dist/lib/external/ai/providers/MockProvider.js +290 -14
- package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
- package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
- package/dist/lib/external/lark/LarkTransport.js +10 -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.d.ts +20 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -24
- package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
- 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.d.ts +9 -0
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +3 -1
- package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
- package/dist/lib/external/mcp/handlers/consolidated.js +2 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +9 -4
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +18 -18
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/knowledge.js +5 -4
- 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 +109 -30
- package/dist/lib/http/routes/candidates.js +11 -4
- package/dist/lib/http/routes/commands.js +10 -1
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/health.js +11 -0
- package/dist/lib/http/routes/modules.js +27 -0
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +66 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/http/utils/routeHelpers.js +2 -1
- 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.d.ts +6 -5
- package/dist/lib/injection/ServiceContainer.js +18 -31
- package/dist/lib/injection/ServiceMap.d.ts +22 -0
- package/dist/lib/injection/modules/AiModule.d.ts +6 -9
- package/dist/lib/injection/modules/AiModule.js +82 -39
- 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.d.ts +54 -7
- package/dist/lib/service/cleanup/CleanupService.js +291 -40
- 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 +45 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -496
- 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 +97 -46
- 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/module/ModuleService.js +10 -19
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +14 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +137 -32
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +94 -33
- package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
- package/dist/lib/service/panorama/LayerInferrer.js +118 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +14 -4
- package/dist/lib/service/panorama/ModuleDiscoverer.js +209 -61
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +15 -4
- package/dist/lib/service/panorama/PanoramaAggregator.js +128 -62
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +60 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +49 -69
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +41 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +10 -5
- package/dist/lib/service/panorama/RoleRefiner.js +92 -282
- package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
- package/dist/lib/service/panorama/TechStackProfiler.js +79 -0
- 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 +6 -8
- package/dist/lib/service/skills/SignalCollector.js +34 -60
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
- package/dist/lib/service/vector/ContextualEnricher.js +4 -0
- 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 +19 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/developer-identity.d.ts +18 -0
- package/dist/lib/shared/developer-identity.js +62 -0
- package/dist/lib/shared/schemas/http-requests.d.ts +8 -17
- package/dist/lib/shared/schemas/http-requests.js +9 -6
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/knowledge-wire.d.ts +1 -0
- 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-D1aVZYFW.js +0 -1
- package/dashboard/dist/assets/index-CxHOu8Hd.css +0 -1
- package/dashboard/dist/assets/index-DDdAOpYT.js +0 -128
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -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) {
|
|
@@ -25,6 +25,15 @@ const logger = Logger.getInstance();
|
|
|
25
25
|
function getContainer() {
|
|
26
26
|
return getServiceContainer();
|
|
27
27
|
}
|
|
28
|
+
/** 检查 AI Provider 是否可用(非 mock),不可用则抛 ValidationError */
|
|
29
|
+
function requireAiReady() {
|
|
30
|
+
const container = getContainer();
|
|
31
|
+
const manager = container.singletons?._aiProviderManager;
|
|
32
|
+
if (manager?.isMock) {
|
|
33
|
+
throw new ValidationError('AI Provider 未配置,当前为 Mock 模式。请先在 .env 中配置 API Key。');
|
|
34
|
+
}
|
|
35
|
+
return container;
|
|
36
|
+
}
|
|
28
37
|
// ═══════════════════════════════════════════════════════
|
|
29
38
|
// UI 语言偏好 — 前端 ↔ 服务端同步
|
|
30
39
|
// ═══════════════════════════════════════════════════════
|
|
@@ -76,22 +85,19 @@ router.get('/providers', async (req, res) => {
|
|
|
76
85
|
});
|
|
77
86
|
/**
|
|
78
87
|
* GET /api/v1/ai/config
|
|
79
|
-
* 获取当前 AI
|
|
88
|
+
* 获取当前 AI 配置(优先从 AiProviderManager 读取)
|
|
80
89
|
*/
|
|
81
90
|
router.get('/config', async (req, res) => {
|
|
82
91
|
const container = getServiceContainer();
|
|
83
|
-
const
|
|
92
|
+
const manager = container.singletons?._aiProviderManager;
|
|
84
93
|
res.json({
|
|
85
94
|
success: true,
|
|
86
|
-
data: {
|
|
87
|
-
provider: p?.name || '',
|
|
88
|
-
model: p?.model || '',
|
|
89
|
-
},
|
|
95
|
+
data: { provider: manager.name, model: manager.model, isMock: manager.isMock },
|
|
90
96
|
});
|
|
91
97
|
});
|
|
92
98
|
/**
|
|
93
99
|
* POST /api/v1/ai/config
|
|
94
|
-
* 更新 AI
|
|
100
|
+
* 更新 AI 配置(切换提供商/模型)— 通过 AiProviderManager 统一热切换
|
|
95
101
|
*/
|
|
96
102
|
router.post('/config', validate(AiConfigBody), async (req, res) => {
|
|
97
103
|
const { provider, model } = req.body;
|
|
@@ -106,18 +112,13 @@ router.post('/config', validate(AiConfigBody), async (req, res) => {
|
|
|
106
112
|
catch (error) {
|
|
107
113
|
throw new ValidationError(`Invalid provider: ${error.message}`);
|
|
108
114
|
}
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
logger.debug('DI container 同步 AI provider 失败', { error: err.message });
|
|
120
|
-
}
|
|
115
|
+
// 通过 reloadAiProvider → AiProviderManager.switchProvider() 统一热切换
|
|
116
|
+
const container = getServiceContainer();
|
|
117
|
+
container.reloadAiProvider(newProvider);
|
|
118
|
+
logger.info('AI provider switched via AiProviderManager', {
|
|
119
|
+
provider: provider.toLowerCase(),
|
|
120
|
+
model: newProvider.model,
|
|
121
|
+
});
|
|
121
122
|
res.json({
|
|
122
123
|
success: true,
|
|
123
124
|
data: {
|
|
@@ -127,13 +128,56 @@ router.post('/config', validate(AiConfigBody), async (req, res) => {
|
|
|
127
128
|
},
|
|
128
129
|
});
|
|
129
130
|
});
|
|
131
|
+
/**
|
|
132
|
+
* POST /api/v1/ai/mock/cleanup
|
|
133
|
+
* 清理 Mock 模式产生的候选数据
|
|
134
|
+
*/
|
|
135
|
+
router.post('/mock/cleanup', async (_req, res) => {
|
|
136
|
+
const container = getContainer();
|
|
137
|
+
const knowledgeService = container.get('knowledgeService');
|
|
138
|
+
const knowledgeRepo = container.get('knowledgeRepository');
|
|
139
|
+
// 查找所有 mock 来源的候选
|
|
140
|
+
const mockSources = ['mock-bootstrap', 'mock-pipeline'];
|
|
141
|
+
let totalDeleted = 0;
|
|
142
|
+
for (const source of mockSources) {
|
|
143
|
+
const ids = await knowledgeRepo.findIdsBySource(source);
|
|
144
|
+
for (const id of ids) {
|
|
145
|
+
try {
|
|
146
|
+
await knowledgeService.delete(id, { userId: 'system:mock-cleanup' });
|
|
147
|
+
totalDeleted++;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
logger.debug(`Mock cleanup: failed to delete ${id}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// 清理 bootstrap 来源的 semantic_memories
|
|
155
|
+
try {
|
|
156
|
+
const memoryRepo = container.get('memoryRepository');
|
|
157
|
+
if (memoryRepo) {
|
|
158
|
+
await memoryRepo.clearBootstrapMemories();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// memoryRepository 可能未注册
|
|
163
|
+
}
|
|
164
|
+
logger.info(`Mock cleanup completed: ${totalDeleted} entries deleted`);
|
|
165
|
+
const rt = getRealtimeService();
|
|
166
|
+
if (rt) {
|
|
167
|
+
rt.broadcastEvent('mock-cleanup-completed', { deleted: totalDeleted });
|
|
168
|
+
}
|
|
169
|
+
res.json({
|
|
170
|
+
success: true,
|
|
171
|
+
data: { deleted: totalDeleted },
|
|
172
|
+
});
|
|
173
|
+
});
|
|
130
174
|
/**
|
|
131
175
|
* POST /api/v1/ai/summarize
|
|
132
176
|
* AI 摘要生成
|
|
133
177
|
*/
|
|
134
178
|
router.post('/summarize', validate(AiSummarizeBody), async (req, res) => {
|
|
135
179
|
const { code, language } = req.body;
|
|
136
|
-
const container =
|
|
180
|
+
const container = requireAiReady();
|
|
137
181
|
const factory = container.get('agentFactory');
|
|
138
182
|
const result = await factory.scanKnowledge({
|
|
139
183
|
label: 'code',
|
|
@@ -158,7 +202,7 @@ router.post('/translate', validate(AiTranslateBody), async (req, res) => {
|
|
|
158
202
|
});
|
|
159
203
|
}
|
|
160
204
|
try {
|
|
161
|
-
const container =
|
|
205
|
+
const container = requireAiReady();
|
|
162
206
|
const factory = container.get('agentFactory');
|
|
163
207
|
const result = await factory.translateToEnglish(summary, usageGuide);
|
|
164
208
|
if (result?.error) {
|
|
@@ -197,7 +241,7 @@ router.post('/translate', validate(AiTranslateBody), async (req, res) => {
|
|
|
197
241
|
*/
|
|
198
242
|
router.post('/chat', validate(AiChatBody), async (req, res) => {
|
|
199
243
|
const { prompt, history, lang, conversationId } = req.body;
|
|
200
|
-
const container =
|
|
244
|
+
const container = requireAiReady();
|
|
201
245
|
const factory = container.get('agentFactory');
|
|
202
246
|
// ── 对话持久化: 从 ConversationStore 加载历史 ──
|
|
203
247
|
let convStore = null;
|
|
@@ -309,7 +353,7 @@ router.post('/chat', validate(AiChatBody), async (req, res) => {
|
|
|
309
353
|
*/
|
|
310
354
|
router.post('/agent/tool', validate(AiToolBody), async (req, res) => {
|
|
311
355
|
const { tool, params } = req.body;
|
|
312
|
-
const container =
|
|
356
|
+
const container = requireAiReady();
|
|
313
357
|
const factory = container.get('agentFactory');
|
|
314
358
|
const result = await factory.invokeAgent(tool, params);
|
|
315
359
|
res.json({ success: true, data: result });
|
|
@@ -332,7 +376,7 @@ const DAG_TASK_HANDLERS = {
|
|
|
332
376
|
};
|
|
333
377
|
router.post('/agent/task', validate(AiTaskBody), async (req, res) => {
|
|
334
378
|
const { task, params } = req.body;
|
|
335
|
-
const container =
|
|
379
|
+
const container = requireAiReady();
|
|
336
380
|
const factory = container.get('agentFactory');
|
|
337
381
|
// 优先尝试 DAG 任务
|
|
338
382
|
const dagHandler = DAG_TASK_HANDLERS[task];
|
|
@@ -530,7 +574,7 @@ router.post('/env-config', validate(AiEnvConfigBody), async (req, res) => {
|
|
|
530
574
|
for (const [k, v] of Object.entries(updates)) {
|
|
531
575
|
process.env[k] = String(v);
|
|
532
576
|
}
|
|
533
|
-
// 尝试热切换 AI Provider
|
|
577
|
+
// 尝试热切换 AI Provider(通过 AiProviderManager 统一处理)
|
|
534
578
|
try {
|
|
535
579
|
const newProvider = createProvider({
|
|
536
580
|
provider: provider.toLowerCase(),
|
|
@@ -538,7 +582,7 @@ router.post('/env-config', validate(AiEnvConfigBody), async (req, res) => {
|
|
|
538
582
|
});
|
|
539
583
|
const container = getServiceContainer();
|
|
540
584
|
container.reloadAiProvider(newProvider);
|
|
541
|
-
logger.info('AI provider hot-swapped after env update', {
|
|
585
|
+
logger.info('AI provider hot-swapped via AiProviderManager after env update', {
|
|
542
586
|
provider,
|
|
543
587
|
model: newProvider.model,
|
|
544
588
|
});
|
|
@@ -576,7 +620,7 @@ router.post('/env-config', validate(AiEnvConfigBody), async (req, res) => {
|
|
|
576
620
|
*/
|
|
577
621
|
router.post('/chat/stream', validate(AiStreamBody), async (req, res) => {
|
|
578
622
|
const { prompt, history, lang } = req.body;
|
|
579
|
-
const container =
|
|
623
|
+
const container = requireAiReady();
|
|
580
624
|
const factory = container.get('agentFactory');
|
|
581
625
|
const session = createStreamSession('chat');
|
|
582
626
|
logger.debug('SSE session created', { sessionId: session.sessionId });
|
|
@@ -626,18 +670,53 @@ router.post('/chat/stream', validate(AiStreamBody), async (req, res) => {
|
|
|
626
670
|
runtime
|
|
627
671
|
.execute(message)
|
|
628
672
|
.then((result) => {
|
|
673
|
+
const replyText = result.reply || '';
|
|
629
674
|
// 发送最终文本
|
|
630
|
-
if (
|
|
675
|
+
if (replyText) {
|
|
631
676
|
const textId = `text_${Date.now()}`;
|
|
632
677
|
session.send({ type: 'text:start', id: textId, role: 'assistant' });
|
|
633
|
-
session.send({ type: 'text:delta', id: textId, delta:
|
|
678
|
+
session.send({ type: 'text:delta', id: textId, delta: replyText });
|
|
634
679
|
session.send({ type: 'text:end', id: textId });
|
|
635
680
|
}
|
|
681
|
+
else {
|
|
682
|
+
logger.warn('SSE session: empty reply from AgentRuntime', {
|
|
683
|
+
sessionId: session.sessionId,
|
|
684
|
+
iterations: result.iterations,
|
|
685
|
+
toolCalls: result.toolCalls?.length || 0,
|
|
686
|
+
});
|
|
687
|
+
}
|
|
636
688
|
session.end({
|
|
637
|
-
text:
|
|
689
|
+
text: replyText || '抱歉,AI 未能生成有效回复。请重试或换个问题。',
|
|
638
690
|
toolCalls: result.toolCalls || [],
|
|
639
691
|
iterations: result.iterations || 0,
|
|
640
692
|
});
|
|
693
|
+
// ── Token 用量持久化(streaming) ──
|
|
694
|
+
try {
|
|
695
|
+
const tokenUsage = result.tokenUsage;
|
|
696
|
+
if (tokenUsage) {
|
|
697
|
+
const tokenStore = container.get('tokenUsageStore');
|
|
698
|
+
const aiProvider = container.singletons?.aiProvider;
|
|
699
|
+
tokenStore.record({
|
|
700
|
+
source: 'user',
|
|
701
|
+
provider: aiProvider?.name ?? undefined,
|
|
702
|
+
model: aiProvider?.model ?? undefined,
|
|
703
|
+
inputTokens: tokenUsage.input || 0,
|
|
704
|
+
outputTokens: tokenUsage.output || 0,
|
|
705
|
+
durationMs: result.durationMs || 0,
|
|
706
|
+
toolCalls: result.toolCalls?.length || 0,
|
|
707
|
+
});
|
|
708
|
+
try {
|
|
709
|
+
const realtime = getRealtimeService();
|
|
710
|
+
realtime?.broadcastTokenUsageUpdated?.();
|
|
711
|
+
}
|
|
712
|
+
catch {
|
|
713
|
+
/* ignore */
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
catch {
|
|
718
|
+
/* token tracking should never break streaming */
|
|
719
|
+
}
|
|
641
720
|
logger.debug('SSE session completed', {
|
|
642
721
|
sessionId: session.sessionId,
|
|
643
722
|
events: session.buffer.length,
|
|
@@ -55,6 +55,13 @@ router.post('/enrich', validate(EnrichBody), async (req, res) => {
|
|
|
55
55
|
let enrichedCount = 0;
|
|
56
56
|
const results = [];
|
|
57
57
|
if (aiProvider) {
|
|
58
|
+
// Mock 模式下跳过 AI enrichment
|
|
59
|
+
if (aiProvider.name === 'mock') {
|
|
60
|
+
return void res.json({
|
|
61
|
+
success: true,
|
|
62
|
+
data: { enriched: 0, total: candidates.length, results: [], mock: true },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
58
65
|
let enriched = [];
|
|
59
66
|
try {
|
|
60
67
|
// 获取用户语言偏好
|
|
@@ -418,8 +425,8 @@ router.post('/refine-preview', validate(RefinePreviewBody), async (req, res) =>
|
|
|
418
425
|
const container = getServiceContainer();
|
|
419
426
|
const knowledgeService = container.get('knowledgeService');
|
|
420
427
|
const aiProvider = container.get('aiProvider');
|
|
421
|
-
if (!aiProvider) {
|
|
422
|
-
throw new ValidationError('AI
|
|
428
|
+
if (!aiProvider || aiProvider.name === 'mock') {
|
|
429
|
+
throw new ValidationError('AI Provider 未配置,当前为 Mock 模式。请先配置 API Key。');
|
|
423
430
|
}
|
|
424
431
|
const entry = await knowledgeService.get(candidateId);
|
|
425
432
|
if (!entry) {
|
|
@@ -459,8 +466,8 @@ router.post('/refine-preview-stream', validate(RefinePreviewBody), async (req, r
|
|
|
459
466
|
const container = getServiceContainer();
|
|
460
467
|
const knowledgeService = container.get('knowledgeService');
|
|
461
468
|
const aiProvider = container.get('aiProvider');
|
|
462
|
-
if (!aiProvider) {
|
|
463
|
-
throw new ValidationError('AI
|
|
469
|
+
if (!aiProvider || aiProvider.name === 'mock') {
|
|
470
|
+
throw new ValidationError('AI Provider 未配置,当前为 Mock 模式。请先配置 API Key。');
|
|
464
471
|
}
|
|
465
472
|
const entry = await knowledgeService.get(candidateId);
|
|
466
473
|
if (!entry) {
|
|
@@ -29,6 +29,15 @@ router.post('/spm-map', async (req, res) => {
|
|
|
29
29
|
*/
|
|
30
30
|
router.post('/embed', async (req, res) => {
|
|
31
31
|
const container = getServiceContainer();
|
|
32
|
+
// Mock 模式下向量构建需要 embedding — 拒绝执行
|
|
33
|
+
const manager = container.singletons?._aiProviderManager;
|
|
34
|
+
if (manager?.isMock) {
|
|
35
|
+
res.status(400).json({
|
|
36
|
+
success: false,
|
|
37
|
+
message: 'AI Provider 未配置,当前为 Mock 模式。Embedding 不可用。',
|
|
38
|
+
});
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
32
41
|
// 优先使用 VectorService (新架构), 降级到 indexingPipeline (旧架构)
|
|
33
42
|
const vectorService = container.services.vectorService ? container.get('vectorService') : null;
|
|
34
43
|
let result;
|
|
@@ -80,7 +89,7 @@ router.get('/status', async (req, res) => {
|
|
|
80
89
|
spmMap: { available: false },
|
|
81
90
|
};
|
|
82
91
|
try {
|
|
83
|
-
const
|
|
92
|
+
const _indexingPipeline = container.get('indexingPipeline');
|
|
84
93
|
status.index.ready = true; // IndexingPipeline is available
|
|
85
94
|
}
|
|
86
95
|
catch {
|
|
@@ -67,8 +67,7 @@ router.get('/reverse', async (req, res) => {
|
|
|
67
67
|
reverseGuard = container.get('reverseGuard');
|
|
68
68
|
}
|
|
69
69
|
catch {
|
|
70
|
-
|
|
71
|
-
reverseGuard = new ReverseGuard(db.getDb());
|
|
70
|
+
reverseGuard = new ReverseGuard(container.get('knowledgeRepository'), container.get('codeEntityRepository'), container.get('recipeSourceRefRepository'));
|
|
72
71
|
}
|
|
73
72
|
const maxFiles = req.query.maxFiles ? Number(req.query.maxFiles) : 200;
|
|
74
73
|
const projectFiles = await collectSourceFilesWithContent(projectRoot, { maxFiles });
|
|
@@ -111,14 +110,13 @@ router.get('/coverage', async (_req, res) => {
|
|
|
111
110
|
analyzer = container.get('coverageAnalyzer');
|
|
112
111
|
}
|
|
113
112
|
catch {
|
|
114
|
-
|
|
115
|
-
analyzer = new CoverageAnalyzer(db.getDb());
|
|
113
|
+
analyzer = new CoverageAnalyzer(container.get('knowledgeRepository'), container.get('guardViolationRepository'));
|
|
116
114
|
}
|
|
117
115
|
// 从 Panorama 或目录结构获取模块文件
|
|
118
116
|
const moduleFiles = new Map();
|
|
119
117
|
try {
|
|
120
118
|
const panorama = container.get('panoramaService');
|
|
121
|
-
const overview = panorama.getOverview();
|
|
119
|
+
const overview = await panorama.getOverview();
|
|
122
120
|
if (overview?.modules) {
|
|
123
121
|
for (const mod of overview.modules) {
|
|
124
122
|
if (mod.files?.length > 0) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** 健康检查端点 */
|
|
2
2
|
import express from 'express';
|
|
3
|
+
import { getDeveloperIdentity } from '../../shared/developer-identity.js';
|
|
3
4
|
const router = express.Router();
|
|
4
5
|
/**
|
|
5
6
|
* GET /api/v1/health
|
|
@@ -25,4 +26,14 @@ router.get('/ready', (req, res) => {
|
|
|
25
26
|
timestamp: Math.floor(Date.now() / 1000),
|
|
26
27
|
});
|
|
27
28
|
});
|
|
29
|
+
/**
|
|
30
|
+
* GET /api/v1/health/identity
|
|
31
|
+
* 当前开发者身份(从 git config / 环境变量解析)
|
|
32
|
+
*/
|
|
33
|
+
router.get('/identity', (_req, res) => {
|
|
34
|
+
res.json({
|
|
35
|
+
success: true,
|
|
36
|
+
developer: getDeveloperIdentity(),
|
|
37
|
+
});
|
|
38
|
+
});
|
|
28
39
|
export default router;
|
|
@@ -459,6 +459,33 @@ router.get('/bootstrap/status', async (req, res) => {
|
|
|
459
459
|
data: taskManager.getSessionStatus(),
|
|
460
460
|
});
|
|
461
461
|
});
|
|
462
|
+
/**
|
|
463
|
+
* POST /api/v1/modules/bootstrap/cancel
|
|
464
|
+
* 取消正在运行的 bootstrap / rescan 异步填充会话
|
|
465
|
+
*/
|
|
466
|
+
router.post('/bootstrap/cancel', async (req, res) => {
|
|
467
|
+
const container = getServiceContainer();
|
|
468
|
+
let taskManager = null;
|
|
469
|
+
try {
|
|
470
|
+
taskManager = container.get('bootstrapTaskManager');
|
|
471
|
+
}
|
|
472
|
+
catch {
|
|
473
|
+
/* not registered */
|
|
474
|
+
}
|
|
475
|
+
if (!taskManager) {
|
|
476
|
+
return void res.json({ success: true, message: 'No bootstrap task manager initialized' });
|
|
477
|
+
}
|
|
478
|
+
if (!taskManager.isRunning) {
|
|
479
|
+
return void res.json({ success: true, message: 'No active bootstrap session' });
|
|
480
|
+
}
|
|
481
|
+
const reason = req.body?.reason || 'Cancelled by user via Dashboard';
|
|
482
|
+
taskManager.abortSession(reason);
|
|
483
|
+
logger.info('Bootstrap session cancelled via HTTP', { reason });
|
|
484
|
+
res.json({
|
|
485
|
+
success: true,
|
|
486
|
+
data: taskManager.getSessionStatus(),
|
|
487
|
+
});
|
|
488
|
+
});
|
|
462
489
|
/**
|
|
463
490
|
* POST /api/v1/modules/rescan
|
|
464
491
|
* 增量扫描:保留已有 Recipe,重新分析项目,补齐缺失知识
|
|
@@ -31,7 +31,7 @@ router.get('/', async (req, res) => {
|
|
|
31
31
|
if (typeof panoramaService.ensureData === 'function') {
|
|
32
32
|
await panoramaService.ensureData();
|
|
33
33
|
}
|
|
34
|
-
const overview = panoramaService.getOverview();
|
|
34
|
+
const overview = await panoramaService.getOverview();
|
|
35
35
|
res.json({ success: true, data: overview });
|
|
36
36
|
}
|
|
37
37
|
catch (err) {
|
|
@@ -62,7 +62,7 @@ router.get('/health', async (req, res) => {
|
|
|
62
62
|
if (typeof panoramaService.ensureData === 'function') {
|
|
63
63
|
await panoramaService.ensureData();
|
|
64
64
|
}
|
|
65
|
-
const health = panoramaService.getHealth();
|
|
65
|
+
const health = await panoramaService.getHealth();
|
|
66
66
|
res.json({ success: true, data: health });
|
|
67
67
|
}
|
|
68
68
|
catch (err) {
|
|
@@ -93,7 +93,7 @@ router.get('/gaps', async (req, res) => {
|
|
|
93
93
|
if (typeof panoramaService.ensureData === 'function') {
|
|
94
94
|
await panoramaService.ensureData();
|
|
95
95
|
}
|
|
96
|
-
const gaps = panoramaService.getGaps();
|
|
96
|
+
const gaps = await panoramaService.getGaps();
|
|
97
97
|
res.json({ success: true, data: gaps });
|
|
98
98
|
}
|
|
99
99
|
catch (err) {
|
|
@@ -124,8 +124,8 @@ router.get('/coverage', async (req, res) => {
|
|
|
124
124
|
if (typeof panoramaService.ensureData === 'function') {
|
|
125
125
|
await panoramaService.ensureData();
|
|
126
126
|
}
|
|
127
|
-
const overview = panoramaService.getOverview();
|
|
128
|
-
const gaps = panoramaService.getGaps?.() ?? [];
|
|
127
|
+
const overview = await panoramaService.getOverview();
|
|
128
|
+
const gaps = (await panoramaService.getGaps?.()) ?? [];
|
|
129
129
|
// 构建模块级覆盖率数据:从 overview.layers 中提取每个模块的文件数和 recipe 数
|
|
130
130
|
const modules = [];
|
|
131
131
|
for (const layer of overview.layers || []) {
|
|
@@ -187,7 +187,7 @@ router.get('/module/:name', async (req, res) => {
|
|
|
187
187
|
if (typeof panoramaService.ensureData === 'function') {
|
|
188
188
|
await panoramaService.ensureData();
|
|
189
189
|
}
|
|
190
|
-
const detail = panoramaService.getModule(req.params.name);
|
|
190
|
+
const detail = await panoramaService.getModule(req.params.name);
|
|
191
191
|
if (!detail) {
|
|
192
192
|
res.status(404).json({
|
|
193
193
|
success: false,
|
|
@@ -220,7 +220,7 @@ router.post('/governance/cycle', async (_req, res) => {
|
|
|
220
220
|
});
|
|
221
221
|
return;
|
|
222
222
|
}
|
|
223
|
-
const report = metabolism.runFullCycle();
|
|
223
|
+
const report = await metabolism.runFullCycle();
|
|
224
224
|
res.json({ success: true, data: report });
|
|
225
225
|
}
|
|
226
226
|
catch (err) {
|
|
@@ -245,7 +245,7 @@ router.get('/governance/decay', async (_req, res) => {
|
|
|
245
245
|
});
|
|
246
246
|
return;
|
|
247
247
|
}
|
|
248
|
-
const results = decayDetector.scanAll();
|
|
248
|
+
const results = await decayDetector.scanAll();
|
|
249
249
|
res.json({ success: true, data: { results } });
|
|
250
250
|
}
|
|
251
251
|
catch (err) {
|
|
@@ -270,8 +270,8 @@ router.post('/governance/staging-check', async (_req, res) => {
|
|
|
270
270
|
});
|
|
271
271
|
return;
|
|
272
272
|
}
|
|
273
|
-
const checkResult = stagingManager.checkAndPromote();
|
|
274
|
-
const currentStaging = stagingManager.listStaging();
|
|
273
|
+
const checkResult = await stagingManager.checkAndPromote();
|
|
274
|
+
const currentStaging = await stagingManager.listStaging();
|
|
275
275
|
res.json({ success: true, data: { checkResult, currentStaging } });
|
|
276
276
|
}
|
|
277
277
|
catch (err) {
|
|
@@ -296,7 +296,7 @@ router.get('/governance/staging', async (_req, res) => {
|
|
|
296
296
|
});
|
|
297
297
|
return;
|
|
298
298
|
}
|
|
299
|
-
const entries = stagingManager.listStaging();
|
|
299
|
+
const entries = await stagingManager.listStaging();
|
|
300
300
|
res.json({ success: true, data: { entries } });
|
|
301
301
|
}
|
|
302
302
|
catch (err) {
|
|
@@ -321,7 +321,7 @@ router.get('/governance/enhancements', async (_req, res) => {
|
|
|
321
321
|
});
|
|
322
322
|
return;
|
|
323
323
|
}
|
|
324
|
-
const suggestions = suggester.analyzeAll();
|
|
324
|
+
const suggestions = await suggester.analyzeAll();
|
|
325
325
|
res.json({ success: true, data: { suggestions } });
|
|
326
326
|
}
|
|
327
327
|
catch (err) {
|