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
@@ -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
- #db;
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(db, projectRoot) {
228
- this.#db = db;
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 row = this.#db
237
- .prepare(`SELECT primary_lang FROM bootstrap_snapshots
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
- const merged = {};
256
- for (const fam of this.#detectFamilies()) {
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
- const merged = {};
268
- for (const fam of this.#detectFamilies()) {
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
- const patterns = [...UNIVERSAL_IMPORT_PATTERNS];
280
- for (const fam of this.#detectFamilies()) {
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 placeholders = filePaths.map(() => '?').join(',');
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
- try {
396
- const protocols = JSON.parse(entity.protocols || '[]');
397
- for (const proto of protocols) {
398
- if (protocolMap[proto]) {
399
- const role = protocolMap[proto];
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.#db
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.to_id.toLowerCase();
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 outEdges = this.#db
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 inEdges = this.#db
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 outFlow = this.#db
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 inFlow = this.#db
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.#db
544
- .prepare(`SELECT ke.to_id as pattern_name FROM knowledge_edges ke
545
- JOIN code_entities ce ON ke.from_id = ce.entity_id
546
- WHERE ce.project_root = ? AND ke.relation = 'uses_pattern'
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 (name === 'singleton') {
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 (name === 'delegate') {
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
- /* ═══ Known Library Categories ════════════════════════════ */
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 (KNOWN_LIBRARIES[normalized]) {
176
- return KNOWN_LIBRARIES[normalized];
63
+ if (knownLibraries[normalized]) {
64
+ return knownLibraries[normalized];
177
65
  }
178
66
  // 尝试原始名称小写
179
67
  const rawLower = name.toLowerCase().replace(/[-_]/g, '');
180
- if (KNOWN_LIBRARIES[rawLower]) {
181
- return KNOWN_LIBRARIES[rawLower];
68
+ if (knownLibraries[rawLower]) {
69
+ return knownLibraries[rawLower];
182
70
  }
183
71
  // 2. 关键词启发式
184
- for (const [pattern, category] of KEYWORD_CATEGORIES) {
72
+ for (const [pattern, category] of LanguageProfiles.keywordCategories) {
185
73
  if (pattern.test(name)) {
186
74
  return category;
187
75
  }