autosnippet 3.3.6 → 3.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
- package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
- package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
- package/dashboard/dist/index.html +3 -3
- package/dist/bin/cli.js +8 -4
- package/dist/lib/agent/AgentRuntime.d.ts +2 -2
- package/dist/lib/agent/AgentRuntime.js +26 -18
- package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
- package/dist/lib/agent/core/LoopContext.d.ts +1 -0
- package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
- package/dist/lib/agent/domain/ChatAgentTasks.js +4 -0
- package/dist/lib/agent/forced-summary.js +7 -2
- package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
- package/dist/lib/agent/memory/ActiveContext.js +0 -2
- package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
- package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
- package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
- package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
- package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
- package/dist/lib/agent/memory/MemoryStore.js +196 -261
- package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
- package/dist/lib/agent/memory/PersistentMemory.js +4 -5
- package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
- package/dist/lib/agent/memory/SessionStore.js +0 -2
- package/dist/lib/agent/tools/ast-graph.js +21 -19
- package/dist/lib/agent/tools/infrastructure.js +3 -2
- package/dist/lib/agent/tools/project-access.d.ts +2 -2
- package/dist/lib/agent/tools/project-access.js +5 -4
- package/dist/lib/bootstrap.js +2 -1
- package/dist/lib/cli/AiScanService.js +8 -21
- package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
- package/dist/lib/cli/KnowledgeSyncService.js +23 -51
- package/dist/lib/core/ast/ProjectGraph.js +5 -27
- package/dist/lib/core/discovery/ConfigWatcher.d.ts +64 -0
- package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +28 -0
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1303 -0
- package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
- package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
- package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
- package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
- package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
- package/dist/lib/core/discovery/index.d.ts +2 -0
- package/dist/lib/core/discovery/index.js +4 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
- package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
- package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
- package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
- package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
- package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
- package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
- package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
- package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
- package/dist/lib/domain/dimension/DimensionSop.js +44 -33
- package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
- package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
- package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +7 -1
- package/dist/lib/domain/knowledge/KnowledgeEntry.js +17 -3
- package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
- package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
- package/dist/lib/domain/knowledge/index.d.ts +2 -1
- package/dist/lib/domain/knowledge/index.js +1 -1
- package/dist/lib/external/ai/AiProvider.d.ts +12 -0
- package/dist/lib/external/ai/AiProvider.js +24 -0
- package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
- package/dist/lib/external/ai/AiProviderManager.js +193 -0
- package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
- package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
- package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
- package/dist/lib/external/ai/providers/MockProvider.js +290 -14
- package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
- package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
- package/dist/lib/external/lark/LarkTransport.js +10 -2
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.d.ts +20 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
- package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -24
- package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
- package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
- package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +9 -0
- package/dist/lib/external/mcp/handlers/bootstrap-external.js +3 -1
- package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
- package/dist/lib/external/mcp/handlers/consolidated.js +2 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +9 -4
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +18 -18
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- package/dist/lib/external/mcp/handlers/knowledge.js +5 -4
- package/dist/lib/external/mcp/handlers/panorama.js +9 -9
- package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
- package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
- package/dist/lib/external/mcp/handlers/search.js +3 -1
- package/dist/lib/external/mcp/handlers/skill.js +4 -4
- package/dist/lib/external/mcp/handlers/structure.js +8 -12
- package/dist/lib/external/mcp/handlers/system.js +10 -34
- package/dist/lib/http/routes/ai.js +109 -30
- package/dist/lib/http/routes/candidates.js +11 -4
- package/dist/lib/http/routes/commands.js +10 -1
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/health.js +11 -0
- package/dist/lib/http/routes/modules.js +27 -0
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +66 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- package/dist/lib/http/utils/routeHelpers.js +2 -1
- package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
- package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
- package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
- package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
- package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
- package/dist/lib/injection/ServiceContainer.d.ts +6 -5
- package/dist/lib/injection/ServiceContainer.js +18 -31
- package/dist/lib/injection/ServiceMap.d.ts +22 -0
- package/dist/lib/injection/modules/AiModule.d.ts +6 -9
- package/dist/lib/injection/modules/AiModule.js +82 -39
- package/dist/lib/injection/modules/AppModule.js +2 -1
- package/dist/lib/injection/modules/GuardModule.js +5 -5
- package/dist/lib/injection/modules/InfraModule.js +60 -0
- package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
- package/dist/lib/injection/modules/PanoramaModule.js +16 -10
- package/dist/lib/injection/modules/VectorModule.js +3 -0
- package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
- package/dist/lib/repository/audit/AuditRepository.js +272 -0
- package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
- package/dist/lib/repository/base/RepositoryBase.js +32 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
- package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
- package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
- package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
- package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
- package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
- package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
- package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
- package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
- package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
- package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
- package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
- package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
- package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
- package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
- package/dist/lib/repository/memory/MemoryRepository.js +260 -0
- package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
- package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
- package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
- package/dist/lib/repository/session/SessionRepository.js +110 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
- package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
- package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
- package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
- package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
- package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
- package/dist/lib/service/cleanup/CleanupService.d.ts +54 -7
- package/dist/lib/service/cleanup/CleanupService.js +291 -40
- package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
- package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
- package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
- package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
- package/dist/lib/service/evolution/ContentPatcher.js +48 -19
- package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
- package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
- package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
- package/dist/lib/service/evolution/DecayDetector.js +63 -57
- package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
- package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
- package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
- package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
- package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
- package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
- package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
- package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
- package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
- package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
- package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
- package/dist/lib/service/evolution/StagingManager.js +37 -95
- package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
- package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
- package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
- package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
- package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
- package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
- package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
- package/dist/lib/service/guard/ReverseGuard.js +21 -31
- package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
- package/dist/lib/service/guard/ViolationsStore.js +75 -69
- package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +45 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -496
- package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
- package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
- package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
- package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
- package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
- package/dist/lib/service/knowledge/KnowledgeService.js +97 -46
- package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
- package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
- package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
- package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
- package/dist/lib/service/module/ModuleService.js +10 -19
- package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +14 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +137 -32
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +94 -33
- package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
- package/dist/lib/service/panorama/LayerInferrer.js +118 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +14 -4
- package/dist/lib/service/panorama/ModuleDiscoverer.js +209 -61
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +15 -4
- package/dist/lib/service/panorama/PanoramaAggregator.js +128 -62
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +60 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +49 -69
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +41 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +10 -5
- package/dist/lib/service/panorama/RoleRefiner.js +92 -282
- package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
- package/dist/lib/service/panorama/TechStackProfiler.js +79 -0
- package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
- package/dist/lib/service/quality/QualityScorer.js +157 -83
- package/dist/lib/service/search/SearchEngine.d.ts +1 -0
- package/dist/lib/service/search/SearchEngine.js +32 -37
- package/dist/lib/service/signal/HitRecorder.js +5 -5
- package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
- package/dist/lib/service/skills/SignalCollector.d.ts +6 -8
- package/dist/lib/service/skills/SignalCollector.js +34 -60
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
- package/dist/lib/service/vector/ContextualEnricher.js +4 -0
- package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
- package/dist/lib/service/vector/SyncCoordinator.js +25 -3
- package/dist/lib/service/vector/VectorService.d.ts +2 -0
- package/dist/lib/service/vector/VectorService.js +3 -0
- package/dist/lib/service/wiki/WikiGenerator.js +1 -1
- package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
- package/dist/lib/shared/LanguageProfiles.js +939 -0
- package/dist/lib/shared/LanguageService.d.ts +6 -0
- package/dist/lib/shared/LanguageService.js +19 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/developer-identity.d.ts +18 -0
- package/dist/lib/shared/developer-identity.js +62 -0
- package/dist/lib/shared/schemas/http-requests.d.ts +8 -17
- package/dist/lib/shared/schemas/http-requests.js +9 -6
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- package/dist/lib/types/knowledge-wire.d.ts +1 -0
- package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
- package/dist/lib/types/project-snapshot-builder.js +0 -1
- package/dist/lib/types/project-snapshot.d.ts +0 -1
- package/dist/lib/types/project-snapshot.js +0 -1
- package/dist/lib/types/snapshot-views.d.ts +0 -2
- package/dist/lib/types/snapshot-views.js +0 -1
- package/package.json +2 -1
- package/dashboard/dist/assets/icons-D1aVZYFW.js +0 -1
- package/dashboard/dist/assets/index-CxHOu8Hd.css +0 -1
- package/dashboard/dist/assets/index-DDdAOpYT.js +0 -128
- package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
- package/dist/lib/repository/base/BaseRepository.js +0 -226
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* @module RoleRefiner
|
|
15
15
|
*/
|
|
16
|
+
import { LanguageProfiles } from '#shared/LanguageProfiles.js';
|
|
16
17
|
/* ═══ Constants ═══════════════════════════════════════════ */
|
|
17
18
|
const WEIGHTS = {
|
|
18
19
|
ast: 0.3,
|
|
@@ -21,252 +22,109 @@ const WEIGHTS = {
|
|
|
21
22
|
entityGraph: 0.1,
|
|
22
23
|
regex: 0.15,
|
|
23
24
|
};
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
],
|
|
25
|
+
/**
|
|
26
|
+
* 配置文件层级名 → 模块角色映射
|
|
27
|
+
* 当配置文件声明了层级时(如 Boxfile 的 layer),
|
|
28
|
+
* 层级名是判断模块角色的强信号
|
|
29
|
+
*/
|
|
30
|
+
const CONFIG_LAYER_TO_ROLE = {
|
|
31
|
+
vendors: 'utility',
|
|
32
|
+
vendor: 'utility',
|
|
33
|
+
basics: 'core',
|
|
34
|
+
basic: 'core',
|
|
35
|
+
foundation: 'core',
|
|
36
|
+
core: 'core',
|
|
37
|
+
services: 'service',
|
|
38
|
+
service: 'service',
|
|
39
|
+
components: 'feature',
|
|
40
|
+
component: 'feature',
|
|
41
|
+
accessories: 'feature',
|
|
42
|
+
accessory: 'feature',
|
|
43
|
+
underlays: 'feature',
|
|
44
|
+
application: 'app',
|
|
45
|
+
app: 'app',
|
|
46
|
+
ui: 'ui',
|
|
47
|
+
networking: 'networking',
|
|
48
|
+
network: 'networking',
|
|
49
|
+
storage: 'storage',
|
|
50
|
+
model: 'model',
|
|
51
|
+
test: 'test',
|
|
52
|
+
tests: 'test',
|
|
183
53
|
};
|
|
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
54
|
/* ═══ RoleRefiner Class ═══════════════════════════════════ */
|
|
191
55
|
export class RoleRefiner {
|
|
192
|
-
#
|
|
56
|
+
#bootstrapRepo;
|
|
57
|
+
#entityRepo;
|
|
58
|
+
#edgeRepo;
|
|
193
59
|
#projectRoot;
|
|
194
60
|
#families = null;
|
|
195
61
|
#superclassMap = null;
|
|
196
62
|
#protocolMap = null;
|
|
197
63
|
#importPatterns = null;
|
|
198
|
-
constructor(
|
|
199
|
-
this.#
|
|
64
|
+
constructor(bootstrapRepo, entityRepo, edgeRepo, projectRoot) {
|
|
65
|
+
this.#bootstrapRepo = bootstrapRepo;
|
|
66
|
+
this.#entityRepo = entityRepo;
|
|
67
|
+
this.#edgeRepo = edgeRepo;
|
|
200
68
|
this.#projectRoot = projectRoot;
|
|
201
69
|
}
|
|
202
70
|
/** 检测项目语言族,基于 bootstrap_snapshots.primary_lang */
|
|
203
|
-
#detectFamilies() {
|
|
71
|
+
async #detectFamilies() {
|
|
204
72
|
if (this.#families) {
|
|
205
73
|
return this.#families;
|
|
206
74
|
}
|
|
207
|
-
const
|
|
208
|
-
|
|
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
|
-
}
|
|
75
|
+
const primaryLang = await this.#bootstrapRepo.getLatestPrimaryLang(this.#projectRoot);
|
|
76
|
+
this.#families = LanguageProfiles.resolveFamilies(primaryLang);
|
|
219
77
|
return this.#families;
|
|
220
78
|
}
|
|
221
79
|
/** 构建当前项目语言族的超类合并映射 */
|
|
222
|
-
#getSuperclassMap() {
|
|
80
|
+
async #getSuperclassMap() {
|
|
223
81
|
if (this.#superclassMap) {
|
|
224
82
|
return this.#superclassMap;
|
|
225
83
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
Object.assign(merged, SUPERCLASS_BY_FAMILY[fam]);
|
|
229
|
-
}
|
|
230
|
-
this.#superclassMap = merged;
|
|
231
|
-
return merged;
|
|
84
|
+
this.#superclassMap = LanguageProfiles.superclassRoles(await this.#detectFamilies());
|
|
85
|
+
return this.#superclassMap;
|
|
232
86
|
}
|
|
233
87
|
/** 构建当前项目语言族的协议合并映射 */
|
|
234
|
-
#getProtocolMap() {
|
|
88
|
+
async #getProtocolMap() {
|
|
235
89
|
if (this.#protocolMap) {
|
|
236
90
|
return this.#protocolMap;
|
|
237
91
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
Object.assign(merged, PROTOCOL_BY_FAMILY[fam]);
|
|
241
|
-
}
|
|
242
|
-
this.#protocolMap = merged;
|
|
243
|
-
return merged;
|
|
92
|
+
this.#protocolMap = LanguageProfiles.protocolRoles(await this.#detectFamilies());
|
|
93
|
+
return this.#protocolMap;
|
|
244
94
|
}
|
|
245
95
|
/** 构建当前项目语言族的 import 模式列表 */
|
|
246
|
-
#getImportPatterns() {
|
|
96
|
+
async #getImportPatterns() {
|
|
247
97
|
if (this.#importPatterns) {
|
|
248
98
|
return this.#importPatterns;
|
|
249
99
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
patterns.push(...IMPORT_PATTERNS_BY_FAMILY[fam]);
|
|
253
|
-
}
|
|
254
|
-
this.#importPatterns = patterns;
|
|
255
|
-
return patterns;
|
|
100
|
+
this.#importPatterns = LanguageProfiles.importRolePatterns(await this.#detectFamilies());
|
|
101
|
+
return this.#importPatterns;
|
|
256
102
|
}
|
|
257
103
|
/**
|
|
258
104
|
* 精化单个模块的角色
|
|
259
105
|
*/
|
|
260
|
-
refineRole(module) {
|
|
106
|
+
async refineRole(module) {
|
|
261
107
|
const signals = [];
|
|
262
108
|
// 1. AST 结构信号 (0.30)
|
|
263
|
-
signals.push(...this.#extractAstSignals(module));
|
|
109
|
+
signals.push(...(await this.#extractAstSignals(module)));
|
|
264
110
|
// 2. CallGraph 行为信号 (0.30)
|
|
265
|
-
signals.push(...this.#extractCallSignals(module));
|
|
111
|
+
signals.push(...(await this.#extractCallSignals(module)));
|
|
266
112
|
// 3. DataFlow 数据流信号 (0.15)
|
|
267
|
-
signals.push(...this.#extractFlowSignals(module));
|
|
113
|
+
signals.push(...(await this.#extractFlowSignals(module)));
|
|
268
114
|
// 4. EntityGraph 拓扑信号 (0.10)
|
|
269
|
-
signals.push(...this.#extractTopoSignals(module));
|
|
115
|
+
signals.push(...(await this.#extractTopoSignals(module)));
|
|
116
|
+
// 4.5. 配置层级信号 — 来自 Boxfile/Tuist 等配置文件的 layer 声明
|
|
117
|
+
if (module.configLayer) {
|
|
118
|
+
const layerRole = CONFIG_LAYER_TO_ROLE[module.configLayer.toLowerCase()];
|
|
119
|
+
if (layerRole) {
|
|
120
|
+
signals.push({
|
|
121
|
+
role: layerRole,
|
|
122
|
+
confidence: 0.85,
|
|
123
|
+
weight: WEIGHTS.ast, // 与 AST 等权重级别 (0.30)
|
|
124
|
+
source: 'config-layer',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
270
128
|
// 5. 正则基线 (0.15)
|
|
271
129
|
signals.push({
|
|
272
130
|
role: module.inferredRole,
|
|
@@ -318,31 +176,26 @@ export class RoleRefiner {
|
|
|
318
176
|
/**
|
|
319
177
|
* 批量精化所有模块
|
|
320
178
|
*/
|
|
321
|
-
refineAll(modules) {
|
|
179
|
+
async refineAll(modules) {
|
|
322
180
|
const result = new Map();
|
|
323
181
|
for (const m of modules) {
|
|
324
|
-
result.set(m.name, this.refineRole(m));
|
|
182
|
+
result.set(m.name, await this.refineRole(m));
|
|
325
183
|
}
|
|
326
184
|
return result;
|
|
327
185
|
}
|
|
328
186
|
/* ─── Signal Extractors ──────────────────────────── */
|
|
329
187
|
/** AST 结构信号: 继承链、协议、import */
|
|
330
|
-
#extractAstSignals(module) {
|
|
188
|
+
async #extractAstSignals(module) {
|
|
331
189
|
const signals = [];
|
|
332
190
|
const filePaths = module.files;
|
|
333
191
|
if (filePaths.length === 0) {
|
|
334
192
|
return signals;
|
|
335
193
|
}
|
|
336
194
|
// 查询模块内实体的继承关系
|
|
337
|
-
const
|
|
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);
|
|
195
|
+
const entities = await this.#entityRepo.findByProjectAndFilePaths(this.#projectRoot, filePaths);
|
|
343
196
|
const roleCounts = {};
|
|
344
|
-
const superclassMap = this.#getSuperclassMap();
|
|
345
|
-
const protocolMap = this.#getProtocolMap();
|
|
197
|
+
const superclassMap = await this.#getSuperclassMap();
|
|
198
|
+
const protocolMap = await this.#getProtocolMap();
|
|
346
199
|
for (const entity of entities) {
|
|
347
200
|
// 继承链推断
|
|
348
201
|
const superclass = entity.superclass;
|
|
@@ -351,27 +204,19 @@ export class RoleRefiner {
|
|
|
351
204
|
roleCounts[role] = (roleCounts[role] ?? 0) + 1;
|
|
352
205
|
}
|
|
353
206
|
// 协议推断
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
roleCounts[role] = (roleCounts[role] ?? 0) + 0.5;
|
|
360
|
-
}
|
|
207
|
+
const protocols = entity.protocols ?? [];
|
|
208
|
+
for (const proto of protocols) {
|
|
209
|
+
if (protocolMap[proto]) {
|
|
210
|
+
const role = protocolMap[proto];
|
|
211
|
+
roleCounts[role] = (roleCounts[role] ?? 0) + 0.5;
|
|
361
212
|
}
|
|
362
213
|
}
|
|
363
|
-
catch {
|
|
364
|
-
// ignore malformed JSON
|
|
365
|
-
}
|
|
366
214
|
}
|
|
367
215
|
// import 模式推断
|
|
368
|
-
const imports = this.#
|
|
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);
|
|
216
|
+
const imports = await this.#edgeRepo.findOutgoingByRelation(module.name, 'depends_on');
|
|
372
217
|
for (const imp of imports) {
|
|
373
|
-
const depName = imp.
|
|
374
|
-
for (const pat of this.#getImportPatterns()) {
|
|
218
|
+
const depName = imp.toId.toLowerCase();
|
|
219
|
+
for (const pat of await this.#getImportPatterns()) {
|
|
375
220
|
if (pat.regex.test(depName)) {
|
|
376
221
|
roleCounts[pat.role] = (roleCounts[pat.role] ?? 0) + 0.5;
|
|
377
222
|
}
|
|
@@ -392,30 +237,16 @@ export class RoleRefiner {
|
|
|
392
237
|
return signals;
|
|
393
238
|
}
|
|
394
239
|
/** CallGraph 行为信号: 调用流向分析 */
|
|
395
|
-
#extractCallSignals(module) {
|
|
240
|
+
async #extractCallSignals(module) {
|
|
396
241
|
const signals = [];
|
|
397
|
-
// 查模块实体的 call edge 统计
|
|
398
242
|
const filePaths = module.files;
|
|
399
243
|
if (filePaths.length === 0) {
|
|
400
244
|
return signals;
|
|
401
245
|
}
|
|
402
|
-
const placeholders = filePaths.map(() => '?').join(',');
|
|
403
246
|
// fan-out: 模块内实体调用外部
|
|
404
|
-
const
|
|
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);
|
|
247
|
+
const fanOut = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'calls', 'from');
|
|
410
248
|
// fan-in: 外部调用模块内实体
|
|
411
|
-
const
|
|
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);
|
|
249
|
+
const fanIn = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'calls', 'to');
|
|
419
250
|
if (fanIn + fanOut === 0) {
|
|
420
251
|
return signals;
|
|
421
252
|
}
|
|
@@ -449,29 +280,16 @@ export class RoleRefiner {
|
|
|
449
280
|
return signals;
|
|
450
281
|
}
|
|
451
282
|
/** DataFlow 数据流信号: 源/汇分析 */
|
|
452
|
-
#extractFlowSignals(module) {
|
|
283
|
+
async #extractFlowSignals(module) {
|
|
453
284
|
const signals = [];
|
|
454
285
|
const filePaths = module.files;
|
|
455
286
|
if (filePaths.length === 0) {
|
|
456
287
|
return signals;
|
|
457
288
|
}
|
|
458
|
-
const placeholders = filePaths.map(() => '?').join(',');
|
|
459
289
|
// data_flow out (data producer)
|
|
460
|
-
const
|
|
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);
|
|
290
|
+
const out = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'data_flow', 'from');
|
|
466
291
|
// data_flow in (data consumer)
|
|
467
|
-
const
|
|
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);
|
|
292
|
+
const _in = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'data_flow', 'to');
|
|
475
293
|
if (out + _in === 0) {
|
|
476
294
|
return signals;
|
|
477
295
|
}
|
|
@@ -496,24 +314,16 @@ export class RoleRefiner {
|
|
|
496
314
|
return signals;
|
|
497
315
|
}
|
|
498
316
|
/** EntityGraph 拓扑信号: 入度分析/模式检测 */
|
|
499
|
-
#extractTopoSignals(module) {
|
|
317
|
+
async #extractTopoSignals(module) {
|
|
500
318
|
const signals = [];
|
|
501
319
|
// 查模块下是否有 singleton / delegate 等设计模式
|
|
502
|
-
const patterns = this.#
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
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) {
|
|
320
|
+
const patterns = await this.#edgeRepo.findPatternsUsedByEntities(this.#projectRoot, module.files);
|
|
321
|
+
for (const name of patterns) {
|
|
322
|
+
const lowerName = name?.toLowerCase();
|
|
323
|
+
if (!lowerName) {
|
|
514
324
|
continue;
|
|
515
325
|
}
|
|
516
|
-
if (
|
|
326
|
+
if (lowerName === 'singleton') {
|
|
517
327
|
signals.push({
|
|
518
328
|
role: 'service',
|
|
519
329
|
confidence: 0.6,
|
|
@@ -521,7 +331,7 @@ export class RoleRefiner {
|
|
|
521
331
|
source: 'pattern-singleton',
|
|
522
332
|
});
|
|
523
333
|
}
|
|
524
|
-
if (
|
|
334
|
+
if (lowerName === 'delegate') {
|
|
525
335
|
signals.push({
|
|
526
336
|
role: 'ui',
|
|
527
337
|
confidence: 0.4,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TechStackProfiler — 技术栈画像聚合
|
|
3
|
+
*
|
|
4
|
+
* 根据外部依赖名称自动分类,生成项目技术栈画像。
|
|
5
|
+
* 使用已知库名映射表 + 关键词启发式进行分类。
|
|
6
|
+
*
|
|
7
|
+
* @module TechStackProfiler
|
|
8
|
+
*/
|
|
9
|
+
import type { ExternalDepProfile, TechStackProfile } from './PanoramaTypes.js';
|
|
10
|
+
/**
|
|
11
|
+
* 对外部依赖进行分类,生成技术栈画像
|
|
12
|
+
*/
|
|
13
|
+
export declare function profileTechStack(externalDeps: ExternalDepProfile[]): TechStackProfile;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TechStackProfiler — 技术栈画像聚合
|
|
3
|
+
*
|
|
4
|
+
* 根据外部依赖名称自动分类,生成项目技术栈画像。
|
|
5
|
+
* 使用已知库名映射表 + 关键词启发式进行分类。
|
|
6
|
+
*
|
|
7
|
+
* @module TechStackProfiler
|
|
8
|
+
*/
|
|
9
|
+
import { LanguageProfiles } from '#shared/LanguageProfiles.js';
|
|
10
|
+
/* ═══ TechStackProfiler ═══════════════════════════════════ */
|
|
11
|
+
/** Fan-in 阈值:高于此值视为关键依赖热点 */
|
|
12
|
+
const HOTSPOT_THRESHOLD = 3;
|
|
13
|
+
/**
|
|
14
|
+
* 对外部依赖进行分类,生成技术栈画像
|
|
15
|
+
*/
|
|
16
|
+
export function profileTechStack(externalDeps) {
|
|
17
|
+
if (externalDeps.length === 0) {
|
|
18
|
+
return { categories: [], hotspots: [], totalExternalDeps: 0 };
|
|
19
|
+
}
|
|
20
|
+
// 1. 分类每个外部依赖
|
|
21
|
+
const categoryMap = new Map();
|
|
22
|
+
for (const dep of externalDeps) {
|
|
23
|
+
const category = classifyDependency(dep.name);
|
|
24
|
+
dep.category = category;
|
|
25
|
+
if (!categoryMap.has(category)) {
|
|
26
|
+
categoryMap.set(category, []);
|
|
27
|
+
}
|
|
28
|
+
categoryMap.get(category).push({
|
|
29
|
+
name: dep.name,
|
|
30
|
+
fanIn: dep.fanIn,
|
|
31
|
+
version: dep.version,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
// 2. 按分类排序(每个分类内按 fan-in 降序,分类间按依赖数降序)
|
|
35
|
+
const categories = [...categoryMap.entries()]
|
|
36
|
+
.map(([name, deps]) => ({
|
|
37
|
+
name,
|
|
38
|
+
deps: deps.sort((a, b) => b.fanIn - a.fanIn),
|
|
39
|
+
}))
|
|
40
|
+
.sort((a, b) => b.deps.length - a.deps.length);
|
|
41
|
+
// 3. 提取热点(fan-in ≥ 阈值)
|
|
42
|
+
const hotspots = externalDeps
|
|
43
|
+
.filter((d) => d.fanIn >= HOTSPOT_THRESHOLD)
|
|
44
|
+
.map((d) => ({ name: d.name, fanIn: d.fanIn, dependedBy: d.dependedBy }))
|
|
45
|
+
.sort((a, b) => b.fanIn - a.fanIn);
|
|
46
|
+
return {
|
|
47
|
+
categories,
|
|
48
|
+
hotspots,
|
|
49
|
+
totalExternalDeps: externalDeps.length,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 分类单个外部依赖
|
|
54
|
+
*/
|
|
55
|
+
function classifyDependency(name) {
|
|
56
|
+
const knownLibraries = LanguageProfiles.knownLibraries;
|
|
57
|
+
// 标准化名称:移除前缀、转小写
|
|
58
|
+
const normalized = name
|
|
59
|
+
.replace(/^(BDMV|BDP|FMT|BD|MTL|Bai|Ali|TX|TT)/, '')
|
|
60
|
+
.toLowerCase()
|
|
61
|
+
.replace(/[-_]/g, '');
|
|
62
|
+
// 1. 精确匹配已知库
|
|
63
|
+
if (knownLibraries[normalized]) {
|
|
64
|
+
return knownLibraries[normalized];
|
|
65
|
+
}
|
|
66
|
+
// 尝试原始名称小写
|
|
67
|
+
const rawLower = name.toLowerCase().replace(/[-_]/g, '');
|
|
68
|
+
if (knownLibraries[rawLower]) {
|
|
69
|
+
return knownLibraries[rawLower];
|
|
70
|
+
}
|
|
71
|
+
// 2. 关键词启发式
|
|
72
|
+
for (const [pattern, category] of LanguageProfiles.keywordCategories) {
|
|
73
|
+
if (pattern.test(name)) {
|
|
74
|
+
return category;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// 3. 默认分类
|
|
78
|
+
return 'Other';
|
|
79
|
+
}
|