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.
Files changed (211) hide show
  1. package/README.md +1 -0
  2. package/dashboard/dist/assets/icons-BMNb0V6L.js +1 -0
  3. package/dashboard/dist/assets/index-DHJ1Dj7u.css +1 -0
  4. package/dashboard/dist/assets/index-DV8biUkH.js +112 -0
  5. package/dashboard/dist/index.html +3 -3
  6. package/dist/bin/cli.js +7 -4
  7. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  8. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  9. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  10. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  11. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  12. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  13. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  14. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  15. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  16. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  17. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  18. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  19. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  20. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  21. package/dist/lib/agent/memory/SessionStore.js +0 -2
  22. package/dist/lib/agent/tools/ast-graph.js +21 -19
  23. package/dist/lib/agent/tools/infrastructure.js +3 -2
  24. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  25. package/dist/lib/agent/tools/project-access.js +5 -4
  26. package/dist/lib/bootstrap.js +2 -1
  27. package/dist/lib/cli/AiScanService.js +4 -17
  28. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  29. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  30. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  31. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +0 -2
  32. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +0 -2
  33. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  34. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  35. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  36. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  37. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  38. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  39. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  40. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  41. package/dist/lib/domain/knowledge/index.js +1 -1
  42. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  43. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  44. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +33 -16
  45. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  46. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  47. package/dist/lib/external/mcp/handlers/bootstrap-external.js +1 -1
  48. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +7 -3
  49. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  50. package/dist/lib/external/mcp/handlers/evolve-external.js +13 -16
  51. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  52. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  53. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  54. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  55. package/dist/lib/external/mcp/handlers/search.js +3 -1
  56. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  57. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  58. package/dist/lib/external/mcp/handlers/system.js +10 -34
  59. package/dist/lib/http/routes/ai.js +11 -13
  60. package/dist/lib/http/routes/guardReport.js +3 -5
  61. package/dist/lib/http/routes/panorama.js +12 -12
  62. package/dist/lib/http/routes/recipes.js +59 -8
  63. package/dist/lib/http/routes/remote.js +3 -13
  64. package/dist/lib/http/routes/search.js +11 -8
  65. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  66. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  67. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  68. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  69. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  70. package/dist/lib/injection/ServiceContainer.js +7 -4
  71. package/dist/lib/injection/ServiceMap.d.ts +20 -0
  72. package/dist/lib/injection/modules/AppModule.js +2 -1
  73. package/dist/lib/injection/modules/GuardModule.js +5 -5
  74. package/dist/lib/injection/modules/InfraModule.js +60 -0
  75. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  76. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  77. package/dist/lib/injection/modules/VectorModule.js +3 -0
  78. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  79. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  80. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  81. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  82. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  83. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  84. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  85. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  86. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  87. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  88. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  89. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  90. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  91. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  92. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  93. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  94. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  95. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  96. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  97. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  98. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  99. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  100. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  101. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  102. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  103. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  104. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  105. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  106. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  107. package/dist/lib/repository/session/SessionRepository.js +110 -0
  108. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  109. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  110. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  111. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  112. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  113. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  114. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  115. package/dist/lib/service/cleanup/CleanupService.js +8 -4
  116. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
  117. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  118. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  119. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  120. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  121. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  122. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  123. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  124. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  125. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  126. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  127. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  128. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  129. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  130. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  131. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  132. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  133. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  134. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  135. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  136. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  137. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  138. package/dist/lib/service/evolution/StagingManager.js +37 -95
  139. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  140. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  141. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  142. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  143. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  144. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  145. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  146. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  147. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  148. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  149. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +39 -63
  150. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -512
  151. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  152. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  153. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  154. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  155. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  156. package/dist/lib/service/knowledge/KnowledgeService.js +76 -38
  157. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  158. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  159. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  160. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  161. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +5 -3
  162. package/dist/lib/service/panorama/CouplingAnalyzer.js +102 -39
  163. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  164. package/dist/lib/service/panorama/DimensionAnalyzer.js +72 -25
  165. package/dist/lib/service/panorama/LayerInferrer.js +1 -1
  166. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +7 -6
  167. package/dist/lib/service/panorama/ModuleDiscoverer.js +174 -82
  168. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +10 -3
  169. package/dist/lib/service/panorama/PanoramaAggregator.js +67 -79
  170. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  171. package/dist/lib/service/panorama/PanoramaScanner.js +32 -31
  172. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  173. package/dist/lib/service/panorama/PanoramaService.js +41 -66
  174. package/dist/lib/service/panorama/PanoramaTypes.d.ts +3 -0
  175. package/dist/lib/service/panorama/RoleRefiner.d.ts +8 -5
  176. package/dist/lib/service/panorama/RoleRefiner.js +52 -283
  177. package/dist/lib/service/panorama/TechStackProfiler.js +7 -119
  178. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  179. package/dist/lib/service/quality/QualityScorer.js +157 -83
  180. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  181. package/dist/lib/service/search/SearchEngine.js +32 -37
  182. package/dist/lib/service/signal/HitRecorder.js +5 -5
  183. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  184. package/dist/lib/service/skills/SignalCollector.d.ts +5 -8
  185. package/dist/lib/service/skills/SignalCollector.js +28 -55
  186. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  187. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  188. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  189. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  190. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  191. package/dist/lib/service/vector/VectorService.js +3 -0
  192. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  193. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  194. package/dist/lib/shared/LanguageProfiles.js +939 -0
  195. package/dist/lib/shared/LanguageService.d.ts +6 -0
  196. package/dist/lib/shared/LanguageService.js +16 -0
  197. package/dist/lib/shared/constants.d.ts +19 -19
  198. package/dist/lib/shared/constants.js +10 -10
  199. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  200. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  201. package/dist/lib/types/project-snapshot-builder.js +0 -1
  202. package/dist/lib/types/project-snapshot.d.ts +0 -1
  203. package/dist/lib/types/project-snapshot.js +0 -1
  204. package/dist/lib/types/snapshot-views.d.ts +0 -2
  205. package/dist/lib/types/snapshot-views.js +0 -1
  206. package/package.json +2 -1
  207. package/dashboard/dist/assets/icons-FHns2ypa.js +0 -1
  208. package/dashboard/dist/assets/index-BRJv5Y3r.js +0 -135
  209. package/dashboard/dist/assets/index-DzoB7kxK.css +0 -1
  210. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  211. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -0,0 +1,939 @@
1
+ /**
2
+ * LanguageProfiles — 全景分析多语言统一注册中心
3
+ *
4
+ * 设计原则:
5
+ * 1. **语言族 (LanguageFamily)** 是核心抽象 — 同族语言共享 import 语法、框架类体系、生态库
6
+ * 2. **单一数据源** — 新增语言只需添加一条 FamilyProfile,所有消费者自动生效
7
+ * 3. **与 LanguageService 互补** — LanguageService 管理基础映射 (ext→lang),
8
+ * LanguageProfiles 管理分析知识 (import 解析、角色推断、技术栈分类)
9
+ * 4. **按关注点暴露 API** — 消费者调用自己需要的访问器,无需了解内部数据结构
10
+ *
11
+ * 消费者:
12
+ * - CouplingAnalyzer → importPatterns, sourceExts
13
+ * - RoleRefiner → familyOf, superclassRoles, protocolRoles, importRolePatterns
14
+ * - TechStackProfiler → knownLibraries, keywordCategories
15
+ * - ModuleDiscoverer → skipDirs, artifactSuffixes, vendorDirs, sourceExts
16
+ *
17
+ * @module LanguageProfiles
18
+ */
19
+ import { LanguageService } from './LanguageService.js';
20
+ /* ═══ Family Definitions ══════════════════════════════════ */
21
+ const APPLE = {
22
+ family: 'apple',
23
+ languages: ['swift', 'objectivec'],
24
+ importPatterns: [
25
+ // #import <ModuleName/Header.h>
26
+ { regex: /^#import\s+<([^/]+)\//, extract: (m) => [m[1]] },
27
+ // @import ModuleName;
28
+ { regex: /^@import\s+([A-Za-z_]\w*)(?:\.\w+)*\s*;/, extract: (m) => [m[1]] },
29
+ // import ModuleName
30
+ { regex: /^import\s+([A-Za-z_]\w+)\s*$/, extract: (m) => [m[1]] },
31
+ ],
32
+ superclassRoles: {
33
+ UIViewController: 'ui',
34
+ UIView: 'ui',
35
+ UITableViewCell: 'ui',
36
+ UICollectionViewCell: 'ui',
37
+ UINavigationController: 'routing',
38
+ UITabBarController: 'routing',
39
+ UIApplication: 'app',
40
+ NSObject: 'core',
41
+ NSManagedObject: 'storage',
42
+ },
43
+ protocolRoles: {
44
+ UITableViewDataSource: 'ui',
45
+ UITableViewDelegate: 'ui',
46
+ UICollectionViewDataSource: 'ui',
47
+ UIApplicationDelegate: 'app',
48
+ UISceneDelegate: 'app',
49
+ UIWindowSceneDelegate: 'app',
50
+ URLSessionDelegate: 'networking',
51
+ Codable: 'model',
52
+ Decodable: 'model',
53
+ Encodable: 'model',
54
+ },
55
+ importRolePatterns: [
56
+ { regex: /alamofire|urlsession|afnetworking|moya/i, role: 'networking' },
57
+ { regex: /\buikit\b|swiftui|rx.*cocoa|snapkit|masonry/i, role: 'ui' },
58
+ { regex: /realm|coredata|fmdb|grdb/i, role: 'storage' },
59
+ { regex: /xctest/i, role: 'test' },
60
+ ],
61
+ knownLibraries: {
62
+ afnetworking: 'Networking',
63
+ alamofire: 'Networking',
64
+ moya: 'Networking',
65
+ urlsession: 'Networking',
66
+ starscream: 'Networking',
67
+ socketrocket: 'Networking',
68
+ sdwebimage: 'Image',
69
+ kingfisher: 'Image',
70
+ nuke: 'Image',
71
+ yyimage: 'Image',
72
+ flanimatedimage: 'Image',
73
+ snapkit: 'UI',
74
+ masonry: 'UI',
75
+ flexlayout: 'UI',
76
+ texture: 'UI',
77
+ asyncdisplaykit: 'UI',
78
+ iglistkit: 'UI',
79
+ mbprogresshud: 'UI',
80
+ svprogresshud: 'UI',
81
+ yytext: 'UI',
82
+ dzzfloatingactionbutton: 'UI',
83
+ herocard: 'UI',
84
+ swiftui: 'UI',
85
+ rxswift: 'Reactive',
86
+ rxcocoa: 'Reactive',
87
+ reactiveswift: 'Reactive',
88
+ combine: 'Reactive',
89
+ openombine: 'Reactive',
90
+ promisekit: 'Reactive',
91
+ realm: 'Storage',
92
+ coredata: 'Storage',
93
+ fmdb: 'Storage',
94
+ grdb: 'Storage',
95
+ wcdb: 'Storage',
96
+ mmkv: 'Storage',
97
+ userdefaults: 'Storage',
98
+ yymodel: 'Serialization',
99
+ objectmapper: 'Serialization',
100
+ codable: 'Serialization',
101
+ swiftyjson: 'Serialization',
102
+ mantle: 'Serialization',
103
+ handyjson: 'Serialization',
104
+ mjextension: 'Serialization',
105
+ cocoalumberjack: 'Logging',
106
+ swiftybeaver: 'Logging',
107
+ oslog: 'Logging',
108
+ urlnavigator: 'Routing',
109
+ deeplink: 'Routing',
110
+ ctmediator: 'Routing',
111
+ quick: 'Testing',
112
+ nimble: 'Testing',
113
+ xctest: 'Testing',
114
+ ocmock: 'Testing',
115
+ ohhttpstubs: 'Testing',
116
+ cryptoswift: 'Security',
117
+ keychain: 'Security',
118
+ keychainaccess: 'Security',
119
+ commoncrypto: 'Security',
120
+ swinject: 'Architecture',
121
+ needle: 'Architecture',
122
+ swiftlint: 'Tooling',
123
+ r_swift: 'Tooling',
124
+ swiftgen: 'Tooling',
125
+ cocoapods: 'Tooling',
126
+ },
127
+ artifactSuffixes: [
128
+ '.xcassets',
129
+ '.bundle',
130
+ '.lproj',
131
+ '.framework',
132
+ '.xcdatamodeld',
133
+ '.xcodeproj',
134
+ '.xcworkspace',
135
+ '.storyboard',
136
+ '.xib',
137
+ '.playground',
138
+ ],
139
+ vendorDirs: ['Pods', 'Carthage'],
140
+ extraSkipDirs: ['.build', '.swiftpm', 'DerivedData'],
141
+ };
142
+ const JVM = {
143
+ family: 'jvm',
144
+ languages: ['java', 'kotlin'],
145
+ importPatterns: [
146
+ // import com.example.auth.Class → 返回所有包段作为候选
147
+ {
148
+ regex: /^import\s+(?:static\s+)?([\w.]+)/,
149
+ extract: (m) => {
150
+ const SKIP = new Set(['java', 'javax', 'android', 'androidx', 'kotlin', 'kotlinx']);
151
+ return m[1]
152
+ .split('.')
153
+ .filter((s) => !SKIP.has(s) && s[0] === s[0].toLowerCase() && s.length > 1);
154
+ },
155
+ },
156
+ ],
157
+ superclassRoles: {
158
+ Activity: 'ui',
159
+ AppCompatActivity: 'ui',
160
+ Fragment: 'ui',
161
+ DialogFragment: 'ui',
162
+ View: 'ui',
163
+ RecyclerViewAdapter: 'ui',
164
+ Service: 'service',
165
+ IntentService: 'service',
166
+ BroadcastReceiver: 'service',
167
+ ContentProvider: 'storage',
168
+ ViewModel: 'ui',
169
+ AndroidViewModel: 'ui',
170
+ Application: 'app',
171
+ },
172
+ protocolRoles: {
173
+ Serializable: 'model',
174
+ Parcelable: 'model',
175
+ Runnable: 'core',
176
+ Callable: 'core',
177
+ OnClickListener: 'ui',
178
+ Adapter: 'ui',
179
+ Repository: 'storage',
180
+ },
181
+ importRolePatterns: [
182
+ { regex: /retrofit|okhttp|volley/i, role: 'networking' },
183
+ { regex: /android\.widget|jetpack.*compose|recyclerview/i, role: 'ui' },
184
+ { regex: /room|hibernate|greendao/i, role: 'storage' },
185
+ { regex: /junit|espresso|mockito/i, role: 'test' },
186
+ ],
187
+ knownLibraries: {
188
+ retrofit: 'Networking',
189
+ okhttp: 'Networking',
190
+ volley: 'Networking',
191
+ glide: 'Image',
192
+ picasso: 'Image',
193
+ coil: 'Image',
194
+ compose: 'UI',
195
+ rxjava: 'Reactive',
196
+ rxkotlin: 'Reactive',
197
+ room: 'Storage',
198
+ hibernate: 'Storage',
199
+ greendao: 'Storage',
200
+ gson: 'Serialization',
201
+ moshi: 'Serialization',
202
+ jackson: 'Serialization',
203
+ timber: 'Logging',
204
+ logback: 'Logging',
205
+ log4j: 'Logging',
206
+ arouter: 'Routing',
207
+ junit: 'Testing',
208
+ espresso: 'Testing',
209
+ mockito: 'Testing',
210
+ hilt: 'Architecture',
211
+ dagger: 'Architecture',
212
+ spring: 'Framework',
213
+ springboot: 'Framework',
214
+ },
215
+ artifactSuffixes: ['.apk', '.aar', '.jar', '.war'],
216
+ vendorDirs: ['res', 'gen'],
217
+ extraSkipDirs: ['.gradle', '.idea', 'target'],
218
+ };
219
+ const DART = {
220
+ family: 'dart',
221
+ languages: ['dart'],
222
+ importPatterns: [
223
+ // import 'package:module/file.dart'
224
+ {
225
+ regex: /^import\s+['"]package:([^/'"]+)/,
226
+ extract: (m) => [m[1]],
227
+ },
228
+ ],
229
+ superclassRoles: {
230
+ StatefulWidget: 'ui',
231
+ StatelessWidget: 'ui',
232
+ State: 'ui',
233
+ ChangeNotifier: 'service',
234
+ Cubit: 'service',
235
+ Bloc: 'service',
236
+ },
237
+ protocolRoles: {
238
+ Widget: 'ui',
239
+ },
240
+ importRolePatterns: [
241
+ { regex: /\bdio\b|http_client/i, role: 'networking' },
242
+ { regex: /flutter|cupertino|material/i, role: 'ui' },
243
+ { regex: /sqflite|hive|objectbox/i, role: 'storage' },
244
+ { regex: /flutter_test/i, role: 'test' },
245
+ ],
246
+ knownLibraries: {
247
+ dio: 'Networking',
248
+ flutter: 'UI',
249
+ rxdart: 'Reactive',
250
+ },
251
+ artifactSuffixes: [],
252
+ vendorDirs: [],
253
+ extraSkipDirs: ['.dart_tool', '.fvm'],
254
+ };
255
+ const PYTHON = {
256
+ family: 'python',
257
+ languages: ['python'],
258
+ importPatterns: [
259
+ // from module import ... / import module
260
+ { regex: /^(?:from|import)\s+([A-Za-z_]\w*)/, extract: (m) => [m[1]] },
261
+ ],
262
+ superclassRoles: {
263
+ BaseModel: 'model',
264
+ Model: 'model',
265
+ APIView: 'service',
266
+ ViewSet: 'service',
267
+ TestCase: 'test',
268
+ },
269
+ protocolRoles: {},
270
+ importRolePatterns: [
271
+ { regex: /requests|aiohttp|httpx|urllib/i, role: 'networking' },
272
+ { regex: /tkinter|pyqt|kivy/i, role: 'ui' },
273
+ { regex: /sqlalchemy|django\.db|peewee|tortoise/i, role: 'storage' },
274
+ { regex: /pytest|unittest/i, role: 'test' },
275
+ ],
276
+ knownLibraries: {
277
+ requests: 'Networking',
278
+ aiohttp: 'Networking',
279
+ httpx: 'Networking',
280
+ pillow: 'Image',
281
+ sqlalchemy: 'Storage',
282
+ django: 'Framework',
283
+ flask: 'Framework',
284
+ fastapi: 'Framework',
285
+ pytest: 'Testing',
286
+ asyncio: 'Async',
287
+ },
288
+ artifactSuffixes: [],
289
+ vendorDirs: [],
290
+ extraSkipDirs: ['__pycache__', 'venv', '.venv', '.tox'],
291
+ };
292
+ const WEB = {
293
+ family: 'web',
294
+ languages: ['javascript', 'typescript'],
295
+ importPatterns: [
296
+ // import ... from 'module'
297
+ {
298
+ regex: /^import\s+.*?from\s+['"]([^./'"@][^'"]*?)['"]/,
299
+ extract: (m) => [m[1].split('/')[0]],
300
+ },
301
+ // import 'module'
302
+ { regex: /^import\s+['"]([^./'"@][^'"]*?)['"]/, extract: (m) => [m[1].split('/')[0]] },
303
+ // require('module')
304
+ { regex: /require\(\s*['"]([^./'"@][^'"]*?)['"]\s*\)/, extract: (m) => [m[1].split('/')[0]] },
305
+ ],
306
+ superclassRoles: {
307
+ Component: 'ui',
308
+ Controller: 'service',
309
+ Module: 'app',
310
+ },
311
+ protocolRoles: {
312
+ OnInit: 'ui',
313
+ OnDestroy: 'ui',
314
+ CanActivate: 'routing',
315
+ NestMiddleware: 'service',
316
+ },
317
+ importRolePatterns: [
318
+ { regex: /axios|fetch|got|superagent/i, role: 'networking' },
319
+ { regex: /react|angular|vue|svelte|next|nuxt/i, role: 'ui' },
320
+ { regex: /typeorm|prisma|sequelize|mongoose|knex/i, role: 'storage' },
321
+ { regex: /jest|mocha|vitest|cypress|playwright/i, role: 'test' },
322
+ { regex: /express|fastify|nestjs|koa/i, role: 'routing' },
323
+ ],
324
+ knownLibraries: {
325
+ axios: 'Networking',
326
+ got: 'Networking',
327
+ superagent: 'Networking',
328
+ sharp: 'Image',
329
+ react: 'UI',
330
+ angular: 'UI',
331
+ vue: 'UI',
332
+ svelte: 'UI',
333
+ tailwindcss: 'UI',
334
+ bootstrap: 'UI',
335
+ rxjs: 'Reactive',
336
+ typeorm: 'Storage',
337
+ prisma: 'Storage',
338
+ sequelize: 'Storage',
339
+ mongoose: 'Storage',
340
+ knex: 'Storage',
341
+ express: 'Framework',
342
+ fastify: 'Framework',
343
+ nestjs: 'Framework',
344
+ koa: 'Framework',
345
+ nextjs: 'Framework',
346
+ nuxt: 'Framework',
347
+ jest: 'Testing',
348
+ mocha: 'Testing',
349
+ vitest: 'Testing',
350
+ cypress: 'Testing',
351
+ playwright: 'Testing',
352
+ jsonwebtoken: 'Security',
353
+ passport: 'Security',
354
+ bcrypt: 'Security',
355
+ inversify: 'Architecture',
356
+ tsyringe: 'Architecture',
357
+ eslint: 'Tooling',
358
+ prettier: 'Tooling',
359
+ webpack: 'Tooling',
360
+ vite: 'Tooling',
361
+ winston: 'Logging',
362
+ pino: 'Logging',
363
+ },
364
+ artifactSuffixes: [],
365
+ vendorDirs: [],
366
+ extraSkipDirs: ['node_modules', '.next', '.nuxt', 'dist', 'out', 'coverage'],
367
+ };
368
+ const GO = {
369
+ family: 'go',
370
+ languages: ['go'],
371
+ importPatterns: [
372
+ // import "path/module" or import alias "path/module"
373
+ {
374
+ regex: /^\s*(?:import\s+)?(?:\w+\s+)?"([^"]+)"/,
375
+ extract: (m) => {
376
+ const parts = m[1].split('/');
377
+ return parts.length > 1 ? [parts[parts.length - 1], parts[parts.length - 2]] : [parts[0]];
378
+ },
379
+ },
380
+ ],
381
+ superclassRoles: {},
382
+ protocolRoles: {
383
+ Handler: 'service',
384
+ ReadWriter: 'core',
385
+ Reader: 'core',
386
+ Writer: 'core',
387
+ Stringer: 'utility',
388
+ },
389
+ importRolePatterns: [
390
+ { regex: /net\/http|resty/i, role: 'networking' },
391
+ { regex: /gin|echo|fiber|mux|chi/i, role: 'routing' },
392
+ { regex: /gorm|sqlx|ent/i, role: 'storage' },
393
+ { regex: /testing/i, role: 'test' },
394
+ ],
395
+ knownLibraries: {
396
+ gin: 'Framework',
397
+ echo: 'Framework',
398
+ fiber: 'Framework',
399
+ gorm: 'Storage',
400
+ },
401
+ artifactSuffixes: [],
402
+ vendorDirs: ['vendor'],
403
+ extraSkipDirs: [],
404
+ };
405
+ const RUST = {
406
+ family: 'rust',
407
+ languages: ['rust'],
408
+ importPatterns: [
409
+ // use crate_name::sub
410
+ { regex: /^use\s+([a-z_]\w*)::/, extract: (m) => [m[1]] },
411
+ // extern crate name
412
+ { regex: /^extern\s+crate\s+([a-z_]\w*)/, extract: (m) => [m[1]] },
413
+ ],
414
+ superclassRoles: {},
415
+ protocolRoles: {
416
+ Display: 'utility',
417
+ Debug: 'utility',
418
+ Serialize: 'model',
419
+ Deserialize: 'model',
420
+ Future: 'core',
421
+ Stream: 'core',
422
+ Service: 'service',
423
+ },
424
+ importRolePatterns: [
425
+ { regex: /reqwest|hyper|surf/i, role: 'networking' },
426
+ { regex: /actix|axum|warp|rocket/i, role: 'routing' },
427
+ { regex: /diesel|sqlx|sea-orm/i, role: 'storage' },
428
+ { regex: /tokio-test/i, role: 'test' },
429
+ ],
430
+ knownLibraries: {
431
+ reqwest: 'Networking',
432
+ hyper: 'Networking',
433
+ actix: 'Framework',
434
+ axum: 'Framework',
435
+ rocket: 'Framework',
436
+ diesel: 'Storage',
437
+ sqlx: 'Storage',
438
+ serde: 'Serialization',
439
+ tokio: 'Async',
440
+ tracing: 'Logging',
441
+ },
442
+ artifactSuffixes: [],
443
+ vendorDirs: [],
444
+ extraSkipDirs: ['target'],
445
+ };
446
+ const DOTNET = {
447
+ family: 'dotnet',
448
+ languages: ['csharp'],
449
+ importPatterns: [
450
+ // using Namespace.Sub
451
+ { regex: /^using\s+(?:static\s+)?([A-Z]\w*)\./, extract: (m) => [m[1]] },
452
+ ],
453
+ superclassRoles: {
454
+ Controller: 'service',
455
+ ControllerBase: 'service',
456
+ DbContext: 'storage',
457
+ Page: 'ui',
458
+ },
459
+ protocolRoles: {
460
+ IDisposable: 'core',
461
+ IEnumerable: 'core',
462
+ IHostedService: 'service',
463
+ },
464
+ importRolePatterns: [
465
+ { regex: /HttpClient|RestSharp/i, role: 'networking' },
466
+ { regex: /EntityFramework|Dapper/i, role: 'storage' },
467
+ { regex: /xUnit|NUnit|MSTest/i, role: 'test' },
468
+ ],
469
+ knownLibraries: {},
470
+ artifactSuffixes: ['.dll', '.exe', '.nupkg'],
471
+ vendorDirs: [],
472
+ extraSkipDirs: ['bin', 'obj'],
473
+ };
474
+ /* ═══ Cross-cutting (language-neutral) ════════════════════ */
475
+ /** C / C++ 共用 import 模式 — 不属于任何特定生态族 */
476
+ const C_CPP_IMPORT_PATTERNS = [
477
+ { regex: /^#include\s+<([^/]+)\//, extract: (m) => [m[1]] },
478
+ ];
479
+ /** 通用 import → 角色推断(任何语言适用) */
480
+ const UNIVERSAL_ROLE_PATTERNS = [
481
+ { regex: /network/i, role: 'networking' },
482
+ { regex: /sqlite/i, role: 'storage' },
483
+ { regex: /router|routing|navigation/i, role: 'routing' },
484
+ ];
485
+ /** 跨平台知名库(不属于单一生态) */
486
+ const CROSS_PLATFORM_LIBRARIES = {
487
+ grpc: 'Networking',
488
+ protobuf: 'Serialization',
489
+ sqlite: 'Storage',
490
+ redis: 'Storage',
491
+ lottie: 'UI',
492
+ yoga: 'UI',
493
+ sentry: 'Diagnostics',
494
+ firebase: 'Diagnostics',
495
+ crashlytics: 'Diagnostics',
496
+ bugly: 'Diagnostics',
497
+ };
498
+ /** 关键词 → 分类的启发式映射 (KNOWN_LIBRARIES 未命中时的 fallback) */
499
+ const KEYWORD_CATEGORIES = [
500
+ [/net(work)?|http|api|url|request|socket|grpc/i, 'Networking'],
501
+ [/image|photo|picture|avatar|thumbnail/i, 'Image'],
502
+ [/ui|view|layout|widget|button|label|cell|collection|table/i, 'UI'],
503
+ [/anim(at)?|lottie|transition|motion/i, 'Animation'],
504
+ [/rx|reactive|combine|signal|observable|promise/i, 'Reactive'],
505
+ [/db|database|sql|realm|store|cache|storage|persist/i, 'Storage'],
506
+ [/json|model|mapper|serial|codable|parse|decode/i, 'Serialization'],
507
+ [/log|debug|trace|monitor|crash|sentry|bugly|diagnostic/i, 'Diagnostics'],
508
+ [/route|router|navigation|deeplink|scheme|mediator/i, 'Routing'],
509
+ [/test|mock|stub|spec|expect|assert/i, 'Testing'],
510
+ [/crypto|encrypt|security|keychain|auth|token|oauth/i, 'Security'],
511
+ [/player|video|audio|media|av|stream/i, 'Media'],
512
+ [/map|location|geo|coordinate|clocation/i, 'Location'],
513
+ [/pay|purchase|billing|iap/i, 'Payment'],
514
+ [/push|notification|apns|message/i, 'Messaging'],
515
+ [/analytics|track|event|statistics/i, 'Analytics'],
516
+ [/ad|banner|interstitial|reward/i, 'Advertising'],
517
+ ];
518
+ /** 第三方 / vendor 目录 (跨平台通用) */
519
+ const COMMON_VENDOR_DIRS = [
520
+ '3rd',
521
+ 'third_party',
522
+ 'thirdparty',
523
+ 'vendor',
524
+ 'vendors',
525
+ 'external',
526
+ 'libs',
527
+ 'assets',
528
+ 'resources',
529
+ 'migrations',
530
+ 'fixtures',
531
+ ];
532
+ /* ═══ Registry ════════════════════════════════════════════ */
533
+ const ALL_FAMILIES = [APPLE, JVM, DART, PYTHON, WEB, GO, RUST, DOTNET];
534
+ /** langId → family 查找表 (运行时构建) */
535
+ const LANG_TO_FAMILY_MAP = new Map();
536
+ for (const fp of ALL_FAMILIES) {
537
+ for (const lang of fp.languages) {
538
+ LANG_TO_FAMILY_MAP.set(lang, fp.family);
539
+ }
540
+ }
541
+ // 常见别名也注册(normalize 后可能仍用到原始值)
542
+ const ALIASES = {
543
+ 'objective-c': 'objectivec',
544
+ objc: 'objectivec',
545
+ scala: 'java',
546
+ groovy: 'java',
547
+ clojure: 'java',
548
+ jsx: 'javascript',
549
+ tsx: 'typescript',
550
+ 'c#': 'csharp',
551
+ golang: 'go',
552
+ };
553
+ for (const [alias, canonical] of Object.entries(ALIASES)) {
554
+ const fam = LANG_TO_FAMILY_MAP.get(canonical);
555
+ if (fam) {
556
+ LANG_TO_FAMILY_MAP.set(alias, fam);
557
+ }
558
+ }
559
+ /** family → profile 快速查找 */
560
+ const FAMILY_MAP = new Map();
561
+ for (const fp of ALL_FAMILIES) {
562
+ FAMILY_MAP.set(fp.family, fp);
563
+ }
564
+ /* ═══ Merged caches (lazy) ════════════════════════════════ */
565
+ let _importPatterns = null;
566
+ let _knownLibraries = null;
567
+ let _skipDirs = null;
568
+ let _artifactSuffixes = null;
569
+ let _vendorDirs = null;
570
+ let _thirdPartyPathRegex = null;
571
+ let _baseClassExclusions = null;
572
+ let _validCodeLanguages = null;
573
+ /**
574
+ * 各语言族中需额外排除的基础类型 — superclassRoles / protocolRoles 未覆盖到的通用根类型。
575
+ * getHotNodes() 等统计查询中应剔除这些高入度但无信息量的节点。
576
+ */
577
+ const EXTRA_BASE_TYPE_EXCLUSIONS = {
578
+ apple: [
579
+ 'UIControl',
580
+ 'UITableViewController',
581
+ 'UICollectionViewController',
582
+ 'UINavigationController',
583
+ 'UITabBarController',
584
+ 'NSOperation',
585
+ 'Any',
586
+ 'AnyObject',
587
+ 'Sendable',
588
+ 'NSCoding',
589
+ 'NSCopying',
590
+ ],
591
+ jvm: [
592
+ 'Object',
593
+ 'ViewGroup',
594
+ 'RecyclerView.ViewHolder',
595
+ 'BaseAdapter',
596
+ 'ArrayAdapter',
597
+ 'MutableLiveData',
598
+ 'Cloneable',
599
+ 'Runnable',
600
+ ],
601
+ dart: ['Widget', 'InheritedWidget', 'RenderObject'],
602
+ python: [
603
+ 'object',
604
+ 'type',
605
+ 'Exception',
606
+ 'BaseException',
607
+ 'ABC',
608
+ 'Protocol',
609
+ 'dict',
610
+ 'list',
611
+ 'tuple',
612
+ 'str',
613
+ 'int',
614
+ 'float',
615
+ ],
616
+ web: [
617
+ 'EventTarget',
618
+ 'HTMLElement',
619
+ 'Error',
620
+ 'Promise',
621
+ 'Map',
622
+ 'Set',
623
+ 'Array',
624
+ 'Function',
625
+ 'EventEmitter',
626
+ 'ReadableStream',
627
+ 'WritableStream',
628
+ ],
629
+ go: ['error', 'Stringer', 'Reader', 'Writer', 'Closer', 'Handler'],
630
+ rust: [
631
+ 'Display',
632
+ 'Debug',
633
+ 'Clone',
634
+ 'Copy',
635
+ 'Send',
636
+ 'Sync',
637
+ 'Default',
638
+ 'Iterator',
639
+ 'IntoIterator',
640
+ 'From',
641
+ 'Into',
642
+ ],
643
+ dotnet: [
644
+ 'System.Object',
645
+ 'ValueType',
646
+ 'Enum',
647
+ 'Exception',
648
+ 'IEnumerable',
649
+ 'IComparable',
650
+ 'Task',
651
+ 'MonoBehaviour',
652
+ ],
653
+ universal: [
654
+ 'Object',
655
+ 'Any',
656
+ 'Unit',
657
+ 'Nothing',
658
+ 'Companion',
659
+ 'Component',
660
+ 'PureComponent',
661
+ 'React.Component',
662
+ ],
663
+ };
664
+ /* ═══ LanguageProfiles — Static API ═══════════════════════ */
665
+ export class LanguageProfiles {
666
+ /* ─── Family Resolution ─────────────────────── */
667
+ /** 将规范化语言 ID 映射到语言族 */
668
+ static familyOf(langId) {
669
+ const normalized = LanguageService.normalize(langId);
670
+ return LANG_TO_FAMILY_MAP.get(normalized) ?? LANG_TO_FAMILY_MAP.get(langId.toLowerCase());
671
+ }
672
+ /** 返回所有已注册的语言族 ID */
673
+ static allFamilies() {
674
+ return ALL_FAMILIES.map((fp) => fp.family);
675
+ }
676
+ /** 根据主语言解析项目涉及的语言族 */
677
+ static resolveFamilies(primaryLang) {
678
+ if (!primaryLang) {
679
+ return ALL_FAMILIES.map((fp) => fp.family);
680
+ }
681
+ const fam = LanguageProfiles.familyOf(primaryLang);
682
+ return fam ? [fam] : ALL_FAMILIES.map((fp) => fp.family);
683
+ }
684
+ /* ─── CouplingAnalyzer: Import Extraction ───── */
685
+ /**
686
+ * 获取所有 import 解析模式 (合并全部语言族 + C/C++)
687
+ *
688
+ * CouplingAnalyzer 对每行代码尝试所有模式,
689
+ * 按「特异性递减」排列:最特殊的模式在前。
690
+ */
691
+ static get importPatterns() {
692
+ if (!_importPatterns) {
693
+ _importPatterns = [];
694
+ for (const fp of ALL_FAMILIES) {
695
+ _importPatterns.push(...fp.importPatterns);
696
+ }
697
+ _importPatterns.push(...C_CPP_IMPORT_PATTERNS);
698
+ }
699
+ return _importPatterns;
700
+ }
701
+ /**
702
+ * 源代码文件扩展名集合 — 委托 LanguageService
703
+ *
704
+ * 消除 CouplingAnalyzer / ModuleDiscoverer 自建 SOURCE_EXTS 的重复。
705
+ */
706
+ static get sourceExts() {
707
+ return LanguageService.sourceExts;
708
+ }
709
+ /* ─── RoleRefiner: Role Inference ───────────── */
710
+ /**
711
+ * 合并指定语言族的超类→角色映射
712
+ * @param families 项目检测到的语言族
713
+ */
714
+ static superclassRoles(families) {
715
+ const merged = {};
716
+ for (const fam of families) {
717
+ const fp = FAMILY_MAP.get(fam);
718
+ if (fp) {
719
+ Object.assign(merged, fp.superclassRoles);
720
+ }
721
+ }
722
+ return merged;
723
+ }
724
+ /**
725
+ * 合并指定语言族的协议/接口→角色映射
726
+ * @param families 项目检测到的语言族
727
+ */
728
+ static protocolRoles(families) {
729
+ const merged = {};
730
+ for (const fam of families) {
731
+ const fp = FAMILY_MAP.get(fam);
732
+ if (fp) {
733
+ Object.assign(merged, fp.protocolRoles);
734
+ }
735
+ }
736
+ return merged;
737
+ }
738
+ /**
739
+ * 合并指定语言族的 import→角色模式 + 通用模式
740
+ * @param families 项目检测到的语言族
741
+ */
742
+ static importRolePatterns(families) {
743
+ const patterns = [];
744
+ for (const fam of families) {
745
+ const fp = FAMILY_MAP.get(fam);
746
+ if (fp) {
747
+ patterns.push(...fp.importRolePatterns);
748
+ }
749
+ }
750
+ patterns.push(...UNIVERSAL_ROLE_PATTERNS);
751
+ return patterns;
752
+ }
753
+ /* ─── TechStackProfiler: Library Classification ── */
754
+ /**
755
+ * 获取全量已知库→分类映射 (合并所有族 + 跨平台库)
756
+ *
757
+ * TechStackProfiler 不按族过滤 — 外部依赖可能跨生态
758
+ */
759
+ static get knownLibraries() {
760
+ if (!_knownLibraries) {
761
+ _knownLibraries = {};
762
+ for (const fp of ALL_FAMILIES) {
763
+ Object.assign(_knownLibraries, fp.knownLibraries);
764
+ }
765
+ Object.assign(_knownLibraries, CROSS_PLATFORM_LIBRARIES);
766
+ }
767
+ return _knownLibraries;
768
+ }
769
+ /** 关键词启发式分类 — KNOWN_LIBRARIES 未命中时的 fallback */
770
+ static get keywordCategories() {
771
+ return KEYWORD_CATEGORIES;
772
+ }
773
+ /* ─── ModuleDiscoverer: Filesystem Heuristics ── */
774
+ /**
775
+ * 应跳过的目录名集合 (合并 LanguageService.scanSkipDirs + 各族额外目录)
776
+ */
777
+ static get skipDirs() {
778
+ if (!_skipDirs) {
779
+ _skipDirs = new Set(LanguageService.scanSkipDirs);
780
+ for (const fp of ALL_FAMILIES) {
781
+ for (const d of fp.extraSkipDirs) {
782
+ _skipDirs.add(d);
783
+ }
784
+ }
785
+ // panorama 特有的跳过目录
786
+ _skipDirs.add('.autosnippet');
787
+ }
788
+ return _skipDirs;
789
+ }
790
+ /** 构建产物后缀 (合并全部族) */
791
+ static get artifactSuffixes() {
792
+ if (!_artifactSuffixes) {
793
+ const set = new Set();
794
+ for (const fp of ALL_FAMILIES) {
795
+ for (const s of fp.artifactSuffixes) {
796
+ set.add(s);
797
+ }
798
+ }
799
+ _artifactSuffixes = [...set];
800
+ }
801
+ return _artifactSuffixes;
802
+ }
803
+ /** Vendor / 第三方目录名集合 (合并通用 + 各族) */
804
+ static get vendorDirs() {
805
+ if (!_vendorDirs) {
806
+ _vendorDirs = new Set(COMMON_VENDOR_DIRS);
807
+ for (const fp of ALL_FAMILIES) {
808
+ for (const d of fp.vendorDirs) {
809
+ _vendorDirs.add(d);
810
+ }
811
+ }
812
+ }
813
+ return _vendorDirs;
814
+ }
815
+ /* ─── Cross-cutting: Third-party Path Detection ──── */
816
+ /**
817
+ * 三方库路径正则 — 匹配路径中的 vendor 目录名或已知库名
818
+ *
819
+ * 组成:
820
+ * 1. vendorDirs + 常见 skip 目录 (Pods, Carthage, DerivedData, …)
821
+ * 2. knownLibraries 中所有库名 (首字母大写形式)
822
+ *
823
+ * 用于 Agent 工具层对搜索结果做三方库过滤。
824
+ */
825
+ static get thirdPartyPathRegex() {
826
+ if (!_thirdPartyPathRegex) {
827
+ // 1. 目录名部分
828
+ const dirNames = new Set([
829
+ ...LanguageProfiles.vendorDirs,
830
+ // 额外常见三方/构建产物目录
831
+ 'Pods',
832
+ 'Carthage',
833
+ '.build/checkouts',
834
+ 'DerivedData',
835
+ 'Submodules',
836
+ 'ThirdParty',
837
+ 'include',
838
+ 'node_modules',
839
+ 'build',
840
+ ]);
841
+ const dirPart = [...dirNames].map((d) => d.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
842
+ // 2. 知名库名部分 — 从 knownLibraries 提取,还原首字母大写
843
+ const libKeys = Object.keys(LanguageProfiles.knownLibraries);
844
+ // 取原始 casing:capitalize 首字母
845
+ const libNames = new Set();
846
+ for (const key of libKeys) {
847
+ if (key.length >= 3) {
848
+ libNames.add(key.charAt(0).toUpperCase() + key.slice(1));
849
+ }
850
+ }
851
+ const libPart = [...libNames].map((n) => n.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
852
+ _thirdPartyPathRegex = new RegExp(`(?:^|/)(?:${dirPart})/|(?:^/)(?:${libPart})/`, 'i');
853
+ }
854
+ return _thirdPartyPathRegex;
855
+ }
856
+ /* ─── HotNodes: Base Class Exclusions ────────── */
857
+ /**
858
+ * 多语言基类/根类型排除集 — 合并所有族的 superclassRoles + protocolRoles + 额外基础类型。
859
+ *
860
+ * 用于 getHotNodes() 等入度统计,排除高入度但无信息量的语言根类型。
861
+ * 新增语言族时自动生效,无需手动维护排除列表。
862
+ */
863
+ static get baseClassExclusions() {
864
+ if (!_baseClassExclusions) {
865
+ const set = new Set();
866
+ // 从各族的 superclassRoles / protocolRoles keys 自动聚合
867
+ for (const fp of ALL_FAMILIES) {
868
+ for (const name of Object.keys(fp.superclassRoles)) {
869
+ set.add(name);
870
+ }
871
+ for (const name of Object.keys(fp.protocolRoles)) {
872
+ set.add(name);
873
+ }
874
+ }
875
+ // 追加额外基础类型
876
+ for (const names of Object.values(EXTRA_BASE_TYPE_EXCLUSIONS)) {
877
+ for (const name of names) {
878
+ set.add(name);
879
+ }
880
+ }
881
+ _baseClassExclusions = set;
882
+ }
883
+ return _baseClassExclusions;
884
+ }
885
+ /* ─── QualityScorer: Valid Code Languages ─────── */
886
+ /**
887
+ * 合法代码语言集合 — 合并 LanguageService.knownLangs + 常见别名。
888
+ *
889
+ * QualityScorer 格式评分使用,判断 recipe 的 language 字段是否合法。
890
+ * 新增语言时只需在 LanguageService 添加,此处自动生效。
891
+ */
892
+ static get validCodeLanguages() {
893
+ if (!_validCodeLanguages) {
894
+ const set = new Set(LanguageService.knownLangs);
895
+ // 添加常见别名,使 QualityScorer 能宽容匹配
896
+ const extraAliases = [
897
+ 'objective-c',
898
+ 'objc',
899
+ 'c#',
900
+ 'golang',
901
+ 'shell',
902
+ 'bash',
903
+ 'zsh',
904
+ 'markdown',
905
+ 'md',
906
+ 'json',
907
+ 'yaml',
908
+ 'yml',
909
+ 'toml',
910
+ 'sql',
911
+ 'graphql',
912
+ 'html',
913
+ 'css',
914
+ 'scss',
915
+ 'less',
916
+ 'jsx',
917
+ 'tsx',
918
+ 'scala',
919
+ 'groovy',
920
+ 'clojure',
921
+ 'lua',
922
+ 'perl',
923
+ 'r',
924
+ 'matlab',
925
+ 'haskell',
926
+ 'elixir',
927
+ 'erlang',
928
+ 'zig',
929
+ 'nim',
930
+ 'v',
931
+ ];
932
+ for (const alias of extraAliases) {
933
+ set.add(alias);
934
+ }
935
+ _validCodeLanguages = set;
936
+ }
937
+ return _validCodeLanguages;
938
+ }
939
+ }