autosnippet 3.3.7 → 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 +7 -4
- 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/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 +4 -17
- 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/CustomConfigDiscoverer.d.ts +0 -2
- package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
- 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/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/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/orchestrator.js +33 -16
- 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.js +1 -1
- package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
- package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
- package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
- package/dist/lib/external/mcp/handlers/guard.js +15 -24
- 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 +11 -13
- package/dist/lib/http/routes/guardReport.js +3 -5
- package/dist/lib/http/routes/panorama.js +12 -12
- package/dist/lib/http/routes/recipes.js +59 -8
- package/dist/lib/http/routes/remote.js +3 -13
- package/dist/lib/http/routes/search.js +11 -8
- 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.js +7 -4
- package/dist/lib/injection/ServiceMap.d.ts +20 -0
- 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.js +8 -4
- 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 +39 -63
- package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
- 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 +76 -38
- 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/panorama/CouplingAnalyzer.d.ts +5 -3
- package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
- package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
- package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
- package/dist/lib/service/panorama/LayerInferrer.js +1 -1
- package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
- package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
- package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
- package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
- package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
- package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
- package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
- package/dist/lib/service/panorama/PanoramaService.js +41 -66
- package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
- package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
- package/dist/lib/service/panorama/RoleRefiner.js +52 -283
- package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
- 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 +5 -8
- package/dist/lib/service/skills/SignalCollector.js +28 -55
- package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
- package/dist/lib/service/skills/SkillAdvisor.js +30 -79
- 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 +16 -0
- package/dist/lib/shared/constants.d.ts +19 -19
- package/dist/lib/shared/constants.js +10 -10
- package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
- 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-FHns2ypa.js +0 -1
- package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
- package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
- 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,
|
|
@@ -50,252 +51,68 @@ const CONFIG_LAYER_TO_ROLE = {
|
|
|
50
51
|
test: 'test',
|
|
51
52
|
tests: 'test',
|
|
52
53
|
};
|
|
53
|
-
/** primary_lang / LanguageService 输出 → 语言族 */
|
|
54
|
-
const LANG_TO_FAMILY = {
|
|
55
|
-
swift: 'apple',
|
|
56
|
-
objectivec: 'apple',
|
|
57
|
-
java: 'jvm',
|
|
58
|
-
kotlin: 'jvm',
|
|
59
|
-
dart: 'dart',
|
|
60
|
-
python: 'python',
|
|
61
|
-
typescript: 'web',
|
|
62
|
-
javascript: 'web',
|
|
63
|
-
tsx: 'web',
|
|
64
|
-
go: 'go',
|
|
65
|
-
rust: 'rust',
|
|
66
|
-
};
|
|
67
|
-
/* ─── 按语言族分区的超类映射 ─────────────────────────────── */
|
|
68
|
-
const SUPERCLASS_BY_FAMILY = {
|
|
69
|
-
apple: {
|
|
70
|
-
UIViewController: 'ui',
|
|
71
|
-
UIView: 'ui',
|
|
72
|
-
UITableViewCell: 'ui',
|
|
73
|
-
UICollectionViewCell: 'ui',
|
|
74
|
-
UINavigationController: 'routing',
|
|
75
|
-
UITabBarController: 'routing',
|
|
76
|
-
UIApplication: 'app',
|
|
77
|
-
NSObject: 'core',
|
|
78
|
-
NSManagedObject: 'storage',
|
|
79
|
-
},
|
|
80
|
-
jvm: {
|
|
81
|
-
Activity: 'ui',
|
|
82
|
-
AppCompatActivity: 'ui',
|
|
83
|
-
Fragment: 'ui',
|
|
84
|
-
DialogFragment: 'ui',
|
|
85
|
-
View: 'ui',
|
|
86
|
-
RecyclerViewAdapter: 'ui',
|
|
87
|
-
Service: 'service',
|
|
88
|
-
IntentService: 'service',
|
|
89
|
-
BroadcastReceiver: 'service',
|
|
90
|
-
ContentProvider: 'storage',
|
|
91
|
-
ViewModel: 'ui',
|
|
92
|
-
AndroidViewModel: 'ui',
|
|
93
|
-
Application: 'app',
|
|
94
|
-
},
|
|
95
|
-
dart: {
|
|
96
|
-
StatefulWidget: 'ui',
|
|
97
|
-
StatelessWidget: 'ui',
|
|
98
|
-
State: 'ui',
|
|
99
|
-
ChangeNotifier: 'service',
|
|
100
|
-
Cubit: 'service',
|
|
101
|
-
Bloc: 'service',
|
|
102
|
-
},
|
|
103
|
-
python: {
|
|
104
|
-
BaseModel: 'model',
|
|
105
|
-
Model: 'model',
|
|
106
|
-
APIView: 'service',
|
|
107
|
-
ViewSet: 'service',
|
|
108
|
-
TestCase: 'test',
|
|
109
|
-
},
|
|
110
|
-
web: {
|
|
111
|
-
Component: 'ui',
|
|
112
|
-
Controller: 'service',
|
|
113
|
-
Module: 'app',
|
|
114
|
-
},
|
|
115
|
-
go: {},
|
|
116
|
-
rust: {},
|
|
117
|
-
};
|
|
118
|
-
/* ─── 按语言族分区的协议/接口映射 ────────────────────────── */
|
|
119
|
-
const PROTOCOL_BY_FAMILY = {
|
|
120
|
-
apple: {
|
|
121
|
-
UITableViewDataSource: 'ui',
|
|
122
|
-
UITableViewDelegate: 'ui',
|
|
123
|
-
UICollectionViewDataSource: 'ui',
|
|
124
|
-
UIApplicationDelegate: 'app',
|
|
125
|
-
UISceneDelegate: 'app',
|
|
126
|
-
UIWindowSceneDelegate: 'app',
|
|
127
|
-
URLSessionDelegate: 'networking',
|
|
128
|
-
Codable: 'model',
|
|
129
|
-
Decodable: 'model',
|
|
130
|
-
Encodable: 'model',
|
|
131
|
-
},
|
|
132
|
-
jvm: {
|
|
133
|
-
Serializable: 'model',
|
|
134
|
-
Parcelable: 'model',
|
|
135
|
-
Runnable: 'core',
|
|
136
|
-
Callable: 'core',
|
|
137
|
-
OnClickListener: 'ui',
|
|
138
|
-
Adapter: 'ui',
|
|
139
|
-
Repository: 'storage',
|
|
140
|
-
},
|
|
141
|
-
dart: {
|
|
142
|
-
Widget: 'ui',
|
|
143
|
-
},
|
|
144
|
-
web: {
|
|
145
|
-
OnInit: 'ui',
|
|
146
|
-
OnDestroy: 'ui',
|
|
147
|
-
CanActivate: 'routing',
|
|
148
|
-
NestMiddleware: 'service',
|
|
149
|
-
},
|
|
150
|
-
go: {
|
|
151
|
-
Handler: 'service',
|
|
152
|
-
ReadWriter: 'core',
|
|
153
|
-
Reader: 'core',
|
|
154
|
-
Writer: 'core',
|
|
155
|
-
Stringer: 'utility',
|
|
156
|
-
},
|
|
157
|
-
rust: {
|
|
158
|
-
Display: 'utility',
|
|
159
|
-
Debug: 'utility',
|
|
160
|
-
Serialize: 'model',
|
|
161
|
-
Deserialize: 'model',
|
|
162
|
-
Future: 'core',
|
|
163
|
-
Stream: 'core',
|
|
164
|
-
Service: 'service',
|
|
165
|
-
},
|
|
166
|
-
python: {},
|
|
167
|
-
};
|
|
168
|
-
const IMPORT_PATTERNS_BY_FAMILY = {
|
|
169
|
-
apple: [
|
|
170
|
-
{ regex: /alamofire|urlsession|afnetworking|moya/i, role: 'networking' },
|
|
171
|
-
{ regex: /\buikit\b|swiftui|rx.*cocoa|snapkit|masonry/i, role: 'ui' },
|
|
172
|
-
{ regex: /realm|coredata|fmdb|grdb/i, role: 'storage' },
|
|
173
|
-
{ regex: /xctest/i, role: 'test' },
|
|
174
|
-
],
|
|
175
|
-
jvm: [
|
|
176
|
-
{ regex: /retrofit|okhttp|volley/i, role: 'networking' },
|
|
177
|
-
{ regex: /android\.widget|jetpack.*compose|recyclerview/i, role: 'ui' },
|
|
178
|
-
{ regex: /room|hibernate|greendao/i, role: 'storage' },
|
|
179
|
-
{ regex: /junit|espresso|mockito/i, role: 'test' },
|
|
180
|
-
],
|
|
181
|
-
dart: [
|
|
182
|
-
{ regex: /\bdio\b|http_client/i, role: 'networking' },
|
|
183
|
-
{ regex: /flutter|cupertino|material/i, role: 'ui' },
|
|
184
|
-
{ regex: /sqflite|hive|objectbox/i, role: 'storage' },
|
|
185
|
-
{ regex: /flutter_test/i, role: 'test' },
|
|
186
|
-
],
|
|
187
|
-
python: [
|
|
188
|
-
{ regex: /requests|aiohttp|httpx|urllib/i, role: 'networking' },
|
|
189
|
-
{ regex: /tkinter|pyqt|kivy/i, role: 'ui' },
|
|
190
|
-
{ regex: /sqlalchemy|django\.db|peewee|tortoise/i, role: 'storage' },
|
|
191
|
-
{ regex: /pytest|unittest/i, role: 'test' },
|
|
192
|
-
],
|
|
193
|
-
web: [
|
|
194
|
-
{ regex: /axios|fetch|got|superagent/i, role: 'networking' },
|
|
195
|
-
{ regex: /react|angular|vue|svelte|next|nuxt/i, role: 'ui' },
|
|
196
|
-
{ regex: /typeorm|prisma|sequelize|mongoose|knex/i, role: 'storage' },
|
|
197
|
-
{ regex: /jest|mocha|vitest|cypress|playwright/i, role: 'test' },
|
|
198
|
-
{ regex: /express|fastify|nestjs|koa/i, role: 'routing' },
|
|
199
|
-
],
|
|
200
|
-
go: [
|
|
201
|
-
{ regex: /net\/http|resty/i, role: 'networking' },
|
|
202
|
-
{ regex: /gin|echo|fiber|mux|chi/i, role: 'routing' },
|
|
203
|
-
{ regex: /gorm|sqlx|ent/i, role: 'storage' },
|
|
204
|
-
{ regex: /testing/i, role: 'test' },
|
|
205
|
-
],
|
|
206
|
-
rust: [
|
|
207
|
-
{ regex: /reqwest|hyper|surf/i, role: 'networking' },
|
|
208
|
-
{ regex: /actix|axum|warp|rocket/i, role: 'routing' },
|
|
209
|
-
{ regex: /diesel|sqlx|sea-orm/i, role: 'storage' },
|
|
210
|
-
{ regex: /tokio-test/i, role: 'test' },
|
|
211
|
-
],
|
|
212
|
-
};
|
|
213
|
-
/** 通用 import 模式(任何语言都适用) */
|
|
214
|
-
const UNIVERSAL_IMPORT_PATTERNS = [
|
|
215
|
-
{ regex: /network/i, role: 'networking' },
|
|
216
|
-
{ regex: /sqlite/i, role: 'storage' },
|
|
217
|
-
{ regex: /router|routing|navigation/i, role: 'routing' },
|
|
218
|
-
];
|
|
219
54
|
/* ═══ RoleRefiner Class ═══════════════════════════════════ */
|
|
220
55
|
export class RoleRefiner {
|
|
221
|
-
#
|
|
56
|
+
#bootstrapRepo;
|
|
57
|
+
#entityRepo;
|
|
58
|
+
#edgeRepo;
|
|
222
59
|
#projectRoot;
|
|
223
60
|
#families = null;
|
|
224
61
|
#superclassMap = null;
|
|
225
62
|
#protocolMap = null;
|
|
226
63
|
#importPatterns = null;
|
|
227
|
-
constructor(
|
|
228
|
-
this.#
|
|
64
|
+
constructor(bootstrapRepo, entityRepo, edgeRepo, projectRoot) {
|
|
65
|
+
this.#bootstrapRepo = bootstrapRepo;
|
|
66
|
+
this.#entityRepo = entityRepo;
|
|
67
|
+
this.#edgeRepo = edgeRepo;
|
|
229
68
|
this.#projectRoot = projectRoot;
|
|
230
69
|
}
|
|
231
70
|
/** 检测项目语言族,基于 bootstrap_snapshots.primary_lang */
|
|
232
|
-
#detectFamilies() {
|
|
71
|
+
async #detectFamilies() {
|
|
233
72
|
if (this.#families) {
|
|
234
73
|
return this.#families;
|
|
235
74
|
}
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
WHERE project_root = ? ORDER BY created_at DESC LIMIT 1`)
|
|
239
|
-
.get(this.#projectRoot);
|
|
240
|
-
const primaryLang = row?.primary_lang;
|
|
241
|
-
if (primaryLang && LANG_TO_FAMILY[primaryLang]) {
|
|
242
|
-
this.#families = [LANG_TO_FAMILY[primaryLang]];
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
// 无 bootstrap 数据时回退:使用所有语言族
|
|
246
|
-
this.#families = Object.keys(SUPERCLASS_BY_FAMILY);
|
|
247
|
-
}
|
|
75
|
+
const primaryLang = await this.#bootstrapRepo.getLatestPrimaryLang(this.#projectRoot);
|
|
76
|
+
this.#families = LanguageProfiles.resolveFamilies(primaryLang);
|
|
248
77
|
return this.#families;
|
|
249
78
|
}
|
|
250
79
|
/** 构建当前项目语言族的超类合并映射 */
|
|
251
|
-
#getSuperclassMap() {
|
|
80
|
+
async #getSuperclassMap() {
|
|
252
81
|
if (this.#superclassMap) {
|
|
253
82
|
return this.#superclassMap;
|
|
254
83
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
Object.assign(merged, SUPERCLASS_BY_FAMILY[fam]);
|
|
258
|
-
}
|
|
259
|
-
this.#superclassMap = merged;
|
|
260
|
-
return merged;
|
|
84
|
+
this.#superclassMap = LanguageProfiles.superclassRoles(await this.#detectFamilies());
|
|
85
|
+
return this.#superclassMap;
|
|
261
86
|
}
|
|
262
87
|
/** 构建当前项目语言族的协议合并映射 */
|
|
263
|
-
#getProtocolMap() {
|
|
88
|
+
async #getProtocolMap() {
|
|
264
89
|
if (this.#protocolMap) {
|
|
265
90
|
return this.#protocolMap;
|
|
266
91
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
Object.assign(merged, PROTOCOL_BY_FAMILY[fam]);
|
|
270
|
-
}
|
|
271
|
-
this.#protocolMap = merged;
|
|
272
|
-
return merged;
|
|
92
|
+
this.#protocolMap = LanguageProfiles.protocolRoles(await this.#detectFamilies());
|
|
93
|
+
return this.#protocolMap;
|
|
273
94
|
}
|
|
274
95
|
/** 构建当前项目语言族的 import 模式列表 */
|
|
275
|
-
#getImportPatterns() {
|
|
96
|
+
async #getImportPatterns() {
|
|
276
97
|
if (this.#importPatterns) {
|
|
277
98
|
return this.#importPatterns;
|
|
278
99
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
patterns.push(...IMPORT_PATTERNS_BY_FAMILY[fam]);
|
|
282
|
-
}
|
|
283
|
-
this.#importPatterns = patterns;
|
|
284
|
-
return patterns;
|
|
100
|
+
this.#importPatterns = LanguageProfiles.importRolePatterns(await this.#detectFamilies());
|
|
101
|
+
return this.#importPatterns;
|
|
285
102
|
}
|
|
286
103
|
/**
|
|
287
104
|
* 精化单个模块的角色
|
|
288
105
|
*/
|
|
289
|
-
refineRole(module) {
|
|
106
|
+
async refineRole(module) {
|
|
290
107
|
const signals = [];
|
|
291
108
|
// 1. AST 结构信号 (0.30)
|
|
292
|
-
signals.push(...this.#extractAstSignals(module));
|
|
109
|
+
signals.push(...(await this.#extractAstSignals(module)));
|
|
293
110
|
// 2. CallGraph 行为信号 (0.30)
|
|
294
|
-
signals.push(...this.#extractCallSignals(module));
|
|
111
|
+
signals.push(...(await this.#extractCallSignals(module)));
|
|
295
112
|
// 3. DataFlow 数据流信号 (0.15)
|
|
296
|
-
signals.push(...this.#extractFlowSignals(module));
|
|
113
|
+
signals.push(...(await this.#extractFlowSignals(module)));
|
|
297
114
|
// 4. EntityGraph 拓扑信号 (0.10)
|
|
298
|
-
signals.push(...this.#extractTopoSignals(module));
|
|
115
|
+
signals.push(...(await this.#extractTopoSignals(module)));
|
|
299
116
|
// 4.5. 配置层级信号 — 来自 Boxfile/Tuist 等配置文件的 layer 声明
|
|
300
117
|
if (module.configLayer) {
|
|
301
118
|
const layerRole = CONFIG_LAYER_TO_ROLE[module.configLayer.toLowerCase()];
|
|
@@ -359,31 +176,26 @@ export class RoleRefiner {
|
|
|
359
176
|
/**
|
|
360
177
|
* 批量精化所有模块
|
|
361
178
|
*/
|
|
362
|
-
refineAll(modules) {
|
|
179
|
+
async refineAll(modules) {
|
|
363
180
|
const result = new Map();
|
|
364
181
|
for (const m of modules) {
|
|
365
|
-
result.set(m.name, this.refineRole(m));
|
|
182
|
+
result.set(m.name, await this.refineRole(m));
|
|
366
183
|
}
|
|
367
184
|
return result;
|
|
368
185
|
}
|
|
369
186
|
/* ─── Signal Extractors ──────────────────────────── */
|
|
370
187
|
/** AST 结构信号: 继承链、协议、import */
|
|
371
|
-
#extractAstSignals(module) {
|
|
188
|
+
async #extractAstSignals(module) {
|
|
372
189
|
const signals = [];
|
|
373
190
|
const filePaths = module.files;
|
|
374
191
|
if (filePaths.length === 0) {
|
|
375
192
|
return signals;
|
|
376
193
|
}
|
|
377
194
|
// 查询模块内实体的继承关系
|
|
378
|
-
const
|
|
379
|
-
const entities = this.#db
|
|
380
|
-
.prepare(`SELECT entity_id, entity_type, superclass, protocols, file_path
|
|
381
|
-
FROM code_entities
|
|
382
|
-
WHERE project_root = ? AND file_path IN (${placeholders})`)
|
|
383
|
-
.all(this.#projectRoot, ...filePaths);
|
|
195
|
+
const entities = await this.#entityRepo.findByProjectAndFilePaths(this.#projectRoot, filePaths);
|
|
384
196
|
const roleCounts = {};
|
|
385
|
-
const superclassMap = this.#getSuperclassMap();
|
|
386
|
-
const protocolMap = this.#getProtocolMap();
|
|
197
|
+
const superclassMap = await this.#getSuperclassMap();
|
|
198
|
+
const protocolMap = await this.#getProtocolMap();
|
|
387
199
|
for (const entity of entities) {
|
|
388
200
|
// 继承链推断
|
|
389
201
|
const superclass = entity.superclass;
|
|
@@ -392,27 +204,19 @@ export class RoleRefiner {
|
|
|
392
204
|
roleCounts[role] = (roleCounts[role] ?? 0) + 1;
|
|
393
205
|
}
|
|
394
206
|
// 协议推断
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
roleCounts[role] = (roleCounts[role] ?? 0) + 0.5;
|
|
401
|
-
}
|
|
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;
|
|
402
212
|
}
|
|
403
213
|
}
|
|
404
|
-
catch {
|
|
405
|
-
// ignore malformed JSON
|
|
406
|
-
}
|
|
407
214
|
}
|
|
408
215
|
// import 模式推断
|
|
409
|
-
const imports = this.#
|
|
410
|
-
.prepare(`SELECT DISTINCT to_id FROM knowledge_edges
|
|
411
|
-
WHERE from_type = 'module' AND from_id = ? AND relation = 'depends_on'`)
|
|
412
|
-
.all(module.name);
|
|
216
|
+
const imports = await this.#edgeRepo.findOutgoingByRelation(module.name, 'depends_on');
|
|
413
217
|
for (const imp of imports) {
|
|
414
|
-
const depName = imp.
|
|
415
|
-
for (const pat of this.#getImportPatterns()) {
|
|
218
|
+
const depName = imp.toId.toLowerCase();
|
|
219
|
+
for (const pat of await this.#getImportPatterns()) {
|
|
416
220
|
if (pat.regex.test(depName)) {
|
|
417
221
|
roleCounts[pat.role] = (roleCounts[pat.role] ?? 0) + 0.5;
|
|
418
222
|
}
|
|
@@ -433,30 +237,16 @@ export class RoleRefiner {
|
|
|
433
237
|
return signals;
|
|
434
238
|
}
|
|
435
239
|
/** CallGraph 行为信号: 调用流向分析 */
|
|
436
|
-
#extractCallSignals(module) {
|
|
240
|
+
async #extractCallSignals(module) {
|
|
437
241
|
const signals = [];
|
|
438
|
-
// 查模块实体的 call edge 统计
|
|
439
242
|
const filePaths = module.files;
|
|
440
243
|
if (filePaths.length === 0) {
|
|
441
244
|
return signals;
|
|
442
245
|
}
|
|
443
|
-
const placeholders = filePaths.map(() => '?').join(',');
|
|
444
246
|
// fan-out: 模块内实体调用外部
|
|
445
|
-
const
|
|
446
|
-
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
447
|
-
JOIN code_entities ce ON ke.from_id = ce.entity_id AND ke.from_type = ce.entity_type
|
|
448
|
-
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
449
|
-
AND ke.relation = 'calls'`)
|
|
450
|
-
.get(this.#projectRoot, ...filePaths);
|
|
247
|
+
const fanOut = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'calls', 'from');
|
|
451
248
|
// fan-in: 外部调用模块内实体
|
|
452
|
-
const
|
|
453
|
-
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
454
|
-
JOIN code_entities ce ON ke.to_id = ce.entity_id AND ke.to_type = ce.entity_type
|
|
455
|
-
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
456
|
-
AND ke.relation = 'calls'`)
|
|
457
|
-
.get(this.#projectRoot, ...filePaths);
|
|
458
|
-
const fanOut = Number(outEdges?.cnt ?? 0);
|
|
459
|
-
const fanIn = Number(inEdges?.cnt ?? 0);
|
|
249
|
+
const fanIn = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'calls', 'to');
|
|
460
250
|
if (fanIn + fanOut === 0) {
|
|
461
251
|
return signals;
|
|
462
252
|
}
|
|
@@ -490,29 +280,16 @@ export class RoleRefiner {
|
|
|
490
280
|
return signals;
|
|
491
281
|
}
|
|
492
282
|
/** DataFlow 数据流信号: 源/汇分析 */
|
|
493
|
-
#extractFlowSignals(module) {
|
|
283
|
+
async #extractFlowSignals(module) {
|
|
494
284
|
const signals = [];
|
|
495
285
|
const filePaths = module.files;
|
|
496
286
|
if (filePaths.length === 0) {
|
|
497
287
|
return signals;
|
|
498
288
|
}
|
|
499
|
-
const placeholders = filePaths.map(() => '?').join(',');
|
|
500
289
|
// data_flow out (data producer)
|
|
501
|
-
const
|
|
502
|
-
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
503
|
-
JOIN code_entities ce ON ke.from_id = ce.entity_id AND ke.from_type = ce.entity_type
|
|
504
|
-
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
505
|
-
AND ke.relation = 'data_flow'`)
|
|
506
|
-
.get(this.#projectRoot, ...filePaths);
|
|
290
|
+
const out = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'data_flow', 'from');
|
|
507
291
|
// data_flow in (data consumer)
|
|
508
|
-
const
|
|
509
|
-
.prepare(`SELECT COUNT(*) as cnt FROM knowledge_edges ke
|
|
510
|
-
JOIN code_entities ce ON ke.to_id = ce.entity_id AND ke.to_type = ce.entity_type
|
|
511
|
-
WHERE ce.project_root = ? AND ce.file_path IN (${placeholders})
|
|
512
|
-
AND ke.relation = 'data_flow'`)
|
|
513
|
-
.get(this.#projectRoot, ...filePaths);
|
|
514
|
-
const out = Number(outFlow?.cnt ?? 0);
|
|
515
|
-
const _in = Number(inFlow?.cnt ?? 0);
|
|
292
|
+
const _in = await this.#edgeRepo.countEdgesJoinedByEntityFiles(this.#projectRoot, filePaths, 'data_flow', 'to');
|
|
516
293
|
if (out + _in === 0) {
|
|
517
294
|
return signals;
|
|
518
295
|
}
|
|
@@ -537,24 +314,16 @@ export class RoleRefiner {
|
|
|
537
314
|
return signals;
|
|
538
315
|
}
|
|
539
316
|
/** EntityGraph 拓扑信号: 入度分析/模式检测 */
|
|
540
|
-
#extractTopoSignals(module) {
|
|
317
|
+
async #extractTopoSignals(module) {
|
|
541
318
|
const signals = [];
|
|
542
319
|
// 查模块下是否有 singleton / delegate 等设计模式
|
|
543
|
-
const patterns = this.#
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
AND ce.entity_id IN (
|
|
548
|
-
SELECT entity_id FROM code_entities
|
|
549
|
-
WHERE project_root = ? AND file_path IN (${module.files.map(() => '?').join(',')})
|
|
550
|
-
)`)
|
|
551
|
-
.all(this.#projectRoot, this.#projectRoot, ...module.files);
|
|
552
|
-
for (const p of patterns) {
|
|
553
|
-
const name = p.pattern_name?.toLowerCase();
|
|
554
|
-
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) {
|
|
555
324
|
continue;
|
|
556
325
|
}
|
|
557
|
-
if (
|
|
326
|
+
if (lowerName === 'singleton') {
|
|
558
327
|
signals.push({
|
|
559
328
|
role: 'service',
|
|
560
329
|
confidence: 0.6,
|
|
@@ -562,7 +331,7 @@ export class RoleRefiner {
|
|
|
562
331
|
source: 'pattern-singleton',
|
|
563
332
|
});
|
|
564
333
|
}
|
|
565
|
-
if (
|
|
334
|
+
if (lowerName === 'delegate') {
|
|
566
335
|
signals.push({
|
|
567
336
|
role: 'ui',
|
|
568
337
|
confidence: 0.4,
|
|
@@ -6,120 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module TechStackProfiler
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* 知名开源库 → 技术栈分类映射
|
|
12
|
-
* 覆盖 iOS/Swift/ObjC + 跨平台常见 + Node/Web 常见
|
|
13
|
-
*/
|
|
14
|
-
const KNOWN_LIBRARIES = {
|
|
15
|
-
// 网络
|
|
16
|
-
afnetworking: 'Networking',
|
|
17
|
-
alamofire: 'Networking',
|
|
18
|
-
moya: 'Networking',
|
|
19
|
-
axios: 'Networking',
|
|
20
|
-
urlsession: 'Networking',
|
|
21
|
-
grpc: 'Networking',
|
|
22
|
-
starscream: 'Networking',
|
|
23
|
-
socketrocket: 'Networking',
|
|
24
|
-
// 图片
|
|
25
|
-
sdwebimage: 'Image',
|
|
26
|
-
kingfisher: 'Image',
|
|
27
|
-
nuke: 'Image',
|
|
28
|
-
yyimage: 'Image',
|
|
29
|
-
flanimatedimage: 'Image',
|
|
30
|
-
// UI / 布局
|
|
31
|
-
snapkit: 'UI',
|
|
32
|
-
masonry: 'UI',
|
|
33
|
-
flexlayout: 'UI',
|
|
34
|
-
yoga: 'UI',
|
|
35
|
-
texture: 'UI',
|
|
36
|
-
asyncdisplaykit: 'UI',
|
|
37
|
-
iglistkit: 'UI',
|
|
38
|
-
mbprogresshud: 'UI',
|
|
39
|
-
svprogresshud: 'UI',
|
|
40
|
-
lottie: 'UI',
|
|
41
|
-
yytext: 'UI',
|
|
42
|
-
dzzfloatingactionbutton: 'UI',
|
|
43
|
-
herocard: 'UI',
|
|
44
|
-
// 响应式 / 函数式
|
|
45
|
-
rxswift: 'Reactive',
|
|
46
|
-
rxcocoa: 'Reactive',
|
|
47
|
-
reactiveswift: 'Reactive',
|
|
48
|
-
combine: 'Reactive',
|
|
49
|
-
openombine: 'Reactive',
|
|
50
|
-
promisekit: 'Reactive',
|
|
51
|
-
// 数据 / 存储
|
|
52
|
-
realm: 'Storage',
|
|
53
|
-
coredata: 'Storage',
|
|
54
|
-
fmdb: 'Storage',
|
|
55
|
-
grdb: 'Storage',
|
|
56
|
-
sqlite: 'Storage',
|
|
57
|
-
wcdb: 'Storage',
|
|
58
|
-
mmkv: 'Storage',
|
|
59
|
-
userdefaults: 'Storage',
|
|
60
|
-
yymodel: 'Serialization',
|
|
61
|
-
objectmapper: 'Serialization',
|
|
62
|
-
codable: 'Serialization',
|
|
63
|
-
swiftyjson: 'Serialization',
|
|
64
|
-
mantle: 'Serialization',
|
|
65
|
-
handyjson: 'Serialization',
|
|
66
|
-
mjextension: 'Serialization',
|
|
67
|
-
// 日志 / 诊断
|
|
68
|
-
cocoalumberjack: 'Logging',
|
|
69
|
-
swiftybeaver: 'Logging',
|
|
70
|
-
oslog: 'Logging',
|
|
71
|
-
bugly: 'Diagnostics',
|
|
72
|
-
sentry: 'Diagnostics',
|
|
73
|
-
firebase: 'Diagnostics',
|
|
74
|
-
crashlytics: 'Diagnostics',
|
|
75
|
-
// 路由
|
|
76
|
-
urlnavigator: 'Routing',
|
|
77
|
-
deeplink: 'Routing',
|
|
78
|
-
arouter: 'Routing',
|
|
79
|
-
ctmediator: 'Routing',
|
|
80
|
-
// 测试
|
|
81
|
-
quick: 'Testing',
|
|
82
|
-
nimble: 'Testing',
|
|
83
|
-
xctest: 'Testing',
|
|
84
|
-
ocmock: 'Testing',
|
|
85
|
-
ohhttpstubs: 'Testing',
|
|
86
|
-
// 安全 / 加密
|
|
87
|
-
cryptoswift: 'Security',
|
|
88
|
-
keychain: 'Security',
|
|
89
|
-
keychainaccess: 'Security',
|
|
90
|
-
commonCrypto: 'Security',
|
|
91
|
-
// 依赖注入
|
|
92
|
-
swinject: 'Architecture',
|
|
93
|
-
needle: 'Architecture',
|
|
94
|
-
// 工具
|
|
95
|
-
swiftlint: 'Tooling',
|
|
96
|
-
r_swift: 'Tooling',
|
|
97
|
-
swiftgen: 'Tooling',
|
|
98
|
-
cocoapods: 'Tooling',
|
|
99
|
-
};
|
|
100
|
-
/**
|
|
101
|
-
* 关键词 → 分类的启发式映射
|
|
102
|
-
* 用于 KNOWN_LIBRARIES 未命中时的 fallback
|
|
103
|
-
*/
|
|
104
|
-
const KEYWORD_CATEGORIES = [
|
|
105
|
-
[/net(work)?|http|api|url|request|socket|grpc/i, 'Networking'],
|
|
106
|
-
[/image|photo|picture|avatar|thumbnail/i, 'Image'],
|
|
107
|
-
[/ui|view|layout|widget|button|label|cell|collection|table/i, 'UI'],
|
|
108
|
-
[/anim(at)?|lottie|transition|motion/i, 'Animation'],
|
|
109
|
-
[/rx|reactive|combine|signal|observable|promise/i, 'Reactive'],
|
|
110
|
-
[/db|database|sql|realm|store|cache|storage|persist/i, 'Storage'],
|
|
111
|
-
[/json|model|mapper|serial|codable|parse|decode/i, 'Serialization'],
|
|
112
|
-
[/log|debug|trace|monitor|crash|sentry|bugly|diagnostic/i, 'Diagnostics'],
|
|
113
|
-
[/route|router|navigation|deeplink|scheme|mediator/i, 'Routing'],
|
|
114
|
-
[/test|mock|stub|spec|expect|assert/i, 'Testing'],
|
|
115
|
-
[/crypto|encrypt|security|keychain|auth|token|oauth/i, 'Security'],
|
|
116
|
-
[/player|video|audio|media|av|stream/i, 'Media'],
|
|
117
|
-
[/map|location|geo|coordinate|clocation/i, 'Location'],
|
|
118
|
-
[/pay|purchase|billing|iap/i, 'Payment'],
|
|
119
|
-
[/push|notification|apns|message/i, 'Messaging'],
|
|
120
|
-
[/analytics|track|event|statistics/i, 'Analytics'],
|
|
121
|
-
[/ad|banner|interstitial|reward/i, 'Advertising'],
|
|
122
|
-
];
|
|
9
|
+
import { LanguageProfiles } from '#shared/LanguageProfiles.js';
|
|
123
10
|
/* ═══ TechStackProfiler ═══════════════════════════════════ */
|
|
124
11
|
/** Fan-in 阈值:高于此值视为关键依赖热点 */
|
|
125
12
|
const HOTSPOT_THRESHOLD = 3;
|
|
@@ -166,22 +53,23 @@ export function profileTechStack(externalDeps) {
|
|
|
166
53
|
* 分类单个外部依赖
|
|
167
54
|
*/
|
|
168
55
|
function classifyDependency(name) {
|
|
56
|
+
const knownLibraries = LanguageProfiles.knownLibraries;
|
|
169
57
|
// 标准化名称:移除前缀、转小写
|
|
170
58
|
const normalized = name
|
|
171
59
|
.replace(/^(BDMV|BDP|FMT|BD|MTL|Bai|Ali|TX|TT)/, '')
|
|
172
60
|
.toLowerCase()
|
|
173
61
|
.replace(/[-_]/g, '');
|
|
174
62
|
// 1. 精确匹配已知库
|
|
175
|
-
if (
|
|
176
|
-
return
|
|
63
|
+
if (knownLibraries[normalized]) {
|
|
64
|
+
return knownLibraries[normalized];
|
|
177
65
|
}
|
|
178
66
|
// 尝试原始名称小写
|
|
179
67
|
const rawLower = name.toLowerCase().replace(/[-_]/g, '');
|
|
180
|
-
if (
|
|
181
|
-
return
|
|
68
|
+
if (knownLibraries[rawLower]) {
|
|
69
|
+
return knownLibraries[rawLower];
|
|
182
70
|
}
|
|
183
71
|
// 2. 关键词启发式
|
|
184
|
-
for (const [pattern, category] of
|
|
72
|
+
for (const [pattern, category] of LanguageProfiles.keywordCategories) {
|
|
185
73
|
if (pattern.test(name)) {
|
|
186
74
|
return category;
|
|
187
75
|
}
|