autosnippet 3.2.21 → 3.3.2
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 -1
- package/dist/bin/cli.js +244 -261
- 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/SetupService.d.ts +46 -2
- package/dist/lib/cli/SetupService.js +2 -27
- package/dist/lib/cli/deploy/FileManifest.d.ts +0 -21
- package/dist/lib/cli/deploy/FileManifest.js +0 -11
- package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.d.ts +2 -5
- package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.js +159 -44
- package/dist/lib/core/discovery/index.d.ts +1 -1
- package/dist/lib/core/discovery/index.js +2 -2
- 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/consolidated.d.ts +116 -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 +245 -8
- 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 +217 -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 +14 -20
- package/dist/lib/external/mcp/tools.js +62 -91
- package/dist/lib/http/HttpServer.js +52 -6
- package/dist/lib/http/routes/{snippets.d.ts → audit.d.ts} +4 -2
- package/dist/lib/http/routes/audit.js +51 -0
- package/dist/lib/http/routes/commands.d.ts +1 -1
- package/dist/lib/http/routes/commands.js +1 -66
- 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/remote.js +0 -5
- 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 +181 -583
- package/dist/lib/infrastructure/database/drizzle/schema.js +28 -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/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/injection/ServiceContainer.js +6 -0
- package/dist/lib/injection/ServiceMap.d.ts +16 -19
- 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 +3 -4
- package/dist/lib/injection/modules/AppModule.js +7 -43
- package/dist/lib/injection/modules/GuardModule.js +59 -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.js +51 -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/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 +55 -1
- package/dist/lib/service/guard/GuardCheckEngine.js +508 -15
- 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/module/ModuleService.js +3 -13
- 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 +108 -0
- package/dist/lib/service/panorama/PanoramaService.js +220 -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/MultiSignalRanker.d.ts +1 -0
- package/dist/lib/service/search/MultiSignalRanker.js +16 -0
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +9 -1
- package/dist/lib/service/search/SearchTypes.d.ts +2 -0
- 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 +58 -0
- package/dist/lib/service/task/IntentExtractor.js +142 -0
- package/dist/lib/service/task/PrimeSearchPipeline.d.ts +54 -0
- package/dist/lib/service/task/PrimeSearchPipeline.js +98 -0
- package/dist/lib/shared/constants.d.ts +0 -15
- package/dist/lib/shared/constants.js +0 -10
- package/dist/lib/shared/schemas/config.d.ts +4 -1
- package/dist/lib/shared/schemas/config.js +8 -1
- 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/dist/scripts/release.js +2 -10
- package/package.json +4 -19
- package/skills/autosnippet-devdocs/SKILL.md +11 -8
- package/templates/claude-code/hooks/autosnippet-session.sh +10 -15
- package/templates/cursor-hooks/hooks/session-start.sh +1 -1
- package/templates/instructions/agent-static.md +2 -1
- package/templates/instructions/conventions.md +5 -6
- package/templates/recipes-setup/README.md +1 -2
- package/dashboard/dist/assets/icons-C1dUryS-.js +0 -1
- package/dashboard/dist/assets/index-D0whuycy.css +0 -1
- package/dashboard/dist/assets/index-DdvZE4Yd.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/http/routes/snippets.js +0 -49
- 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/platform/ClipboardManager.d.ts +0 -24
- package/dist/lib/platform/ClipboardManager.js +0 -142
- package/dist/lib/platform/NativeUi.d.ts +0 -53
- package/dist/lib/platform/NativeUi.js +0 -284
- package/dist/lib/platform/ios/index.d.ts +0 -38
- package/dist/lib/platform/ios/index.js +0 -42
- package/dist/lib/platform/ios/routes/spm.d.ts +0 -9
- package/dist/lib/platform/ios/routes/spm.js +0 -371
- package/dist/lib/platform/ios/snippet/PlaceholderConverter.d.ts +0 -21
- package/dist/lib/platform/ios/snippet/PlaceholderConverter.js +0 -48
- package/dist/lib/platform/ios/snippet/XcodeCodec.d.ts +0 -23
- package/dist/lib/platform/ios/snippet/XcodeCodec.js +0 -96
- package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +0 -56
- package/dist/lib/platform/ios/spm/DependencyGraph.js +0 -195
- package/dist/lib/platform/ios/spm/PackageSwiftParser.d.ts +0 -69
- package/dist/lib/platform/ios/spm/PackageSwiftParser.js +0 -231
- package/dist/lib/platform/ios/spm/PathFinder.d.ts +0 -28
- package/dist/lib/platform/ios/spm/PathFinder.js +0 -117
- package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +0 -44
- package/dist/lib/platform/ios/spm/PolicyEngine.js +0 -79
- package/dist/lib/platform/ios/spm/SpmHelper.d.ts +0 -102
- package/dist/lib/platform/ios/spm/SpmHelper.js +0 -464
- package/dist/lib/platform/ios/xcode/HeaderResolver.d.ts +0 -33
- package/dist/lib/platform/ios/xcode/HeaderResolver.js +0 -90
- package/dist/lib/platform/ios/xcode/SaveEventFilter.d.ts +0 -66
- package/dist/lib/platform/ios/xcode/SaveEventFilter.js +0 -142
- package/dist/lib/platform/ios/xcode/XcodeAutomation.d.ts +0 -71
- package/dist/lib/platform/ios/xcode/XcodeAutomation.js +0 -327
- package/dist/lib/platform/ios/xcode/XcodeImportResolver.d.ts +0 -130
- package/dist/lib/platform/ios/xcode/XcodeImportResolver.js +0 -404
- package/dist/lib/platform/ios/xcode/XcodeIntegration.d.ts +0 -89
- package/dist/lib/platform/ios/xcode/XcodeIntegration.js +0 -588
- package/dist/lib/platform/ios/xcode/XcodeWriteUtils.d.ts +0 -99
- package/dist/lib/platform/ios/xcode/XcodeWriteUtils.js +0 -190
- 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/automation/ActionPipeline.d.ts +0 -34
- package/dist/lib/service/automation/ActionPipeline.js +0 -53
- package/dist/lib/service/automation/AutomationOrchestrator.d.ts +0 -86
- package/dist/lib/service/automation/AutomationOrchestrator.js +0 -57
- package/dist/lib/service/automation/ContextCollector.d.ts +0 -24
- package/dist/lib/service/automation/ContextCollector.js +0 -35
- package/dist/lib/service/automation/DirectiveDetector.d.ts +0 -51
- package/dist/lib/service/automation/DirectiveDetector.js +0 -112
- package/dist/lib/service/automation/FileWatcher.d.ts +0 -51
- package/dist/lib/service/automation/FileWatcher.js +0 -366
- package/dist/lib/service/automation/TriggerResolver.d.ts +0 -36
- package/dist/lib/service/automation/TriggerResolver.js +0 -62
- package/dist/lib/service/automation/handlers/AlinkHandler.d.ts +0 -7
- package/dist/lib/service/automation/handlers/AlinkHandler.js +0 -80
- package/dist/lib/service/automation/handlers/CreateHandler.d.ts +0 -11
- package/dist/lib/service/automation/handlers/CreateHandler.js +0 -170
- package/dist/lib/service/automation/handlers/GuardHandler.d.ts +0 -17
- package/dist/lib/service/automation/handlers/GuardHandler.js +0 -218
- package/dist/lib/service/automation/handlers/HeaderHandler.d.ts +0 -2
- package/dist/lib/service/automation/handlers/HeaderHandler.js +0 -32
- package/dist/lib/service/automation/handlers/SearchHandler.d.ts +0 -11
- package/dist/lib/service/automation/handlers/SearchHandler.js +0 -278
- package/dist/lib/service/snippet/SnippetFactory.d.ts +0 -101
- package/dist/lib/service/snippet/SnippetFactory.js +0 -145
- package/dist/lib/service/snippet/SnippetInstaller.d.ts +0 -91
- package/dist/lib/service/snippet/SnippetInstaller.js +0 -276
- package/dist/lib/service/snippet/codecs/SnippetCodec.d.ts +0 -44
- package/dist/lib/service/snippet/codecs/SnippetCodec.js +0 -35
- package/dist/lib/service/snippet/codecs/VSCodeCodec.d.ts +0 -27
- package/dist/lib/service/snippet/codecs/VSCodeCodec.js +0 -82
- 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
- package/dist/scripts/build-native-ui.d.ts +0 -3
- package/dist/scripts/build-native-ui.js +0 -62
- package/dist/scripts/init-snippets.d.ts +0 -30
- package/dist/scripts/init-snippets.js +0 -298
- package/dist/scripts/install-full.d.ts +0 -7
- package/dist/scripts/install-full.js +0 -38
- package/resources/native-ui/README.md +0 -29
- package/resources/native-ui/combined-window.swift +0 -494
- package/resources/native-ui/main.swift +0 -598
- package/scripts/postinstall-safe.mjs +0 -89
|
@@ -715,16 +715,12 @@ async function replyLark(messageId, text) {
|
|
|
715
715
|
/**
|
|
716
716
|
* 截取 IDE 窗口截图(通过 ScreenCaptureKit 原生 API,息屏时可用)
|
|
717
717
|
* @param [opts.windowTitle] 窗口标题关键词(默认 "Code")
|
|
718
|
-
* @returns >}
|
|
719
718
|
*/
|
|
720
719
|
async function captureIDEScreenshot(opts = {}) {
|
|
721
720
|
try {
|
|
722
721
|
const { screenshot } = await import('../../platform/ScreenCaptureService.js');
|
|
723
|
-
// 统一使用窗口截取(desktopIndependentWindow,亮屏/息屏均可用)
|
|
724
|
-
// 优先截取 IDE 窗口
|
|
725
722
|
const windowTitle = opts.windowTitle || 'Code';
|
|
726
723
|
let result = await screenshot({ windowTitle, format: 'png' });
|
|
727
|
-
// IDE 窗口未找到 → 尝试常见 IDE 名称
|
|
728
724
|
if (!result.success) {
|
|
729
725
|
for (const alt of ['Visual Studio', 'Cursor', 'Xcode', 'IntelliJ', 'WebStorm']) {
|
|
730
726
|
if (alt.toLowerCase() === windowTitle.toLowerCase()) {
|
|
@@ -736,7 +732,6 @@ async function captureIDEScreenshot(opts = {}) {
|
|
|
736
732
|
}
|
|
737
733
|
}
|
|
738
734
|
}
|
|
739
|
-
// 仍未找到 → 不指定窗口名,Swift 工具会自动选最大窗口
|
|
740
735
|
if (!result.success) {
|
|
741
736
|
logger.info(`[Remote/Screenshot] IDE window not found, capturing largest available window`);
|
|
742
737
|
result = await screenshot({ format: 'png' });
|
|
@@ -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 路由)
|
|
@@ -1,15 +1,15 @@
|
|
|
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 路由)
|
|
10
9
|
*/
|
|
11
10
|
import express from 'express';
|
|
12
11
|
import { TaskDispatchBody } from '#shared/schemas/http-requests.js';
|
|
12
|
+
import { taskHandler } from '../../external/mcp/handlers/task.js';
|
|
13
13
|
import { getServiceContainer } from '../../injection/ServiceContainer.js';
|
|
14
14
|
import { validate } from '../middleware/validate.js';
|
|
15
15
|
const router = express.Router();
|
|
@@ -24,357 +24,27 @@ const router = express.Router();
|
|
|
24
24
|
*/
|
|
25
25
|
router.post('/', validate(TaskDispatchBody), async (req, res) => {
|
|
26
26
|
const container = getServiceContainer();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
const { operation, ...params } = req.body;
|
|
27
|
+
// Build a minimal McpContext for the task handler
|
|
28
|
+
const ctx = {
|
|
29
|
+
container,
|
|
30
|
+
session: req.__mcpSession ??
|
|
31
|
+
undefined,
|
|
32
|
+
startedAt: Date.now(),
|
|
33
|
+
};
|
|
35
34
|
try {
|
|
36
|
-
const result = await
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const result = await taskHandler(ctx, req.body);
|
|
36
|
+
const envelope = result;
|
|
37
|
+
if (envelope.success === false) {
|
|
38
|
+
return void res.status(400).json(envelope);
|
|
39
39
|
}
|
|
40
|
-
return void res.json(
|
|
40
|
+
return void res.json(envelope);
|
|
41
41
|
}
|
|
42
42
|
catch (err) {
|
|
43
43
|
return void res.status(400).json({
|
|
44
44
|
success: false,
|
|
45
|
-
message: err.message,
|
|
46
|
-
operation,
|
|
45
|
+
message: err instanceof Error ? err.message : String(err),
|
|
46
|
+
operation: req.body.operation,
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
});
|
|
50
|
-
/** 操作路由 — 与 MCP handler/task.js 保持一致 */
|
|
51
|
-
async function _dispatch(svc, operation, params) {
|
|
52
|
-
switch (operation) {
|
|
53
|
-
case 'create':
|
|
54
|
-
return _create(svc, params);
|
|
55
|
-
case 'ready':
|
|
56
|
-
return _ready(svc, params);
|
|
57
|
-
case 'claim':
|
|
58
|
-
return _claim(svc, params);
|
|
59
|
-
case 'close':
|
|
60
|
-
return _close(svc, params);
|
|
61
|
-
case 'fail':
|
|
62
|
-
return _fail(svc, params);
|
|
63
|
-
case 'defer':
|
|
64
|
-
return _defer(svc, params);
|
|
65
|
-
case 'progress':
|
|
66
|
-
return _progress(svc, params);
|
|
67
|
-
case 'prime':
|
|
68
|
-
return _prime(svc);
|
|
69
|
-
case 'decompose':
|
|
70
|
-
return _decompose(svc, params);
|
|
71
|
-
case 'show':
|
|
72
|
-
return _show(svc, params);
|
|
73
|
-
case 'list':
|
|
74
|
-
return _list(svc, params);
|
|
75
|
-
case 'blocked':
|
|
76
|
-
return _blocked(svc);
|
|
77
|
-
case 'dep_add':
|
|
78
|
-
return _depAdd(svc, params);
|
|
79
|
-
case 'dep_tree':
|
|
80
|
-
return _depTree(svc, params);
|
|
81
|
-
case 'stats':
|
|
82
|
-
return _stats(svc);
|
|
83
|
-
case 'record_decision':
|
|
84
|
-
return _recordDecision(svc, params);
|
|
85
|
-
case 'revise_decision':
|
|
86
|
-
return _reviseDecision(svc, params);
|
|
87
|
-
case 'unpin_decision':
|
|
88
|
-
return _unpinDecision(svc, params);
|
|
89
|
-
case 'list_decisions':
|
|
90
|
-
return _list(svc, { ...params, taskType: 'decision', status: params.status || 'pinned' });
|
|
91
|
-
default:
|
|
92
|
-
return { success: false, message: `Unknown operation: ${operation}` };
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// ── create ──
|
|
96
|
-
async function _create(svc, args) {
|
|
97
|
-
if (!args.title) {
|
|
98
|
-
return { success: false, message: 'title is required' };
|
|
99
|
-
}
|
|
100
|
-
const { task, isDuplicate } = await svc.create({
|
|
101
|
-
title: args.title,
|
|
102
|
-
description: args.description || '',
|
|
103
|
-
design: args.design || '',
|
|
104
|
-
acceptance: args.acceptance || '',
|
|
105
|
-
priority: args.priority ?? 2,
|
|
106
|
-
taskType: args.taskType || 'task',
|
|
107
|
-
parentId: args.parentId || null,
|
|
108
|
-
});
|
|
109
|
-
return {
|
|
110
|
-
success: true,
|
|
111
|
-
data: task.toJSON(),
|
|
112
|
-
message: isDuplicate
|
|
113
|
-
? `Duplicate detected: ${task.id} already exists`
|
|
114
|
-
: `Created ${task.id}: ${task.title}`,
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
// ── ready ──
|
|
118
|
-
async function _ready(svc, args) {
|
|
119
|
-
const tasks = await svc.ready({
|
|
120
|
-
limit: args.limit || 5,
|
|
121
|
-
withKnowledge: args.withKnowledge !== false,
|
|
122
|
-
});
|
|
123
|
-
return {
|
|
124
|
-
success: true,
|
|
125
|
-
data: tasks.map((t) => (t.toJSON ? t.toJSON() : t)),
|
|
126
|
-
count: tasks.length,
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
// ── claim ──
|
|
130
|
-
async function _claim(svc, args) {
|
|
131
|
-
if (!args.id) {
|
|
132
|
-
return { success: false, message: 'id is required' };
|
|
133
|
-
}
|
|
134
|
-
const task = await svc.claim(args.id, args.assignee || 'agent');
|
|
135
|
-
return { success: true, data: task.toJSON() };
|
|
136
|
-
}
|
|
137
|
-
// ── close ──
|
|
138
|
-
async function _close(svc, args) {
|
|
139
|
-
if (!args.id) {
|
|
140
|
-
return { success: false, message: 'id is required' };
|
|
141
|
-
}
|
|
142
|
-
const { task, newlyReady } = await svc.close(args.id, args.reason || 'Completed');
|
|
143
|
-
return {
|
|
144
|
-
success: true,
|
|
145
|
-
data: task.toJSON(),
|
|
146
|
-
newlyReady,
|
|
147
|
-
message: `Closed ${task.id}. ${newlyReady.length} tasks newly ready.`,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
// ── fail ──
|
|
151
|
-
async function _fail(svc, args) {
|
|
152
|
-
if (!args.id) {
|
|
153
|
-
return { success: false, message: 'id is required' };
|
|
154
|
-
}
|
|
155
|
-
const task = await svc.fail(args.id, args.reason || '');
|
|
156
|
-
return { success: true, data: task.toJSON() };
|
|
157
|
-
}
|
|
158
|
-
// ── defer ──
|
|
159
|
-
async function _defer(svc, args) {
|
|
160
|
-
if (!args.id) {
|
|
161
|
-
return { success: false, message: 'id is required' };
|
|
162
|
-
}
|
|
163
|
-
const task = await svc.defer(args.id, args.reason || '');
|
|
164
|
-
return { success: true, data: task.toJSON() };
|
|
165
|
-
}
|
|
166
|
-
// ── progress ──
|
|
167
|
-
async function _progress(svc, args) {
|
|
168
|
-
if (!args.id) {
|
|
169
|
-
return { success: false, message: 'id is required' };
|
|
170
|
-
}
|
|
171
|
-
const task = await svc.progress(args.id, args.note || args.description || '');
|
|
172
|
-
return { success: true, data: task.toJSON() };
|
|
173
|
-
}
|
|
174
|
-
// ── prime ──
|
|
175
|
-
async function _prime(svc) {
|
|
176
|
-
const result = await svc.prime({ withKnowledge: true });
|
|
177
|
-
const decisionCount = (result.decisions || []).length;
|
|
178
|
-
const staleCount = (result.staleDecisions || []).length;
|
|
179
|
-
const decisionTitles = (result.decisions || []).map((d) => d.title).join('; ');
|
|
180
|
-
const statsLine = `${result.inProgress.length} in-progress, ${result.ready.length} ready, ${result.stats.total} total`;
|
|
181
|
-
// ── Behavioral Rules Reminder (synced with MCP handler) ──
|
|
182
|
-
result._taskRules = {
|
|
183
|
-
reminder: [
|
|
184
|
-
'📋 TASK RULES (MANDATORY):',
|
|
185
|
-
'🔑 YOU are the task operator — user speaks naturally, you translate to task operations. NEVER tell user to run task commands.',
|
|
186
|
-
'• MUST prime on EVERY message BEFORE anything else',
|
|
187
|
-
'• MUST create task for non-trivial work (≥2 files OR ≥10 lines)',
|
|
188
|
-
'• MUST claim before coding, close when done with meaningful reason',
|
|
189
|
-
'• MUST handle unfinished tasks before starting new work (ask user: Continue/Defer/Abandon)',
|
|
190
|
-
'• NEVER skip prime, NEVER start new work with open in_progress tasks',
|
|
191
|
-
'• NEVER leave tasks in in_progress when session ends — close or defer ALL',
|
|
192
|
-
'• When in doubt → create a task. When idle → ready()',
|
|
193
|
-
'• Session end → close all tasks, defer incomplete, verify zero in_progress',
|
|
194
|
-
].join('\n'),
|
|
195
|
-
translationHint: [
|
|
196
|
-
'User Says → You Run:',
|
|
197
|
-
'"fix bug"/"implement" → create→claim→code→close',
|
|
198
|
-
'"continue" → resume in-progress→close',
|
|
199
|
-
'"pause" → defer | "abandon" → fail | "break down" → decompose',
|
|
200
|
-
'"what\'s next" → ready() | "agreed" → record_decision',
|
|
201
|
-
'Quick question → No task. Just answer.',
|
|
202
|
-
].join('\n'),
|
|
203
|
-
};
|
|
204
|
-
// ── Resume Prompt: 有 inProgress 任务时,提示 Agent 让用户选择 ──
|
|
205
|
-
if (result.inProgress.length > 0) {
|
|
206
|
-
const taskList = result.inProgress
|
|
207
|
-
.map((t) => {
|
|
208
|
-
const age = t.updatedAt
|
|
209
|
-
? `${Math.floor((Date.now() / 1000 - t.updatedAt) / 86400)}d ago`
|
|
210
|
-
: '';
|
|
211
|
-
return `• **${t.id}** — ${t.title}${age ? ` (${age})` : ''}`;
|
|
212
|
-
})
|
|
213
|
-
.join('\n');
|
|
214
|
-
result._resumePrompt = {
|
|
215
|
-
instruction: [
|
|
216
|
-
'There are unfinished tasks. You MUST present these options to the user BEFORE doing anything else:',
|
|
217
|
-
'',
|
|
218
|
-
'**Unfinished tasks:**',
|
|
219
|
-
taskList,
|
|
220
|
-
'',
|
|
221
|
-
'Ask the user to choose:',
|
|
222
|
-
'1. **Continue** — resume the unfinished task(s)',
|
|
223
|
-
'2. **Defer** — pause it and work on something else',
|
|
224
|
-
'3. **Abandon** — close/fail it and start fresh',
|
|
225
|
-
'',
|
|
226
|
-
"Wait for the user's answer. Do NOT auto-resume.",
|
|
227
|
-
].join('\n'),
|
|
228
|
-
taskIds: result.inProgress.map((t) => t.id),
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
let message;
|
|
232
|
-
if (decisionCount > 0) {
|
|
233
|
-
const stalePart = staleCount > 0 ? ` ${staleCount} stale.` : '';
|
|
234
|
-
message = `⚠️ ${decisionCount} ACTIVE DECISION(S): [${decisionTitles}].${stalePart} ${statsLine}.`;
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
message = `${statsLine}.`;
|
|
238
|
-
}
|
|
239
|
-
if (result.inProgress.length > 0) {
|
|
240
|
-
message += ` ⏸️ ${result.inProgress.length} unfinished task(s) — ask user before resuming.`;
|
|
241
|
-
}
|
|
242
|
-
return {
|
|
243
|
-
success: true,
|
|
244
|
-
data: result,
|
|
245
|
-
message,
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
// ── decompose ──
|
|
249
|
-
async function _decompose(svc, args) {
|
|
250
|
-
const epicId = args.parentId || args.id;
|
|
251
|
-
const subtasks = args.children || args.subtasks;
|
|
252
|
-
if (!epicId) {
|
|
253
|
-
return { success: false, message: 'parentId (or id) is required' };
|
|
254
|
-
}
|
|
255
|
-
if (!subtasks || !Array.isArray(subtasks)) {
|
|
256
|
-
return { success: false, message: 'children (or subtasks) array is required' };
|
|
257
|
-
}
|
|
258
|
-
const tasks = await svc.decompose(epicId, subtasks);
|
|
259
|
-
return {
|
|
260
|
-
success: true,
|
|
261
|
-
data: tasks.map((t) => t.toJSON()),
|
|
262
|
-
count: tasks.length,
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
// ── show ──
|
|
266
|
-
async function _show(svc, args) {
|
|
267
|
-
if (!args.id) {
|
|
268
|
-
return { success: false, message: 'id is required' };
|
|
269
|
-
}
|
|
270
|
-
const task = await svc.show(args.id);
|
|
271
|
-
if (!task) {
|
|
272
|
-
return { success: false, message: `Task ${args.id} not found` };
|
|
273
|
-
}
|
|
274
|
-
return { success: true, data: task.toJSON() };
|
|
275
|
-
}
|
|
276
|
-
// ── list ──
|
|
277
|
-
async function _list(svc, args) {
|
|
278
|
-
const tasks = await svc.list({ status: args.status, taskType: args.taskType, parentId: args.parentId }, { limit: args.limit || 50 });
|
|
279
|
-
return {
|
|
280
|
-
success: true,
|
|
281
|
-
data: tasks.map((t) => t.toJSON()),
|
|
282
|
-
count: tasks.length,
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
// ── blocked ──
|
|
286
|
-
async function _blocked(svc) {
|
|
287
|
-
const tasks = await svc.blocked();
|
|
288
|
-
return {
|
|
289
|
-
success: true,
|
|
290
|
-
data: tasks.map((t) => (t.toJSON ? t.toJSON() : t)),
|
|
291
|
-
count: tasks.length,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
// ── dep_add ──
|
|
295
|
-
async function _depAdd(svc, args) {
|
|
296
|
-
if (!args.taskId || !args.dependsOn) {
|
|
297
|
-
return { success: false, message: 'taskId and dependsOn are required' };
|
|
298
|
-
}
|
|
299
|
-
await svc.addDependency(args.taskId, args.dependsOn, args.depType || 'blocks');
|
|
300
|
-
return {
|
|
301
|
-
success: true,
|
|
302
|
-
message: `Dependency added: ${args.taskId} ${args.depType || 'blocks'} ${args.dependsOn}`,
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
// ── dep_tree ──
|
|
306
|
-
async function _depTree(svc, args) {
|
|
307
|
-
if (!args.id) {
|
|
308
|
-
return { success: false, message: 'id is required' };
|
|
309
|
-
}
|
|
310
|
-
const tree = await svc.depTree(args.id);
|
|
311
|
-
return { success: true, data: tree };
|
|
312
|
-
}
|
|
313
|
-
// ── stats ──
|
|
314
|
-
async function _stats(svc) {
|
|
315
|
-
const stats = await svc.stats();
|
|
316
|
-
return { success: true, data: stats };
|
|
317
|
-
}
|
|
318
|
-
// ── record_decision ──
|
|
319
|
-
async function _recordDecision(svc, args) {
|
|
320
|
-
if (!args.title) {
|
|
321
|
-
return { success: false, message: 'title is required' };
|
|
322
|
-
}
|
|
323
|
-
if (!args.description) {
|
|
324
|
-
return { success: false, message: 'description is required' };
|
|
325
|
-
}
|
|
326
|
-
const { task, isDuplicate } = await svc.recordDecision({
|
|
327
|
-
title: args.title,
|
|
328
|
-
description: args.description,
|
|
329
|
-
rationale: args.rationale || '',
|
|
330
|
-
tags: args.tags || [],
|
|
331
|
-
relatedTaskId: args.relatedTaskId || null,
|
|
332
|
-
});
|
|
333
|
-
return {
|
|
334
|
-
success: true,
|
|
335
|
-
data: task.toJSON(),
|
|
336
|
-
message: isDuplicate
|
|
337
|
-
? `Decision already recorded: ${task.id}`
|
|
338
|
-
: `Decision pinned: ${task.id} — "${args.title}"`,
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
// ── revise_decision ──
|
|
342
|
-
async function _reviseDecision(svc, args) {
|
|
343
|
-
if (!args.id) {
|
|
344
|
-
return { success: false, message: 'id of old decision is required' };
|
|
345
|
-
}
|
|
346
|
-
if (!args.title) {
|
|
347
|
-
return { success: false, message: 'title of new decision is required' };
|
|
348
|
-
}
|
|
349
|
-
if (!args.description) {
|
|
350
|
-
return { success: false, message: 'description of new decision is required' };
|
|
351
|
-
}
|
|
352
|
-
const result = await svc.reviseDecision({
|
|
353
|
-
oldDecisionId: args.id,
|
|
354
|
-
title: args.title,
|
|
355
|
-
description: args.description,
|
|
356
|
-
rationale: args.rationale || '',
|
|
357
|
-
reason: args.reason || '',
|
|
358
|
-
});
|
|
359
|
-
return {
|
|
360
|
-
success: true,
|
|
361
|
-
data: {
|
|
362
|
-
newDecision: result.newDecision.toJSON(),
|
|
363
|
-
superseded: result.oldDecisionId,
|
|
364
|
-
},
|
|
365
|
-
message: `Decision revised: ${result.oldDecisionId} → ${result.newDecision.id}`,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
// ── unpin_decision ──
|
|
369
|
-
async function _unpinDecision(svc, args) {
|
|
370
|
-
if (!args.id) {
|
|
371
|
-
return { success: false, message: 'id is required' };
|
|
372
|
-
}
|
|
373
|
-
const task = await svc.unpinDecision(args.id, args.reason || '');
|
|
374
|
-
return {
|
|
375
|
-
success: true,
|
|
376
|
-
data: task.toJSON(),
|
|
377
|
-
message: `Decision ${args.id} unpinned and closed`,
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
50
|
export default router;
|
|
@@ -53,7 +53,7 @@ router.get('/stats', async (req, res) => {
|
|
|
53
53
|
router.post('/clear', async (req, res) => {
|
|
54
54
|
const container = getServiceContainer();
|
|
55
55
|
const violationsStore = container.get('violationsStore');
|
|
56
|
-
const { ruleId, file, all } = req.body;
|
|
56
|
+
const { ruleId, file, all } = req.body || {};
|
|
57
57
|
let cleared = 0;
|
|
58
58
|
if (all) {
|
|
59
59
|
cleared = (await violationsStore.clearAll());
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { AuditStore } from './AuditStore.js';
|
|
2
|
+
/** Minimal EventBus shape for optional audit event emission */
|
|
3
|
+
interface AuditEventBus {
|
|
4
|
+
emit(event: string, data: unknown): void;
|
|
5
|
+
}
|
|
2
6
|
/** AuditLogger - 审计日志记录器 */
|
|
3
7
|
export declare class AuditLogger {
|
|
8
|
+
#private;
|
|
4
9
|
auditStore: AuditStore;
|
|
5
10
|
logger: import('winston').Logger;
|
|
6
|
-
constructor(auditStore: AuditStore);
|
|
11
|
+
constructor(auditStore: AuditStore, eventBus?: AuditEventBus | null);
|
|
7
12
|
/**
|
|
8
13
|
* 记录审计日志
|
|
9
14
|
* 兼容两种传入格式:
|
|
@@ -3,9 +3,11 @@ import Logger from '../../infrastructure/logging/Logger.js';
|
|
|
3
3
|
export class AuditLogger {
|
|
4
4
|
auditStore;
|
|
5
5
|
logger;
|
|
6
|
-
|
|
6
|
+
#eventBus;
|
|
7
|
+
constructor(auditStore, eventBus) {
|
|
7
8
|
this.auditStore = auditStore;
|
|
8
9
|
this.logger = Logger.getInstance();
|
|
10
|
+
this.#eventBus = eventBus ?? null;
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* 记录审计日志
|
|
@@ -40,6 +42,17 @@ export class AuditLogger {
|
|
|
40
42
|
actor: entry.actor,
|
|
41
43
|
action: entry.action,
|
|
42
44
|
});
|
|
45
|
+
// 实时推送审计事件到 Dashboard(M7 §6 audit:entry Socket.io)
|
|
46
|
+
if (this.#eventBus) {
|
|
47
|
+
this.#eventBus.emit('audit:entry', {
|
|
48
|
+
id: auditEntry.id,
|
|
49
|
+
timestamp: auditEntry.timestamp,
|
|
50
|
+
actor: auditEntry.actor,
|
|
51
|
+
action: auditEntry.action,
|
|
52
|
+
resource: auditEntry.resource,
|
|
53
|
+
result: auditEntry.result,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
43
56
|
}
|
|
44
57
|
catch (error) {
|
|
45
58
|
// 审计失败不应阻断业务,仅记录错误
|