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
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RoleRefiner — 四重信号融合角色精化
|
|
3
|
+
*
|
|
4
|
+
* 将 TargetClassifier 的正则推断 (~65% 准确率) 提升到 ≥90%,
|
|
5
|
+
* 通过融合 AST 结构、CallGraph 行为、DataFlow 数据流、EntityGraph 拓扑四重信号。
|
|
6
|
+
*
|
|
7
|
+
* 信号权重:
|
|
8
|
+
* AST 结构 0.30 继承链/协议/import/后缀
|
|
9
|
+
* CallGraph 行为 0.30 被调用分析/扇入扇出比/调用类型
|
|
10
|
+
* DataFlow 数据流 0.15 源汇分析/转换检测
|
|
11
|
+
* EntityGraph 拓扑 0.10 入度分析/模式检测
|
|
12
|
+
* 正则基线 0.15 TargetClassifier 结果
|
|
13
|
+
*
|
|
14
|
+
* @module RoleRefiner
|
|
15
|
+
*/
|
|
16
|
+
/* ═══ Constants ═══════════════════════════════════════════ */
|
|
17
|
+
const WEIGHTS = {
|
|
18
|
+
ast: 0.3,
|
|
19
|
+
callGraph: 0.3,
|
|
20
|
+
dataFlow: 0.15,
|
|
21
|
+
entityGraph: 0.1,
|
|
22
|
+
regex: 0.15,
|
|
23
|
+
};
|
|
24
|
+
/** primary_lang / LanguageService 输出 → 语言族 */
|
|
25
|
+
const LANG_TO_FAMILY = {
|
|
26
|
+
swift: 'apple',
|
|
27
|
+
objectivec: 'apple',
|
|
28
|
+
java: 'jvm',
|
|
29
|
+
kotlin: 'jvm',
|
|
30
|
+
dart: 'dart',
|
|
31
|
+
python: 'python',
|
|
32
|
+
typescript: 'web',
|
|
33
|
+
javascript: 'web',
|
|
34
|
+
tsx: 'web',
|
|
35
|
+
go: 'go',
|
|
36
|
+
rust: 'rust',
|
|
37
|
+
};
|
|
38
|
+
/* ─── 按语言族分区的超类映射 ─────────────────────────────── */
|
|
39
|
+
const SUPERCLASS_BY_FAMILY = {
|
|
40
|
+
apple: {
|
|
41
|
+
UIViewController: 'ui',
|
|
42
|
+
UIView: 'ui',
|
|
43
|
+
UITableViewCell: 'ui',
|
|
44
|
+
UICollectionViewCell: 'ui',
|
|
45
|
+
UINavigationController: 'routing',
|
|
46
|
+
UITabBarController: 'routing',
|
|
47
|
+
UIApplication: 'app',
|
|
48
|
+
NSObject: 'core',
|
|
49
|
+
NSManagedObject: 'storage',
|
|
50
|
+
},
|
|
51
|
+
jvm: {
|
|
52
|
+
Activity: 'ui',
|
|
53
|
+
AppCompatActivity: 'ui',
|
|
54
|
+
Fragment: 'ui',
|
|
55
|
+
DialogFragment: 'ui',
|
|
56
|
+
View: 'ui',
|
|
57
|
+
RecyclerViewAdapter: 'ui',
|
|
58
|
+
Service: 'service',
|
|
59
|
+
IntentService: 'service',
|
|
60
|
+
BroadcastReceiver: 'service',
|
|
61
|
+
ContentProvider: 'storage',
|
|
62
|
+
ViewModel: 'ui',
|
|
63
|
+
AndroidViewModel: 'ui',
|
|
64
|
+
Application: 'app',
|
|
65
|
+
},
|
|
66
|
+
dart: {
|
|
67
|
+
StatefulWidget: 'ui',
|
|
68
|
+
StatelessWidget: 'ui',
|
|
69
|
+
State: 'ui',
|
|
70
|
+
ChangeNotifier: 'service',
|
|
71
|
+
Cubit: 'service',
|
|
72
|
+
Bloc: 'service',
|
|
73
|
+
},
|
|
74
|
+
python: {
|
|
75
|
+
BaseModel: 'model',
|
|
76
|
+
Model: 'model',
|
|
77
|
+
APIView: 'service',
|
|
78
|
+
ViewSet: 'service',
|
|
79
|
+
TestCase: 'test',
|
|
80
|
+
},
|
|
81
|
+
web: {
|
|
82
|
+
Component: 'ui',
|
|
83
|
+
Controller: 'service',
|
|
84
|
+
Module: 'app',
|
|
85
|
+
},
|
|
86
|
+
go: {},
|
|
87
|
+
rust: {},
|
|
88
|
+
};
|
|
89
|
+
/* ─── 按语言族分区的协议/接口映射 ────────────────────────── */
|
|
90
|
+
const PROTOCOL_BY_FAMILY = {
|
|
91
|
+
apple: {
|
|
92
|
+
UITableViewDataSource: 'ui',
|
|
93
|
+
UITableViewDelegate: 'ui',
|
|
94
|
+
UICollectionViewDataSource: 'ui',
|
|
95
|
+
UIApplicationDelegate: 'app',
|
|
96
|
+
UISceneDelegate: 'app',
|
|
97
|
+
UIWindowSceneDelegate: 'app',
|
|
98
|
+
URLSessionDelegate: 'networking',
|
|
99
|
+
Codable: 'model',
|
|
100
|
+
Decodable: 'model',
|
|
101
|
+
Encodable: 'model',
|
|
102
|
+
},
|
|
103
|
+
jvm: {
|
|
104
|
+
Serializable: 'model',
|
|
105
|
+
Parcelable: 'model',
|
|
106
|
+
Runnable: 'core',
|
|
107
|
+
Callable: 'core',
|
|
108
|
+
OnClickListener: 'ui',
|
|
109
|
+
Adapter: 'ui',
|
|
110
|
+
Repository: 'storage',
|
|
111
|
+
},
|
|
112
|
+
dart: {
|
|
113
|
+
Widget: 'ui',
|
|
114
|
+
},
|
|
115
|
+
web: {
|
|
116
|
+
OnInit: 'ui',
|
|
117
|
+
OnDestroy: 'ui',
|
|
118
|
+
CanActivate: 'routing',
|
|
119
|
+
NestMiddleware: 'service',
|
|
120
|
+
},
|
|
121
|
+
go: {
|
|
122
|
+
Handler: 'service',
|
|
123
|
+
ReadWriter: 'core',
|
|
124
|
+
Reader: 'core',
|
|
125
|
+
Writer: 'core',
|
|
126
|
+
Stringer: 'utility',
|
|
127
|
+
},
|
|
128
|
+
rust: {
|
|
129
|
+
Display: 'utility',
|
|
130
|
+
Debug: 'utility',
|
|
131
|
+
Serialize: 'model',
|
|
132
|
+
Deserialize: 'model',
|
|
133
|
+
Future: 'core',
|
|
134
|
+
Stream: 'core',
|
|
135
|
+
Service: 'service',
|
|
136
|
+
},
|
|
137
|
+
python: {},
|
|
138
|
+
};
|
|
139
|
+
const IMPORT_PATTERNS_BY_FAMILY = {
|
|
140
|
+
apple: [
|
|
141
|
+
{ regex: /alamofire|urlsession|afnetworking|moya/i, role: 'networking' },
|
|
142
|
+
{ regex: /\buikit\b|swiftui|rx.*cocoa|snapkit|masonry/i, role: 'ui' },
|
|
143
|
+
{ regex: /realm|coredata|fmdb|grdb/i, role: 'storage' },
|
|
144
|
+
{ regex: /xctest/i, role: 'test' },
|
|
145
|
+
],
|
|
146
|
+
jvm: [
|
|
147
|
+
{ regex: /retrofit|okhttp|volley/i, role: 'networking' },
|
|
148
|
+
{ regex: /android\.widget|jetpack.*compose|recyclerview/i, role: 'ui' },
|
|
149
|
+
{ regex: /room|hibernate|greendao/i, role: 'storage' },
|
|
150
|
+
{ regex: /junit|espresso|mockito/i, role: 'test' },
|
|
151
|
+
],
|
|
152
|
+
dart: [
|
|
153
|
+
{ regex: /\bdio\b|http_client/i, role: 'networking' },
|
|
154
|
+
{ regex: /flutter|cupertino|material/i, role: 'ui' },
|
|
155
|
+
{ regex: /sqflite|hive|objectbox/i, role: 'storage' },
|
|
156
|
+
{ regex: /flutter_test/i, role: 'test' },
|
|
157
|
+
],
|
|
158
|
+
python: [
|
|
159
|
+
{ regex: /requests|aiohttp|httpx|urllib/i, role: 'networking' },
|
|
160
|
+
{ regex: /tkinter|pyqt|kivy/i, role: 'ui' },
|
|
161
|
+
{ regex: /sqlalchemy|django\.db|peewee|tortoise/i, role: 'storage' },
|
|
162
|
+
{ regex: /pytest|unittest/i, role: 'test' },
|
|
163
|
+
],
|
|
164
|
+
web: [
|
|
165
|
+
{ regex: /axios|fetch|got|superagent/i, role: 'networking' },
|
|
166
|
+
{ regex: /react|angular|vue|svelte|next|nuxt/i, role: 'ui' },
|
|
167
|
+
{ regex: /typeorm|prisma|sequelize|mongoose|knex/i, role: 'storage' },
|
|
168
|
+
{ regex: /jest|mocha|vitest|cypress|playwright/i, role: 'test' },
|
|
169
|
+
{ regex: /express|fastify|nestjs|koa/i, role: 'routing' },
|
|
170
|
+
],
|
|
171
|
+
go: [
|
|
172
|
+
{ regex: /net\/http|resty/i, role: 'networking' },
|
|
173
|
+
{ regex: /gin|echo|fiber|mux|chi/i, role: 'routing' },
|
|
174
|
+
{ regex: /gorm|sqlx|ent/i, role: 'storage' },
|
|
175
|
+
{ regex: /testing/i, role: 'test' },
|
|
176
|
+
],
|
|
177
|
+
rust: [
|
|
178
|
+
{ regex: /reqwest|hyper|surf/i, role: 'networking' },
|
|
179
|
+
{ regex: /actix|axum|warp|rocket/i, role: 'routing' },
|
|
180
|
+
{ regex: /diesel|sqlx|sea-orm/i, role: 'storage' },
|
|
181
|
+
{ regex: /tokio-test/i, role: 'test' },
|
|
182
|
+
],
|
|
183
|
+
};
|
|
184
|
+
/** 通用 import 模式(任何语言都适用) */
|
|
185
|
+
const UNIVERSAL_IMPORT_PATTERNS = [
|
|
186
|
+
{ regex: /network/i, role: 'networking' },
|
|
187
|
+
{ regex: /sqlite/i, role: 'storage' },
|
|
188
|
+
{ regex: /router|routing|navigation/i, role: 'routing' },
|
|
189
|
+
];
|
|
190
|
+
/* ═══ RoleRefiner Class ═══════════════════════════════════ */
|
|
191
|
+
export class RoleRefiner {
|
|
192
|
+
#db;
|
|
193
|
+
#projectRoot;
|
|
194
|
+
#families = null;
|
|
195
|
+
#superclassMap = null;
|
|
196
|
+
#protocolMap = null;
|
|
197
|
+
#importPatterns = null;
|
|
198
|
+
constructor(db, projectRoot) {
|
|
199
|
+
this.#db = db;
|
|
200
|
+
this.#projectRoot = projectRoot;
|
|
201
|
+
}
|
|
202
|
+
/** 检测项目语言族,基于 bootstrap_snapshots.primary_lang */
|
|
203
|
+
#detectFamilies() {
|
|
204
|
+
if (this.#families) {
|
|
205
|
+
return this.#families;
|
|
206
|
+
}
|
|
207
|
+
const row = this.#db
|
|
208
|
+
.prepare(`SELECT primary_lang FROM bootstrap_snapshots
|
|
209
|
+
WHERE project_root = ? ORDER BY created_at DESC LIMIT 1`)
|
|
210
|
+
.get(this.#projectRoot);
|
|
211
|
+
const primaryLang = row?.primary_lang;
|
|
212
|
+
if (primaryLang && LANG_TO_FAMILY[primaryLang]) {
|
|
213
|
+
this.#families = [LANG_TO_FAMILY[primaryLang]];
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// 无 bootstrap 数据时回退:使用所有语言族
|
|
217
|
+
this.#families = Object.keys(SUPERCLASS_BY_FAMILY);
|
|
218
|
+
}
|
|
219
|
+
return this.#families;
|
|
220
|
+
}
|
|
221
|
+
/** 构建当前项目语言族的超类合并映射 */
|
|
222
|
+
#getSuperclassMap() {
|
|
223
|
+
if (this.#superclassMap) {
|
|
224
|
+
return this.#superclassMap;
|
|
225
|
+
}
|
|
226
|
+
const merged = {};
|
|
227
|
+
for (const fam of this.#detectFamilies()) {
|
|
228
|
+
Object.assign(merged, SUPERCLASS_BY_FAMILY[fam]);
|
|
229
|
+
}
|
|
230
|
+
this.#superclassMap = merged;
|
|
231
|
+
return merged;
|
|
232
|
+
}
|
|
233
|
+
/** 构建当前项目语言族的协议合并映射 */
|
|
234
|
+
#getProtocolMap() {
|
|
235
|
+
if (this.#protocolMap) {
|
|
236
|
+
return this.#protocolMap;
|
|
237
|
+
}
|
|
238
|
+
const merged = {};
|
|
239
|
+
for (const fam of this.#detectFamilies()) {
|
|
240
|
+
Object.assign(merged, PROTOCOL_BY_FAMILY[fam]);
|
|
241
|
+
}
|
|
242
|
+
this.#protocolMap = merged;
|
|
243
|
+
return merged;
|
|
244
|
+
}
|
|
245
|
+
/** 构建当前项目语言族的 import 模式列表 */
|
|
246
|
+
#getImportPatterns() {
|
|
247
|
+
if (this.#importPatterns) {
|
|
248
|
+
return this.#importPatterns;
|
|
249
|
+
}
|
|
250
|
+
const patterns = [...UNIVERSAL_IMPORT_PATTERNS];
|
|
251
|
+
for (const fam of this.#detectFamilies()) {
|
|
252
|
+
patterns.push(...IMPORT_PATTERNS_BY_FAMILY[fam]);
|
|
253
|
+
}
|
|
254
|
+
this.#importPatterns = patterns;
|
|
255
|
+
return patterns;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* 精化单个模块的角色
|
|
259
|
+
*/
|
|
260
|
+
refineRole(module) {
|
|
261
|
+
const signals = [];
|
|
262
|
+
// 1. AST 结构信号 (0.30)
|
|
263
|
+
signals.push(...this.#extractAstSignals(module));
|
|
264
|
+
// 2. CallGraph 行为信号 (0.30)
|
|
265
|
+
signals.push(...this.#extractCallSignals(module));
|
|
266
|
+
// 3. DataFlow 数据流信号 (0.15)
|
|
267
|
+
signals.push(...this.#extractFlowSignals(module));
|
|
268
|
+
// 4. EntityGraph 拓扑信号 (0.10)
|
|
269
|
+
signals.push(...this.#extractTopoSignals(module));
|
|
270
|
+
// 5. 正则基线 (0.15)
|
|
271
|
+
signals.push({
|
|
272
|
+
role: module.inferredRole,
|
|
273
|
+
confidence: 0.5,
|
|
274
|
+
weight: WEIGHTS.regex,
|
|
275
|
+
source: 'regex-baseline',
|
|
276
|
+
});
|
|
277
|
+
// 加权投票
|
|
278
|
+
const roleScores = {};
|
|
279
|
+
for (const signal of signals) {
|
|
280
|
+
roleScores[signal.role] = (roleScores[signal.role] ?? 0) + signal.confidence * signal.weight;
|
|
281
|
+
}
|
|
282
|
+
const sorted = Object.entries(roleScores).sort((a, b) => b[1] - a[1]);
|
|
283
|
+
if (sorted.length === 0) {
|
|
284
|
+
return {
|
|
285
|
+
refinedRole: module.inferredRole,
|
|
286
|
+
confidence: 0,
|
|
287
|
+
resolution: 'fallback',
|
|
288
|
+
signals,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const [topRole, topScore] = sorted[0];
|
|
292
|
+
const secondScore = sorted[1]?.[1] ?? 0;
|
|
293
|
+
// 冲突解决
|
|
294
|
+
if (topScore > 0.7) {
|
|
295
|
+
return {
|
|
296
|
+
refinedRole: topRole,
|
|
297
|
+
confidence: Math.min(topScore, 1),
|
|
298
|
+
resolution: 'clear',
|
|
299
|
+
signals,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
if (topScore - secondScore < 0.1) {
|
|
303
|
+
return {
|
|
304
|
+
refinedRole: topRole,
|
|
305
|
+
confidence: Math.min(topScore, 1),
|
|
306
|
+
resolution: 'uncertain',
|
|
307
|
+
alternatives: sorted.slice(0, 3),
|
|
308
|
+
signals,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return {
|
|
312
|
+
refinedRole: topRole,
|
|
313
|
+
confidence: Math.min(topScore, 1),
|
|
314
|
+
resolution: topScore > 0.4 ? 'clear' : 'fallback',
|
|
315
|
+
signals,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* 批量精化所有模块
|
|
320
|
+
*/
|
|
321
|
+
refineAll(modules) {
|
|
322
|
+
const result = new Map();
|
|
323
|
+
for (const m of modules) {
|
|
324
|
+
result.set(m.name, this.refineRole(m));
|
|
325
|
+
}
|
|
326
|
+
return result;
|
|
327
|
+
}
|
|
328
|
+
/* ─── Signal Extractors ──────────────────────────── */
|
|
329
|
+
/** AST 结构信号: 继承链、协议、import */
|
|
330
|
+
#extractAstSignals(module) {
|
|
331
|
+
const signals = [];
|
|
332
|
+
const filePaths = module.files;
|
|
333
|
+
if (filePaths.length === 0) {
|
|
334
|
+
return signals;
|
|
335
|
+
}
|
|
336
|
+
// 查询模块内实体的继承关系
|
|
337
|
+
const placeholders = filePaths.map(() => '?').join(',');
|
|
338
|
+
const entities = this.#db
|
|
339
|
+
.prepare(`SELECT entity_id, entity_type, superclass, protocols, file_path
|
|
340
|
+
FROM code_entities
|
|
341
|
+
WHERE project_root = ? AND file_path IN (${placeholders})`)
|
|
342
|
+
.all(this.#projectRoot, ...filePaths);
|
|
343
|
+
const roleCounts = {};
|
|
344
|
+
const superclassMap = this.#getSuperclassMap();
|
|
345
|
+
const protocolMap = this.#getProtocolMap();
|
|
346
|
+
for (const entity of entities) {
|
|
347
|
+
// 继承链推断
|
|
348
|
+
const superclass = entity.superclass;
|
|
349
|
+
if (superclass && superclassMap[superclass]) {
|
|
350
|
+
const role = superclassMap[superclass];
|
|
351
|
+
roleCounts[role] = (roleCounts[role] ?? 0) + 1;
|
|
352
|
+
}
|
|
353
|
+
// 协议推断
|
|
354
|
+
try {
|
|
355
|
+
const protocols = JSON.parse(entity.protocols || '[]');
|
|
356
|
+
for (const proto of protocols) {
|
|
357
|
+
if (protocolMap[proto]) {
|
|
358
|
+
const role = protocolMap[proto];
|
|
359
|
+
roleCounts[role] = (roleCounts[role] ?? 0) + 0.5;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
catch {
|
|
364
|
+
// ignore malformed JSON
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// import 模式推断
|
|
368
|
+
const imports = this.#db
|
|
369
|
+
.prepare(`SELECT DISTINCT to_id FROM knowledge_edges
|
|
370
|
+
WHERE from_type = 'module' AND from_id = ? AND relation = 'depends_on'`)
|
|
371
|
+
.all(module.name);
|
|
372
|
+
for (const imp of imports) {
|
|
373
|
+
const depName = imp.to_id.toLowerCase();
|
|
374
|
+
for (const pat of this.#getImportPatterns()) {
|
|
375
|
+
if (pat.regex.test(depName)) {
|
|
376
|
+
roleCounts[pat.role] = (roleCounts[pat.role] ?? 0) + 0.5;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// 转换为信号
|
|
381
|
+
const totalSignals = Object.values(roleCounts).reduce((a, b) => a + b, 0);
|
|
382
|
+
if (totalSignals > 0) {
|
|
383
|
+
for (const [role, count] of Object.entries(roleCounts)) {
|
|
384
|
+
signals.push({
|
|
385
|
+
role: role,
|
|
386
|
+
confidence: Math.min(count / totalSignals, 1),
|
|
387
|
+
weight: WEIGHTS.ast,
|
|
388
|
+
source: 'ast-structure',
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
return signals;
|
|
393
|
+
}
|
|
394
|
+
/** CallGraph 行为信号: 调用流向分析 */
|
|
395
|
+
#extractCallSignals(module) {
|
|
396
|
+
const signals = [];
|
|
397
|
+
// 查模块实体的 call edge 统计
|
|
398
|
+
const filePaths = module.files;
|
|
399
|
+
if (filePaths.length === 0) {
|
|
400
|
+
return signals;
|
|
401
|
+
}
|
|
402
|
+
const placeholders = filePaths.map(() => '?').join(',');
|
|
403
|
+
// fan-out: 模块内实体调用外部
|
|
404
|
+
const outEdges = this.#db
|
|
405
|
+
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
406
|
+
JOIN code_entities ce ON ke.from_id = ce.entity_id AND ke.from_type = ce.entity_type
|
|
407
|
+
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
408
|
+
AND ke.relation = 'calls'`)
|
|
409
|
+
.get(this.#projectRoot, ...filePaths);
|
|
410
|
+
// fan-in: 外部调用模块内实体
|
|
411
|
+
const inEdges = this.#db
|
|
412
|
+
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
413
|
+
JOIN code_entities ce ON ke.to_id = ce.entity_id AND ke.to_type = ce.entity_type
|
|
414
|
+
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
415
|
+
AND ke.relation = 'calls'`)
|
|
416
|
+
.get(this.#projectRoot, ...filePaths);
|
|
417
|
+
const fanOut = Number(outEdges?.cnt ?? 0);
|
|
418
|
+
const fanIn = Number(inEdges?.cnt ?? 0);
|
|
419
|
+
if (fanIn + fanOut === 0) {
|
|
420
|
+
return signals;
|
|
421
|
+
}
|
|
422
|
+
const ratio = fanIn / (fanIn + fanOut);
|
|
423
|
+
// 高被调用 → 偏 core/service (被依赖)
|
|
424
|
+
// 高调用 → 偏 app/ui (消费者)
|
|
425
|
+
if (ratio > 0.7) {
|
|
426
|
+
signals.push({
|
|
427
|
+
role: 'core',
|
|
428
|
+
confidence: ratio * 0.8,
|
|
429
|
+
weight: WEIGHTS.callGraph,
|
|
430
|
+
source: 'call-fanin-heavy',
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
else if (ratio < 0.3) {
|
|
434
|
+
signals.push({
|
|
435
|
+
role: 'ui',
|
|
436
|
+
confidence: (1 - ratio) * 0.6,
|
|
437
|
+
weight: WEIGHTS.callGraph,
|
|
438
|
+
source: 'call-fanout-heavy',
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
signals.push({
|
|
443
|
+
role: 'service',
|
|
444
|
+
confidence: 0.5,
|
|
445
|
+
weight: WEIGHTS.callGraph,
|
|
446
|
+
source: 'call-balanced',
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
return signals;
|
|
450
|
+
}
|
|
451
|
+
/** DataFlow 数据流信号: 源/汇分析 */
|
|
452
|
+
#extractFlowSignals(module) {
|
|
453
|
+
const signals = [];
|
|
454
|
+
const filePaths = module.files;
|
|
455
|
+
if (filePaths.length === 0) {
|
|
456
|
+
return signals;
|
|
457
|
+
}
|
|
458
|
+
const placeholders = filePaths.map(() => '?').join(',');
|
|
459
|
+
// data_flow out (data producer)
|
|
460
|
+
const outFlow = this.#db
|
|
461
|
+
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
462
|
+
JOIN code_entities ce ON ke.from_id = ce.entity_id AND ke.from_type = ce.entity_type
|
|
463
|
+
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
464
|
+
AND ke.relation = 'data_flow'`)
|
|
465
|
+
.get(this.#projectRoot, ...filePaths);
|
|
466
|
+
// data_flow in (data consumer)
|
|
467
|
+
const inFlow = this.#db
|
|
468
|
+
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
469
|
+
JOIN code_entities ce ON ke.to_id = ce.entity_id AND ke.to_type = ce.entity_type
|
|
470
|
+
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
471
|
+
AND ke.relation = 'data_flow'`)
|
|
472
|
+
.get(this.#projectRoot, ...filePaths);
|
|
473
|
+
const out = Number(outFlow?.cnt ?? 0);
|
|
474
|
+
const _in = Number(inFlow?.cnt ?? 0);
|
|
475
|
+
if (out + _in === 0) {
|
|
476
|
+
return signals;
|
|
477
|
+
}
|
|
478
|
+
// 大量产出数据 → model/networking
|
|
479
|
+
if (out > _in * 2) {
|
|
480
|
+
signals.push({
|
|
481
|
+
role: 'model',
|
|
482
|
+
confidence: 0.6,
|
|
483
|
+
weight: WEIGHTS.dataFlow,
|
|
484
|
+
source: 'dataflow-producer',
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
// 大量消费数据 → ui
|
|
488
|
+
if (_in > out * 2) {
|
|
489
|
+
signals.push({
|
|
490
|
+
role: 'ui',
|
|
491
|
+
confidence: 0.5,
|
|
492
|
+
weight: WEIGHTS.dataFlow,
|
|
493
|
+
source: 'dataflow-consumer',
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
return signals;
|
|
497
|
+
}
|
|
498
|
+
/** EntityGraph 拓扑信号: 入度分析/模式检测 */
|
|
499
|
+
#extractTopoSignals(module) {
|
|
500
|
+
const signals = [];
|
|
501
|
+
// 查模块下是否有 singleton / delegate 等设计模式
|
|
502
|
+
const patterns = this.#db
|
|
503
|
+
.prepare(`SELECT ke.to_id as pattern_name FROM knowledge_edges ke
|
|
504
|
+
JOIN code_entities ce ON ke.from_id = ce.entity_id
|
|
505
|
+
WHERE ce.project_root = ? AND ke.relation = 'uses_pattern'
|
|
506
|
+
AND ce.entity_id IN (
|
|
507
|
+
SELECT entity_id FROM code_entities
|
|
508
|
+
WHERE project_root = ? AND file_path IN (${module.files.map(() => '?').join(',')})
|
|
509
|
+
)`)
|
|
510
|
+
.all(this.#projectRoot, this.#projectRoot, ...module.files);
|
|
511
|
+
for (const p of patterns) {
|
|
512
|
+
const name = p.pattern_name?.toLowerCase();
|
|
513
|
+
if (!name) {
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
if (name === 'singleton') {
|
|
517
|
+
signals.push({
|
|
518
|
+
role: 'service',
|
|
519
|
+
confidence: 0.6,
|
|
520
|
+
weight: WEIGHTS.entityGraph,
|
|
521
|
+
source: 'pattern-singleton',
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
if (name === 'delegate') {
|
|
525
|
+
signals.push({
|
|
526
|
+
role: 'ui',
|
|
527
|
+
confidence: 0.4,
|
|
528
|
+
weight: WEIGHTS.entityGraph,
|
|
529
|
+
source: 'pattern-delegate',
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return signals;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
@@ -209,6 +209,8 @@ export class VectorSignal {
|
|
|
209
209
|
export class MultiSignalRanker {
|
|
210
210
|
#signals;
|
|
211
211
|
#scenarioWeights;
|
|
212
|
+
#realtimeWeights = new Map();
|
|
213
|
+
#recentlyUsed = new Set();
|
|
212
214
|
constructor(options = {}) {
|
|
213
215
|
this.#signals = {
|
|
214
216
|
relevance: new RelevanceSignal(),
|
|
@@ -230,6 +232,20 @@ export class MultiSignalRanker {
|
|
|
230
232
|
}
|
|
231
233
|
}
|
|
232
234
|
this.#scenarioWeights = { ...SCENARIO_WEIGHTS, ...remapped };
|
|
235
|
+
// Phase 2: 订阅实时信号更新权重
|
|
236
|
+
if (options.signalBus) {
|
|
237
|
+
options.signalBus.subscribe('quality|usage', (signal) => {
|
|
238
|
+
this.#onSignal(signal);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
#onSignal(signal) {
|
|
243
|
+
if (signal.type === 'quality' && signal.target) {
|
|
244
|
+
this.#realtimeWeights.set(signal.target, signal.value);
|
|
245
|
+
}
|
|
246
|
+
if (signal.type === 'usage' && signal.target) {
|
|
247
|
+
this.#recentlyUsed.add(signal.target);
|
|
248
|
+
}
|
|
233
249
|
}
|
|
234
250
|
/**
|
|
235
251
|
* 对候选列表进行多信号加权排序
|
|
@@ -30,6 +30,7 @@ export declare class SearchEngine {
|
|
|
30
30
|
_indexed: boolean;
|
|
31
31
|
_lastIndexTime: string | null;
|
|
32
32
|
_multiSignalRanker: MultiSignalRanker;
|
|
33
|
+
_signalBus: import('../../infrastructure/signal/SignalBus.js').SignalBus | null;
|
|
33
34
|
aiProvider: SearchAiProvider | null;
|
|
34
35
|
db: SearchDb;
|
|
35
36
|
hybridRetriever: SearchHybridRetriever | null;
|
|
@@ -27,6 +27,7 @@ export class SearchEngine {
|
|
|
27
27
|
_indexed;
|
|
28
28
|
_lastIndexTime = null;
|
|
29
29
|
_multiSignalRanker;
|
|
30
|
+
_signalBus;
|
|
30
31
|
aiProvider;
|
|
31
32
|
db;
|
|
32
33
|
hybridRetriever;
|
|
@@ -51,6 +52,7 @@ export class SearchEngine {
|
|
|
51
52
|
// auto 模式 BM25+semantic 融合权重(可配置)
|
|
52
53
|
this._fusionBm25Weight = options.fusionBm25Weight ?? 0.6;
|
|
53
54
|
this._fusionSemanticWeight = options.fusionSemanticWeight ?? 0.4;
|
|
55
|
+
this._signalBus = options.signalBus || null;
|
|
54
56
|
}
|
|
55
57
|
/** 构建搜索索引 - 从数据库加载所有可搜索实体 */
|
|
56
58
|
buildIndex() {
|
|
@@ -218,6 +220,12 @@ export class SearchEngine {
|
|
|
218
220
|
if (cacheKey) {
|
|
219
221
|
this._setCache(cacheKey, response);
|
|
220
222
|
}
|
|
223
|
+
// ── Signal emission ──
|
|
224
|
+
if (this._signalBus && response.total > 0) {
|
|
225
|
+
this._signalBus.send('search', 'SearchEngine', Math.min(response.total / limit, 1), {
|
|
226
|
+
metadata: { query, mode: actualMode, total: response.total },
|
|
227
|
+
});
|
|
228
|
+
}
|
|
221
229
|
return response;
|
|
222
230
|
}
|
|
223
231
|
// ── Ranking Pipeline ────────────────────────────────────────────
|
|
@@ -416,7 +424,7 @@ export class SearchEngine {
|
|
|
416
424
|
qualityScore: meta.qualityScore || 0,
|
|
417
425
|
};
|
|
418
426
|
});
|
|
419
|
-
// 为每个结果补充 content
|
|
427
|
+
// 为每个结果补充 content(预览需要)— 批量 IN 查询替代 N+1
|
|
420
428
|
this._supplementDetails(items);
|
|
421
429
|
return items;
|
|
422
430
|
}
|
|
@@ -178,6 +178,7 @@ export interface RrfHit {
|
|
|
178
178
|
[key: string]: unknown;
|
|
179
179
|
}
|
|
180
180
|
/** Cross-encoder reranker abstraction */
|
|
181
|
+
import type { SignalBus } from '../../infrastructure/signal/SignalBus.js';
|
|
181
182
|
export interface SearchCrossEncoder {
|
|
182
183
|
rerank(query: string, candidates: SearchResultItem[]): Promise<SearchResultItem[]>;
|
|
183
184
|
}
|
|
@@ -188,6 +189,7 @@ export interface SearchEngineOptions {
|
|
|
188
189
|
vectorService?: SearchVectorService | null;
|
|
189
190
|
hybridRetriever?: SearchHybridRetriever | null;
|
|
190
191
|
crossEncoderReranker?: SearchCrossEncoder | null;
|
|
192
|
+
signalBus?: SignalBus | null;
|
|
191
193
|
cacheMaxAge?: number;
|
|
192
194
|
fusionBm25Weight?: number;
|
|
193
195
|
fusionSemanticWeight?: number;
|