autosnippet 3.3.0 → 3.3.3
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/dashboard/dist/assets/icons-BJ2mUBi8.js +1 -0
- package/dashboard/dist/assets/index-B659K9t5.js +128 -0
- package/dashboard/dist/assets/index-NCm40PMD.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.d.ts +1 -0
- package/dist/bin/cli.js +284 -142
- package/dist/lib/agent/context/ExplorationTracker.d.ts +2 -0
- package/dist/lib/agent/context/ExplorationTracker.js +21 -3
- package/dist/lib/agent/core/ToolExecutionPipeline.d.ts +3 -1
- package/dist/lib/agent/core/ToolExecutionPipeline.js +8 -1
- package/dist/lib/agent/forge/DynamicComposer.d.ts +58 -0
- package/dist/lib/agent/forge/DynamicComposer.js +99 -0
- package/dist/lib/agent/forge/SandboxRunner.d.ts +60 -0
- package/dist/lib/agent/forge/SandboxRunner.js +251 -0
- package/dist/lib/agent/forge/TemporaryToolRegistry.d.ts +76 -0
- package/dist/lib/agent/forge/TemporaryToolRegistry.js +154 -0
- package/dist/lib/agent/forge/ToolForge.d.ts +92 -0
- package/dist/lib/agent/forge/ToolForge.js +239 -0
- package/dist/lib/agent/forge/ToolRequirementAnalyzer.d.ts +44 -0
- package/dist/lib/agent/forge/ToolRequirementAnalyzer.js +119 -0
- package/dist/lib/agent/tools/ToolRegistry.d.ts +2 -0
- package/dist/lib/agent/tools/ToolRegistry.js +4 -0
- package/dist/lib/agent/tools/composite.js +0 -1
- package/dist/lib/agent/tools/index.d.ts +2 -50
- package/dist/lib/agent/tools/index.js +2 -3
- package/dist/lib/agent/tools/lifecycle.d.ts +1 -58
- package/dist/lib/agent/tools/lifecycle.js +2 -75
- package/dist/lib/cli/KnowledgeSyncService.d.ts +26 -0
- package/dist/lib/cli/KnowledgeSyncService.js +33 -1
- package/dist/lib/cli/deploy/FileManifest.d.ts +0 -21
- package/dist/lib/cli/deploy/FileManifest.js +0 -11
- package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +10 -0
- package/dist/lib/domain/knowledge/KnowledgeEntry.js +2 -0
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +19 -2
- package/dist/lib/domain/knowledge/Lifecycle.js +32 -6
- package/dist/lib/domain/knowledge/UnifiedValidator.d.ts +1 -5
- package/dist/lib/domain/knowledge/UnifiedValidator.js +7 -44
- package/dist/lib/domain/knowledge/values/Stats.d.ts +29 -0
- package/dist/lib/domain/knowledge/values/Stats.js +41 -0
- package/dist/lib/external/mcp/McpServer.d.ts +19 -38
- package/dist/lib/external/mcp/McpServer.js +145 -117
- package/dist/lib/external/mcp/autoApproveInjector.js +0 -2
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.d.ts +26 -1
- package/dist/lib/external/mcp/handlers/bootstrap/MissionBriefingBuilder.js +41 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +3 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +27 -0
- package/dist/lib/external/mcp/handlers/bootstrap/skills.js +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -0
- package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
- package/dist/lib/external/mcp/handlers/browse.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/browse.js +2 -1
- package/dist/lib/external/mcp/handlers/consolidated.d.ts +117 -6
- package/dist/lib/external/mcp/handlers/consolidated.js +251 -71
- package/dist/lib/external/mcp/handlers/guard.d.ts +150 -0
- package/dist/lib/external/mcp/handlers/guard.js +239 -5
- package/dist/lib/external/mcp/handlers/knowledge.d.ts +0 -29
- package/dist/lib/external/mcp/handlers/knowledge.js +1 -76
- package/dist/lib/external/mcp/handlers/panorama.d.ts +36 -0
- package/dist/lib/external/mcp/handlers/panorama.js +156 -0
- package/dist/lib/external/mcp/handlers/system.d.ts +2 -54
- package/dist/lib/external/mcp/handlers/system.js +3 -113
- package/dist/lib/external/mcp/handlers/task.d.ts +13 -24
- package/dist/lib/external/mcp/handlers/task.js +218 -557
- package/dist/lib/external/mcp/handlers/types.d.ts +91 -8
- package/dist/lib/external/mcp/handlers/types.js +18 -1
- package/dist/lib/external/mcp/handlers/wiki-external.d.ts +18 -1
- package/dist/lib/external/mcp/handlers/wiki-external.js +16 -1
- package/dist/lib/external/mcp/tools.d.ts +18 -24
- package/dist/lib/external/mcp/tools.js +132 -159
- package/dist/lib/http/HttpServer.js +52 -0
- package/dist/lib/http/middleware/validate.js +7 -3
- package/dist/lib/http/routes/audit.d.ts +8 -0
- package/dist/lib/http/routes/audit.js +51 -0
- package/dist/lib/http/routes/guardReport.d.ts +10 -0
- package/dist/lib/http/routes/guardReport.js +143 -0
- package/dist/lib/http/routes/knowledge.js +32 -1
- package/dist/lib/http/routes/panorama.d.ts +11 -0
- package/dist/lib/http/routes/panorama.js +322 -0
- package/dist/lib/http/routes/signals.d.ts +10 -0
- package/dist/lib/http/routes/signals.js +104 -0
- package/dist/lib/http/routes/task.d.ts +2 -3
- package/dist/lib/http/routes/task.js +17 -347
- package/dist/lib/http/routes/violations.js +1 -1
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +6 -1
- package/dist/lib/infrastructure/audit/AuditLogger.js +14 -1
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +202 -504
- package/dist/lib/infrastructure/database/drizzle/schema.js +38 -69
- package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.d.ts +8 -0
- package/dist/lib/infrastructure/database/migrations/004_evolution_proposals.js +43 -0
- package/dist/lib/infrastructure/database/migrations/005_recipe_source_refs.d.ts +9 -0
- package/dist/lib/infrastructure/database/migrations/005_recipe_source_refs.js +24 -0
- package/dist/lib/infrastructure/logging/Logger.d.ts +2 -0
- package/dist/lib/infrastructure/logging/Logger.js +34 -7
- package/dist/lib/infrastructure/monitoring/ErrorTracker.js +3 -1
- package/dist/lib/infrastructure/monitoring/PerformanceMonitor.d.ts +2 -2
- package/dist/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -10
- package/dist/lib/infrastructure/notification/LarkNotifier.d.ts +24 -0
- package/dist/lib/infrastructure/notification/LarkNotifier.js +97 -0
- package/dist/lib/infrastructure/report/ReportStore.d.ts +45 -0
- package/dist/lib/infrastructure/report/ReportStore.js +133 -0
- package/dist/lib/infrastructure/signal/SignalAggregator.d.ts +18 -0
- package/dist/lib/infrastructure/signal/SignalAggregator.js +84 -0
- package/dist/lib/infrastructure/signal/SignalBridge.d.ts +13 -0
- package/dist/lib/infrastructure/signal/SignalBridge.js +20 -0
- package/dist/lib/infrastructure/signal/SignalBus.d.ts +63 -0
- package/dist/lib/infrastructure/signal/SignalBus.js +106 -0
- package/dist/lib/infrastructure/signal/SignalTraceWriter.d.ts +36 -0
- package/dist/lib/infrastructure/signal/SignalTraceWriter.js +130 -0
- package/dist/lib/infrastructure/vector/HnswVectorAdapter.js +18 -2
- package/dist/lib/injection/ServiceContainer.js +8 -0
- package/dist/lib/injection/ServiceMap.d.ts +16 -10
- package/dist/lib/injection/modules/AgentModule.d.ts +1 -1
- package/dist/lib/injection/modules/AgentModule.js +7 -1
- package/dist/lib/injection/modules/AppModule.d.ts +1 -1
- package/dist/lib/injection/modules/AppModule.js +4 -13
- package/dist/lib/injection/modules/GuardModule.js +27 -2
- package/dist/lib/injection/modules/InfraModule.d.ts +0 -1
- package/dist/lib/injection/modules/InfraModule.js +9 -7
- package/dist/lib/injection/modules/KnowledgeModule.d.ts +5 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +131 -0
- package/dist/lib/injection/modules/PanoramaModule.d.ts +18 -0
- package/dist/lib/injection/modules/PanoramaModule.js +76 -0
- package/dist/lib/injection/modules/SignalModule.d.ts +10 -0
- package/dist/lib/injection/modules/SignalModule.js +84 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +1 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +6 -0
- package/dist/lib/service/bootstrap/BootstrapTaskManager.d.ts +3 -1
- package/dist/lib/service/bootstrap/BootstrapTaskManager.js +20 -1
- package/dist/lib/service/bootstrap/UiStartupTasks.d.ts +45 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +101 -0
- package/dist/lib/service/delivery/AgentInstructionsGenerator.js +4 -5
- package/dist/lib/service/delivery/CursorDeliveryPipeline.d.ts +3 -1
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +13 -10
- package/dist/lib/service/delivery/RulesGenerator.js +3 -2
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +114 -0
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +542 -0
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +54 -0
- package/dist/lib/service/evolution/ContradictionDetector.js +253 -0
- package/dist/lib/service/evolution/DecayDetector.d.ts +71 -0
- package/dist/lib/service/evolution/DecayDetector.js +244 -0
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +38 -0
- package/dist/lib/service/evolution/EnhancementSuggester.js +220 -0
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +82 -0
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +167 -0
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +53 -0
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +210 -0
- package/dist/lib/service/evolution/StagingManager.d.ts +57 -0
- package/dist/lib/service/evolution/StagingManager.js +201 -0
- package/dist/lib/service/guard/ComplianceReporter.d.ts +42 -2
- package/dist/lib/service/guard/ComplianceReporter.js +43 -5
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +54 -0
- package/dist/lib/service/guard/CoverageAnalyzer.js +149 -0
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +42 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +465 -14
- package/dist/lib/service/guard/GuardFeedbackLoop.d.ts +3 -0
- package/dist/lib/service/guard/GuardFeedbackLoop.js +9 -0
- package/dist/lib/service/guard/ReverseGuard.d.ts +73 -0
- package/dist/lib/service/guard/ReverseGuard.js +256 -0
- package/dist/lib/service/guard/RuleLearner.d.ts +12 -0
- package/dist/lib/service/guard/RuleLearner.js +38 -0
- package/dist/lib/service/guard/UncertaintyCollector.d.ts +83 -0
- package/dist/lib/service/guard/UncertaintyCollector.js +149 -0
- package/dist/lib/service/guard/ViolationsStore.d.ts +1 -0
- package/dist/lib/service/guard/ViolationsStore.js +33 -3
- package/dist/lib/service/knowledge/ConfidenceRouter.d.ts +13 -0
- package/dist/lib/service/knowledge/ConfidenceRouter.js +14 -0
- package/dist/lib/service/knowledge/KnowledgeService.js +22 -4
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +68 -0
- package/dist/lib/service/knowledge/SourceRefReconciler.js +309 -0
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +27 -0
- package/dist/lib/service/panorama/CouplingAnalyzer.js +192 -0
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +28 -0
- package/dist/lib/service/panorama/DimensionAnalyzer.js +320 -0
- package/dist/lib/service/panorama/LayerInferrer.d.ts +19 -0
- package/dist/lib/service/panorama/LayerInferrer.js +182 -0
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +24 -0
- package/dist/lib/service/panorama/ModuleDiscoverer.js +185 -0
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +29 -0
- package/dist/lib/service/panorama/PanoramaAggregator.js +228 -0
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +52 -0
- package/dist/lib/service/panorama/PanoramaScanner.js +188 -0
- package/dist/lib/service/panorama/PanoramaService.d.ts +125 -0
- package/dist/lib/service/panorama/PanoramaService.js +363 -0
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +134 -0
- package/dist/lib/service/panorama/PanoramaTypes.js +6 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +48 -0
- package/dist/lib/service/panorama/RoleRefiner.js +535 -0
- package/dist/lib/service/search/BM25Scorer.d.ts +2 -2
- package/dist/lib/service/search/CoarseRanker.d.ts +7 -6
- package/dist/lib/service/search/CoarseRanker.js +11 -10
- package/dist/lib/service/search/FieldWeightedScorer.d.ts +81 -0
- package/dist/lib/service/search/FieldWeightedScorer.js +318 -0
- package/dist/lib/service/search/MultiSignalRanker.d.ts +3 -2
- package/dist/lib/service/search/MultiSignalRanker.js +17 -1
- package/dist/lib/service/search/SearchEngine.d.ts +9 -7
- package/dist/lib/service/search/SearchEngine.js +67 -10
- package/dist/lib/service/search/SearchTypes.d.ts +25 -3
- package/dist/lib/service/search/SearchTypes.js +6 -1
- package/dist/lib/service/signal/HitRecorder.d.ts +68 -0
- package/dist/lib/service/signal/HitRecorder.js +173 -0
- package/dist/lib/service/skills/SignalCollector.d.ts +3 -1
- package/dist/lib/service/skills/SignalCollector.js +31 -1
- package/dist/lib/service/task/IntentExtractor.d.ts +66 -0
- package/dist/lib/service/task/IntentExtractor.js +256 -0
- package/dist/lib/service/task/PrimeSearchPipeline.d.ts +54 -0
- package/dist/lib/service/task/PrimeSearchPipeline.js +113 -0
- package/dist/lib/service/vector/VectorService.d.ts +3 -0
- package/dist/lib/service/vector/VectorService.js +38 -4
- package/dist/lib/shared/schemas/mcp-tools.d.ts +41 -96
- package/dist/lib/shared/schemas/mcp-tools.js +59 -119
- package/dist/scripts/analyze-signals.d.ts +20 -0
- package/dist/scripts/analyze-signals.js +155 -0
- package/dist/scripts/diagnose-mcp.js +1 -1
- package/package.json +1 -1
- package/skills/autosnippet-create/SKILL.md +98 -89
- package/skills/autosnippet-devdocs/SKILL.md +55 -57
- package/templates/claude-code/hooks/autosnippet-session.sh +10 -15
- package/templates/cursor-hooks/hooks/session-start.sh +1 -1
- package/templates/guard-ci.yml +2 -2
- package/templates/instructions/agent-static.md +2 -1
- package/templates/instructions/conventions.md +5 -6
- package/templates/recipes-setup/README.md +1 -2
- package/templates/recipes-setup/_template.md +39 -39
- package/dashboard/dist/assets/icons-BofcEZ3f.js +0 -1
- package/dashboard/dist/assets/index-D0whuycy.css +0 -1
- package/dashboard/dist/assets/index-SiN1GChm.js +0 -128
- package/dist/lib/domain/task/Task.d.ts +0 -140
- package/dist/lib/domain/task/Task.js +0 -254
- package/dist/lib/domain/task/TaskDependency.d.ts +0 -23
- package/dist/lib/domain/task/TaskDependency.js +0 -34
- package/dist/lib/domain/task/TaskIdGenerator.d.ts +0 -40
- package/dist/lib/domain/task/TaskIdGenerator.js +0 -75
- package/dist/lib/domain/task/index.d.ts +0 -4
- package/dist/lib/domain/task/index.js +0 -4
- package/dist/lib/infrastructure/database/migrations/002_add_tasks.d.ts +0 -11
- package/dist/lib/infrastructure/database/migrations/002_add_tasks.js +0 -86
- package/dist/lib/repository/task/TaskRepository.impl.d.ts +0 -171
- package/dist/lib/repository/task/TaskRepository.impl.js +0 -347
- package/dist/lib/service/task/TaskGraphService.d.ts +0 -222
- package/dist/lib/service/task/TaskGraphService.js +0 -597
- package/dist/lib/service/task/TaskKnowledgeBridge.d.ts +0 -95
- package/dist/lib/service/task/TaskKnowledgeBridge.js +0 -298
- package/dist/lib/service/task/TaskReadyEngine.d.ts +0 -84
- package/dist/lib/service/task/TaskReadyEngine.js +0 -115
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Guard Report API 路由
|
|
3
|
+
*
|
|
4
|
+
* 端点:
|
|
5
|
+
* GET /api/v1/guard/report — 项目合规性报告(ComplianceReporter + Uncertainty)
|
|
6
|
+
* GET /api/v1/guard/report/reverse — ReverseGuard 反向验证
|
|
7
|
+
* GET /api/v1/guard/report/coverage — CoverageAnalyzer 覆盖率矩阵
|
|
8
|
+
*/
|
|
9
|
+
import express from 'express';
|
|
10
|
+
import { getServiceContainer } from '../../injection/ServiceContainer.js';
|
|
11
|
+
import { resolveProjectRoot } from '../../shared/resolveProjectRoot.js';
|
|
12
|
+
const router = express.Router();
|
|
13
|
+
/**
|
|
14
|
+
* GET /api/v1/guard/report
|
|
15
|
+
* 生成完整的合规性报告,含 uncertain/coverage/confidence
|
|
16
|
+
*
|
|
17
|
+
* Query params:
|
|
18
|
+
* minScore — 最低通过分数 (默认 60)
|
|
19
|
+
* maxErrors — 最大错误数 (默认 0)
|
|
20
|
+
* maxFiles — 扫描文件上限
|
|
21
|
+
*/
|
|
22
|
+
router.get('/', async (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
const container = getServiceContainer();
|
|
25
|
+
const complianceReporter = container.get('complianceReporter');
|
|
26
|
+
if (!complianceReporter) {
|
|
27
|
+
res.status(503).json({
|
|
28
|
+
success: false,
|
|
29
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'ComplianceReporter not available' },
|
|
30
|
+
});
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const projectRoot = resolveProjectRoot(container);
|
|
34
|
+
const qualityGate = {
|
|
35
|
+
minScore: req.query.minScore ? Number(req.query.minScore) : undefined,
|
|
36
|
+
maxErrors: req.query.maxErrors ? Number(req.query.maxErrors) : undefined,
|
|
37
|
+
};
|
|
38
|
+
const maxFiles = req.query.maxFiles ? Number(req.query.maxFiles) : undefined;
|
|
39
|
+
const report = await complianceReporter.generate(projectRoot, {
|
|
40
|
+
qualityGate,
|
|
41
|
+
maxFiles,
|
|
42
|
+
});
|
|
43
|
+
res.json({ success: true, data: report });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
res.status(500).json({
|
|
47
|
+
success: false,
|
|
48
|
+
error: { code: 'GUARD_REPORT_ERROR', message: err.message },
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* GET /api/v1/guard/report/reverse
|
|
54
|
+
* ReverseGuard — Recipe→Code 反向验证
|
|
55
|
+
*
|
|
56
|
+
* Query params:
|
|
57
|
+
* maxFiles — 扫描文件上限 (默认 200)
|
|
58
|
+
*/
|
|
59
|
+
router.get('/reverse', async (req, res) => {
|
|
60
|
+
try {
|
|
61
|
+
const container = getServiceContainer();
|
|
62
|
+
const projectRoot = resolveProjectRoot(container);
|
|
63
|
+
const { ReverseGuard } = await import('../../service/guard/ReverseGuard.js');
|
|
64
|
+
const { collectSourceFilesWithContent } = await import('../../service/guard/SourceFileCollector.js');
|
|
65
|
+
let reverseGuard;
|
|
66
|
+
try {
|
|
67
|
+
reverseGuard = container.get('reverseGuard');
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
const db = container.get('database');
|
|
71
|
+
reverseGuard = new ReverseGuard(db.getDb());
|
|
72
|
+
}
|
|
73
|
+
const maxFiles = req.query.maxFiles ? Number(req.query.maxFiles) : 200;
|
|
74
|
+
const projectFiles = await collectSourceFilesWithContent(projectRoot, { maxFiles });
|
|
75
|
+
const results = reverseGuard.auditAllRules(projectFiles);
|
|
76
|
+
const drifts = reverseGuard.getDriftResults(results);
|
|
77
|
+
res.json({
|
|
78
|
+
success: true,
|
|
79
|
+
data: {
|
|
80
|
+
totalRecipes: results.length,
|
|
81
|
+
healthy: results.filter((r) => r.recommendation === 'healthy').length,
|
|
82
|
+
investigate: results.filter((r) => r.recommendation === 'investigate').length,
|
|
83
|
+
decay: results.filter((r) => r.recommendation === 'decay').length,
|
|
84
|
+
drifts,
|
|
85
|
+
allResults: results.map((r) => ({
|
|
86
|
+
recipeId: r.recipeId,
|
|
87
|
+
title: r.title,
|
|
88
|
+
recommendation: r.recommendation,
|
|
89
|
+
signalCount: r.signals.length,
|
|
90
|
+
})),
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
res.status(500).json({
|
|
96
|
+
success: false,
|
|
97
|
+
error: { code: 'REVERSE_GUARD_ERROR', message: err.message },
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
/**
|
|
102
|
+
* GET /api/v1/guard/report/coverage
|
|
103
|
+
* CoverageAnalyzer — 模块覆盖率矩阵
|
|
104
|
+
*/
|
|
105
|
+
router.get('/coverage', async (_req, res) => {
|
|
106
|
+
try {
|
|
107
|
+
const container = getServiceContainer();
|
|
108
|
+
const { CoverageAnalyzer } = await import('../../service/guard/CoverageAnalyzer.js');
|
|
109
|
+
let analyzer;
|
|
110
|
+
try {
|
|
111
|
+
analyzer = container.get('coverageAnalyzer');
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
const db = container.get('database');
|
|
115
|
+
analyzer = new CoverageAnalyzer(db.getDb());
|
|
116
|
+
}
|
|
117
|
+
// 从 Panorama 或目录结构获取模块文件
|
|
118
|
+
const moduleFiles = new Map();
|
|
119
|
+
try {
|
|
120
|
+
const panorama = container.get('panoramaService');
|
|
121
|
+
const overview = panorama.getOverview();
|
|
122
|
+
if (overview?.modules) {
|
|
123
|
+
for (const mod of overview.modules) {
|
|
124
|
+
if (mod.files?.length > 0) {
|
|
125
|
+
moduleFiles.set(mod.name, mod.files);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
/* PanoramaService not available */
|
|
132
|
+
}
|
|
133
|
+
const matrix = analyzer.analyze(moduleFiles);
|
|
134
|
+
res.json({ success: true, data: matrix });
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
res.status(500).json({
|
|
138
|
+
success: false,
|
|
139
|
+
error: { code: 'COVERAGE_ANALYZER_ERROR', message: err.message },
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
export default router;
|
|
@@ -109,6 +109,37 @@ router.get('/stats', async (req, res) => {
|
|
|
109
109
|
const stats = await knowledgeService.getStats();
|
|
110
110
|
res.json({ success: true, data: stats });
|
|
111
111
|
});
|
|
112
|
+
/**
|
|
113
|
+
* GET /api/v1/knowledge/lifecycle
|
|
114
|
+
* 获取六态生命周期统计 + 各状态条目列表
|
|
115
|
+
*/
|
|
116
|
+
router.get('/lifecycle', async (req, res) => {
|
|
117
|
+
const container = getServiceContainer();
|
|
118
|
+
const knowledgeService = container.get('knowledgeService');
|
|
119
|
+
const stats = await knowledgeService.getStats();
|
|
120
|
+
const states = ['pending', 'staging', 'active', 'evolving', 'decaying', 'deprecated'];
|
|
121
|
+
const lifecycle = {
|
|
122
|
+
counts: {},
|
|
123
|
+
entries: {},
|
|
124
|
+
};
|
|
125
|
+
const counts = lifecycle.counts;
|
|
126
|
+
for (const state of states) {
|
|
127
|
+
counts[state] = stats?.[state] ?? 0;
|
|
128
|
+
}
|
|
129
|
+
// 仅对过渡态(staging / evolving / decaying)返回条目详情
|
|
130
|
+
const transitionalStates = ['staging', 'evolving', 'decaying'];
|
|
131
|
+
const entries = lifecycle.entries;
|
|
132
|
+
for (const state of transitionalStates) {
|
|
133
|
+
if (counts[state] > 0) {
|
|
134
|
+
const result = await knowledgeService.list({ lifecycle: state }, { page: 1, pageSize: 20 });
|
|
135
|
+
entries[state] = result.items ?? [];
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
entries[state] = [];
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
res.json({ success: true, data: lifecycle });
|
|
142
|
+
});
|
|
112
143
|
/**
|
|
113
144
|
* GET /api/v1/knowledge/:id
|
|
114
145
|
* 获取知识条目详情
|
|
@@ -160,7 +191,7 @@ router.delete('/:id', requirePermission('knowledge', 'delete'), async (req, res)
|
|
|
160
191
|
const result = await knowledgeService.delete(id, context);
|
|
161
192
|
res.json({ success: true, data: result });
|
|
162
193
|
});
|
|
163
|
-
/* ═══ 生命周期操作(
|
|
194
|
+
/* ═══ 生命周期操作(6 态: pending / staging / active / evolving / decaying / deprecated)═══ */
|
|
164
195
|
/**
|
|
165
196
|
* PATCH /api/v1/knowledge/:id/publish
|
|
166
197
|
* 发布 (pending → active) — 仅开发者
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panorama API 路由
|
|
3
|
+
*
|
|
4
|
+
* 端点:
|
|
5
|
+
* GET /api/v1/panorama — 项目全景概览
|
|
6
|
+
* GET /api/v1/panorama/health — 全景健康度
|
|
7
|
+
* GET /api/v1/panorama/gaps — 知识空白区
|
|
8
|
+
* GET /api/v1/panorama/module/:name — 单模块详情
|
|
9
|
+
*/
|
|
10
|
+
declare const router: import("express-serve-static-core").Router;
|
|
11
|
+
export default router;
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Panorama API 路由
|
|
3
|
+
*
|
|
4
|
+
* 端点:
|
|
5
|
+
* GET /api/v1/panorama — 项目全景概览
|
|
6
|
+
* GET /api/v1/panorama/health — 全景健康度
|
|
7
|
+
* GET /api/v1/panorama/gaps — 知识空白区
|
|
8
|
+
* GET /api/v1/panorama/module/:name — 单模块详情
|
|
9
|
+
*/
|
|
10
|
+
import express from 'express';
|
|
11
|
+
import { getServiceContainer } from '../../injection/ServiceContainer.js';
|
|
12
|
+
const router = express.Router();
|
|
13
|
+
/**
|
|
14
|
+
* GET /api/v1/panorama
|
|
15
|
+
* 返回项目全景概览(层级、模块、覆盖率)
|
|
16
|
+
*/
|
|
17
|
+
router.get('/', async (_req, res) => {
|
|
18
|
+
try {
|
|
19
|
+
const container = getServiceContainer();
|
|
20
|
+
const panoramaService = container.get('panoramaService');
|
|
21
|
+
if (!panoramaService) {
|
|
22
|
+
res.status(503).json({
|
|
23
|
+
success: false,
|
|
24
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'PanoramaService not available' },
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (typeof panoramaService.ensureData === 'function') {
|
|
29
|
+
await panoramaService.ensureData();
|
|
30
|
+
}
|
|
31
|
+
const overview = panoramaService.getOverview();
|
|
32
|
+
res.json({ success: true, data: overview });
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
res.status(500).json({
|
|
36
|
+
success: false,
|
|
37
|
+
error: { code: 'PANORAMA_ERROR', message: err.message },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
/**
|
|
42
|
+
* GET /api/v1/panorama/health
|
|
43
|
+
* 返回全景健康度评分
|
|
44
|
+
*/
|
|
45
|
+
router.get('/health', async (_req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const container = getServiceContainer();
|
|
48
|
+
const panoramaService = container.get('panoramaService');
|
|
49
|
+
if (!panoramaService) {
|
|
50
|
+
res.status(503).json({
|
|
51
|
+
success: false,
|
|
52
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'PanoramaService not available' },
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (typeof panoramaService.ensureData === 'function') {
|
|
57
|
+
await panoramaService.ensureData();
|
|
58
|
+
}
|
|
59
|
+
const health = panoramaService.getHealth();
|
|
60
|
+
res.json({ success: true, data: health });
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
res.status(500).json({
|
|
64
|
+
success: false,
|
|
65
|
+
error: { code: 'PANORAMA_ERROR', message: err.message },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* GET /api/v1/panorama/gaps
|
|
71
|
+
* 返回知识空白区列表
|
|
72
|
+
*/
|
|
73
|
+
router.get('/gaps', async (_req, res) => {
|
|
74
|
+
try {
|
|
75
|
+
const container = getServiceContainer();
|
|
76
|
+
const panoramaService = container.get('panoramaService');
|
|
77
|
+
if (!panoramaService) {
|
|
78
|
+
res.status(503).json({
|
|
79
|
+
success: false,
|
|
80
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'PanoramaService not available' },
|
|
81
|
+
});
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (typeof panoramaService.ensureData === 'function') {
|
|
85
|
+
await panoramaService.ensureData();
|
|
86
|
+
}
|
|
87
|
+
const gaps = panoramaService.getGaps();
|
|
88
|
+
res.json({ success: true, data: gaps });
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
res.status(500).json({
|
|
92
|
+
success: false,
|
|
93
|
+
error: { code: 'PANORAMA_ERROR', message: err.message },
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
/**
|
|
98
|
+
* GET /api/v1/panorama/coverage
|
|
99
|
+
* 返回各模块知识覆盖率热力图数据
|
|
100
|
+
*/
|
|
101
|
+
router.get('/coverage', async (_req, res) => {
|
|
102
|
+
try {
|
|
103
|
+
const container = getServiceContainer();
|
|
104
|
+
const panoramaService = container.get('panoramaService');
|
|
105
|
+
if (!panoramaService) {
|
|
106
|
+
res.status(503).json({
|
|
107
|
+
success: false,
|
|
108
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'PanoramaService not available' },
|
|
109
|
+
});
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (typeof panoramaService.ensureData === 'function') {
|
|
113
|
+
await panoramaService.ensureData();
|
|
114
|
+
}
|
|
115
|
+
const overview = panoramaService.getOverview();
|
|
116
|
+
const gaps = panoramaService.getGaps?.() ?? [];
|
|
117
|
+
// 构建模块级覆盖率数据:从 overview.layers 中提取每个模块的文件数和 recipe 数
|
|
118
|
+
const modules = [];
|
|
119
|
+
for (const layer of overview.layers || []) {
|
|
120
|
+
const layerModules = layer.modules || [];
|
|
121
|
+
for (const mod of layerModules) {
|
|
122
|
+
const fileCount = mod.fileCount || 0;
|
|
123
|
+
const recipeCount = mod.recipeCount || 0;
|
|
124
|
+
const coverage = fileCount > 0 ? Math.round((recipeCount / fileCount) * 100) : 0;
|
|
125
|
+
modules.push({
|
|
126
|
+
name: mod.name || 'unknown',
|
|
127
|
+
layer: layer.name,
|
|
128
|
+
fileCount,
|
|
129
|
+
recipeCount,
|
|
130
|
+
coverage: Math.min(coverage, 100),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// 按覆盖率升序(低覆盖在前,方便高亮)
|
|
135
|
+
modules.sort((a, b) => a.coverage - b.coverage);
|
|
136
|
+
// 空白区按维度聚合
|
|
137
|
+
const gapsByDimension = {};
|
|
138
|
+
for (const gap of gaps) {
|
|
139
|
+
const dim = gap.dimensionName || 'unknown';
|
|
140
|
+
gapsByDimension[dim] = (gapsByDimension[dim] || 0) + 1;
|
|
141
|
+
}
|
|
142
|
+
res.json({
|
|
143
|
+
success: true,
|
|
144
|
+
data: {
|
|
145
|
+
modules,
|
|
146
|
+
gapsByDimension,
|
|
147
|
+
overallCoverage: overview.overallCoverage ?? 0,
|
|
148
|
+
totalFiles: overview.totalFiles ?? 0,
|
|
149
|
+
totalRecipes: overview.totalRecipes ?? 0,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
res.status(500).json({
|
|
155
|
+
success: false,
|
|
156
|
+
error: { code: 'PANORAMA_ERROR', message: err.message },
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
/**
|
|
161
|
+
* GET /api/v1/panorama/module/:name
|
|
162
|
+
* 返回单模块详情
|
|
163
|
+
*/
|
|
164
|
+
router.get('/module/:name', async (req, res) => {
|
|
165
|
+
try {
|
|
166
|
+
const container = getServiceContainer();
|
|
167
|
+
const panoramaService = container.get('panoramaService');
|
|
168
|
+
if (!panoramaService) {
|
|
169
|
+
res.status(503).json({
|
|
170
|
+
success: false,
|
|
171
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'PanoramaService not available' },
|
|
172
|
+
});
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (typeof panoramaService.ensureData === 'function') {
|
|
176
|
+
await panoramaService.ensureData();
|
|
177
|
+
}
|
|
178
|
+
const detail = panoramaService.getModule(req.params.name);
|
|
179
|
+
if (!detail) {
|
|
180
|
+
res.status(404).json({
|
|
181
|
+
success: false,
|
|
182
|
+
error: { code: 'MODULE_NOT_FOUND', message: `Module "${req.params.name}" not found` },
|
|
183
|
+
});
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
res.json({ success: true, data: detail });
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
res.status(500).json({
|
|
190
|
+
success: false,
|
|
191
|
+
error: { code: 'PANORAMA_ERROR', message: err.message },
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
/* ═══ 治理 (Governance) ═══════════════════════════════════════ */
|
|
196
|
+
/**
|
|
197
|
+
* POST /api/v1/panorama/governance/cycle
|
|
198
|
+
* 执行完整治理周期(矛盾检测 + 冗余分析 + 衰退扫描)
|
|
199
|
+
*/
|
|
200
|
+
router.post('/governance/cycle', async (_req, res) => {
|
|
201
|
+
try {
|
|
202
|
+
const container = getServiceContainer();
|
|
203
|
+
const metabolism = container.get('knowledgeMetabolism');
|
|
204
|
+
if (!metabolism) {
|
|
205
|
+
res.status(503).json({
|
|
206
|
+
success: false,
|
|
207
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'KnowledgeMetabolism not available' },
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const report = metabolism.runFullCycle();
|
|
212
|
+
res.json({ success: true, data: report });
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
res.status(500).json({
|
|
216
|
+
success: false,
|
|
217
|
+
error: { code: 'GOVERNANCE_ERROR', message: err.message },
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
/**
|
|
222
|
+
* GET /api/v1/panorama/governance/decay
|
|
223
|
+
* 获取衰退评估报告
|
|
224
|
+
*/
|
|
225
|
+
router.get('/governance/decay', async (_req, res) => {
|
|
226
|
+
try {
|
|
227
|
+
const container = getServiceContainer();
|
|
228
|
+
const decayDetector = container.get('decayDetector');
|
|
229
|
+
if (!decayDetector) {
|
|
230
|
+
res.status(503).json({
|
|
231
|
+
success: false,
|
|
232
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'DecayDetector not available' },
|
|
233
|
+
});
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const results = decayDetector.scanAll();
|
|
237
|
+
res.json({ success: true, data: { results } });
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
res.status(500).json({
|
|
241
|
+
success: false,
|
|
242
|
+
error: { code: 'GOVERNANCE_ERROR', message: err.message },
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
/**
|
|
247
|
+
* POST /api/v1/panorama/governance/staging-check
|
|
248
|
+
* 检查 staging 条目并自动发布到期的
|
|
249
|
+
*/
|
|
250
|
+
router.post('/governance/staging-check', async (_req, res) => {
|
|
251
|
+
try {
|
|
252
|
+
const container = getServiceContainer();
|
|
253
|
+
const stagingManager = container.get('stagingManager');
|
|
254
|
+
if (!stagingManager) {
|
|
255
|
+
res.status(503).json({
|
|
256
|
+
success: false,
|
|
257
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'StagingManager not available' },
|
|
258
|
+
});
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const checkResult = stagingManager.checkAndPromote();
|
|
262
|
+
const currentStaging = stagingManager.listStaging();
|
|
263
|
+
res.json({ success: true, data: { checkResult, currentStaging } });
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
res.status(500).json({
|
|
267
|
+
success: false,
|
|
268
|
+
error: { code: 'GOVERNANCE_ERROR', message: err.message },
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
/**
|
|
273
|
+
* GET /api/v1/panorama/governance/staging
|
|
274
|
+
* 获取当前 staging 列表(只读)
|
|
275
|
+
*/
|
|
276
|
+
router.get('/governance/staging', async (_req, res) => {
|
|
277
|
+
try {
|
|
278
|
+
const container = getServiceContainer();
|
|
279
|
+
const stagingManager = container.get('stagingManager');
|
|
280
|
+
if (!stagingManager) {
|
|
281
|
+
res.status(503).json({
|
|
282
|
+
success: false,
|
|
283
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'StagingManager not available' },
|
|
284
|
+
});
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
const entries = stagingManager.listStaging();
|
|
288
|
+
res.json({ success: true, data: { entries } });
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
res.status(500).json({
|
|
292
|
+
success: false,
|
|
293
|
+
error: { code: 'GOVERNANCE_ERROR', message: err.message },
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
/**
|
|
298
|
+
* GET /api/v1/panorama/governance/enhancements
|
|
299
|
+
* 获取增强建议
|
|
300
|
+
*/
|
|
301
|
+
router.get('/governance/enhancements', async (_req, res) => {
|
|
302
|
+
try {
|
|
303
|
+
const container = getServiceContainer();
|
|
304
|
+
const suggester = container.get('enhancementSuggester');
|
|
305
|
+
if (!suggester) {
|
|
306
|
+
res.status(503).json({
|
|
307
|
+
success: false,
|
|
308
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'EnhancementSuggester not available' },
|
|
309
|
+
});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const suggestions = suggester.analyzeAll();
|
|
313
|
+
res.json({ success: true, data: { suggestions } });
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
res.status(500).json({
|
|
317
|
+
success: false,
|
|
318
|
+
error: { code: 'GOVERNANCE_ERROR', message: err.message },
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
export default router;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signal & Report API 路由
|
|
3
|
+
*
|
|
4
|
+
* 端点:
|
|
5
|
+
* GET /api/v1/signals/trace — 查询信号留痕
|
|
6
|
+
* GET /api/v1/signals/stats — 信号统计
|
|
7
|
+
* GET /api/v1/signals/reports — 查询管道报告
|
|
8
|
+
*/
|
|
9
|
+
import express from 'express';
|
|
10
|
+
import { getServiceContainer } from '../../injection/ServiceContainer.js';
|
|
11
|
+
const router = express.Router();
|
|
12
|
+
/**
|
|
13
|
+
* GET /api/v1/signals/trace
|
|
14
|
+
* 查询信号留痕(支持 type / source / target / from / to / limit / offset)
|
|
15
|
+
*/
|
|
16
|
+
router.get('/trace', async (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const container = getServiceContainer();
|
|
19
|
+
const traceWriter = container.get('signalTraceWriter');
|
|
20
|
+
if (!traceWriter) {
|
|
21
|
+
res.status(503).json({
|
|
22
|
+
success: false,
|
|
23
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'SignalTraceWriter not available' },
|
|
24
|
+
});
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const typeParam = req.query.type;
|
|
28
|
+
const type = typeof typeParam === 'string' ? typeParam.split(',').filter(Boolean) : undefined;
|
|
29
|
+
const source = typeof req.query.source === 'string' ? req.query.source : undefined;
|
|
30
|
+
const target = typeof req.query.target === 'string' ? req.query.target : undefined;
|
|
31
|
+
const from = req.query.from ? Number(req.query.from) : undefined;
|
|
32
|
+
const to = req.query.to ? Number(req.query.to) : undefined;
|
|
33
|
+
const limit = req.query.limit ? Math.min(Number(req.query.limit), 200) : undefined;
|
|
34
|
+
const offset = req.query.offset ? Number(req.query.offset) : undefined;
|
|
35
|
+
const result = await traceWriter.query({ type, source, target, from, to, limit, offset });
|
|
36
|
+
res.json({ success: true, data: result });
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
res.status(500).json({
|
|
40
|
+
success: false,
|
|
41
|
+
error: { code: 'INTERNAL_ERROR', message: err instanceof Error ? err.message : String(err) },
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* GET /api/v1/signals/stats
|
|
47
|
+
* 信号统计(可选 from / to 时间范围)
|
|
48
|
+
*/
|
|
49
|
+
router.get('/stats', async (req, res) => {
|
|
50
|
+
try {
|
|
51
|
+
const container = getServiceContainer();
|
|
52
|
+
const traceWriter = container.get('signalTraceWriter');
|
|
53
|
+
if (!traceWriter) {
|
|
54
|
+
res.status(503).json({
|
|
55
|
+
success: false,
|
|
56
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'SignalTraceWriter not available' },
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const from = req.query.from ? Number(req.query.from) : undefined;
|
|
61
|
+
const to = req.query.to ? Number(req.query.to) : undefined;
|
|
62
|
+
const stats = await traceWriter.stats({ from, to });
|
|
63
|
+
res.json({ success: true, data: stats });
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
res.status(500).json({
|
|
67
|
+
success: false,
|
|
68
|
+
error: { code: 'INTERNAL_ERROR', message: err instanceof Error ? err.message : String(err) },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
/**
|
|
73
|
+
* GET /api/v1/signals/reports
|
|
74
|
+
* 查询管道报告(支持 category / type / from / to / limit / offset)
|
|
75
|
+
*/
|
|
76
|
+
router.get('/reports', async (req, res) => {
|
|
77
|
+
try {
|
|
78
|
+
const container = getServiceContainer();
|
|
79
|
+
const reportStore = container.get('reportStore');
|
|
80
|
+
if (!reportStore) {
|
|
81
|
+
res.status(503).json({
|
|
82
|
+
success: false,
|
|
83
|
+
error: { code: 'SERVICE_UNAVAILABLE', message: 'ReportStore not available' },
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const catParam = req.query.category;
|
|
88
|
+
const category = typeof catParam === 'string' ? catParam.split(',').filter(Boolean) : undefined;
|
|
89
|
+
const type = typeof req.query.type === 'string' ? req.query.type : undefined;
|
|
90
|
+
const from = req.query.from ? Number(req.query.from) : undefined;
|
|
91
|
+
const to = req.query.to ? Number(req.query.to) : undefined;
|
|
92
|
+
const limit = req.query.limit ? Math.min(Number(req.query.limit), 200) : undefined;
|
|
93
|
+
const offset = req.query.offset ? Number(req.query.offset) : undefined;
|
|
94
|
+
const result = await reportStore.query({ category, type, from, to, limit, offset });
|
|
95
|
+
res.json({ success: true, data: result });
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
res.status(500).json({
|
|
99
|
+
success: false,
|
|
100
|
+
error: { code: 'INTERNAL_ERROR', message: err instanceof Error ? err.message : String(err) },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
export default router;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Task HTTP API 路由 (v3.3 — Intent Lifecycle)
|
|
3
3
|
*
|
|
4
4
|
* 为 VS Code Extension `taskTool.ts` 提供 HTTP 转发端点。
|
|
5
|
-
*
|
|
6
|
-
* 将业务逻辑转发到此端点,由 TaskGraphService 执行。
|
|
5
|
+
* 5 operations: prime, create, close, fail, record_decision
|
|
7
6
|
*
|
|
8
7
|
* 端点:
|
|
9
8
|
* POST /api/v1/task — 统一入口(operation 路由)
|