autosnippet 3.3.6 → 3.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) 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 +8 -4
  7. package/dist/lib/agent/AgentRuntime.d.ts +2 -2
  8. package/dist/lib/agent/AgentRuntime.js +26 -18
  9. package/dist/lib/agent/core/ChatAgentPrompts.js +57 -21
  10. package/dist/lib/agent/core/LoopContext.d.ts +1 -0
  11. package/dist/lib/agent/core/ToolExecutionPipeline.js +13 -0
  12. package/dist/lib/agent/domain/ChatAgentTasks.js +4 -0
  13. package/dist/lib/agent/forced-summary.js +7 -2
  14. package/dist/lib/agent/memory/ActiveContext.d.ts +0 -2
  15. package/dist/lib/agent/memory/ActiveContext.js +0 -2
  16. package/dist/lib/agent/memory/MemoryEmbeddingStore.d.ts +49 -0
  17. package/dist/lib/agent/memory/MemoryEmbeddingStore.js +159 -0
  18. package/dist/lib/agent/memory/MemoryRetriever.d.ts +2 -0
  19. package/dist/lib/agent/memory/MemoryRetriever.js +25 -11
  20. package/dist/lib/agent/memory/MemoryStore.d.ts +8 -41
  21. package/dist/lib/agent/memory/MemoryStore.js +196 -261
  22. package/dist/lib/agent/memory/PersistentMemory.d.ts +2 -0
  23. package/dist/lib/agent/memory/PersistentMemory.js +4 -5
  24. package/dist/lib/agent/memory/SessionStore.d.ts +0 -2
  25. package/dist/lib/agent/memory/SessionStore.js +0 -2
  26. package/dist/lib/agent/tools/ast-graph.js +21 -19
  27. package/dist/lib/agent/tools/infrastructure.js +3 -2
  28. package/dist/lib/agent/tools/project-access.d.ts +2 -2
  29. package/dist/lib/agent/tools/project-access.js +5 -4
  30. package/dist/lib/bootstrap.js +2 -1
  31. package/dist/lib/cli/AiScanService.js +8 -21
  32. package/dist/lib/cli/KnowledgeSyncService.d.ts +7 -37
  33. package/dist/lib/cli/KnowledgeSyncService.js +23 -51
  34. package/dist/lib/core/ast/ProjectGraph.js +5 -27
  35. package/dist/lib/core/discovery/ConfigWatcher.d.ts +64 -0
  36. package/dist/lib/core/discovery/ConfigWatcher.js +336 -0
  37. package/dist/lib/core/discovery/CustomConfigDiscoverer.d.ts +28 -0
  38. package/dist/lib/core/discovery/CustomConfigDiscoverer.js +1303 -0
  39. package/dist/lib/core/discovery/DiscovererPreference.d.ts +44 -0
  40. package/dist/lib/core/discovery/DiscovererPreference.js +141 -0
  41. package/dist/lib/core/discovery/DiscovererRegistry.d.ts +10 -1
  42. package/dist/lib/core/discovery/DiscovererRegistry.js +42 -2
  43. package/dist/lib/core/discovery/ProjectDiscoverer.d.ts +19 -0
  44. package/dist/lib/core/discovery/index.d.ts +2 -0
  45. package/dist/lib/core/discovery/index.js +4 -0
  46. package/dist/lib/core/discovery/parsers/CMakeParser.d.ts +32 -0
  47. package/dist/lib/core/discovery/parsers/CMakeParser.js +148 -0
  48. package/dist/lib/core/discovery/parsers/GradleDslParser.d.ts +43 -0
  49. package/dist/lib/core/discovery/parsers/GradleDslParser.js +171 -0
  50. package/dist/lib/core/discovery/parsers/JsonConfigParser.d.ts +45 -0
  51. package/dist/lib/core/discovery/parsers/JsonConfigParser.js +122 -0
  52. package/dist/lib/core/discovery/parsers/RubyDslParser.d.ts +49 -0
  53. package/dist/lib/core/discovery/parsers/RubyDslParser.js +282 -0
  54. package/dist/lib/core/discovery/parsers/StarlarkParser.d.ts +33 -0
  55. package/dist/lib/core/discovery/parsers/StarlarkParser.js +229 -0
  56. package/dist/lib/core/discovery/parsers/YamlConfigParser.d.ts +37 -0
  57. package/dist/lib/core/discovery/parsers/YamlConfigParser.js +212 -0
  58. package/dist/lib/domain/dimension/DimensionRegistry.d.ts +0 -2
  59. package/dist/lib/domain/dimension/DimensionRegistry.js +0 -2
  60. package/dist/lib/domain/dimension/DimensionSop.js +44 -33
  61. package/dist/lib/domain/dimension/UnifiedDimension.d.ts +0 -2
  62. package/dist/lib/domain/dimension/UnifiedDimension.js +0 -2
  63. package/dist/lib/domain/knowledge/KnowledgeEntry.d.ts +7 -1
  64. package/dist/lib/domain/knowledge/KnowledgeEntry.js +17 -3
  65. package/dist/lib/domain/knowledge/Lifecycle.d.ts +26 -0
  66. package/dist/lib/domain/knowledge/Lifecycle.js +42 -0
  67. package/dist/lib/domain/knowledge/index.d.ts +2 -1
  68. package/dist/lib/domain/knowledge/index.js +1 -1
  69. package/dist/lib/external/ai/AiProvider.d.ts +12 -0
  70. package/dist/lib/external/ai/AiProvider.js +24 -0
  71. package/dist/lib/external/ai/AiProviderManager.d.ts +101 -0
  72. package/dist/lib/external/ai/AiProviderManager.js +193 -0
  73. package/dist/lib/external/ai/providers/ClaudeProvider.js +11 -0
  74. package/dist/lib/external/ai/providers/GoogleGeminiProvider.js +18 -0
  75. package/dist/lib/external/ai/providers/MockProvider.d.ts +21 -3
  76. package/dist/lib/external/ai/providers/MockProvider.js +290 -14
  77. package/dist/lib/external/ai/providers/OpenAiProvider.js +16 -0
  78. package/dist/lib/external/lark/LarkTransport.d.ts +5 -1
  79. package/dist/lib/external/lark/LarkTransport.js +10 -2
  80. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.d.ts +2 -1
  81. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +102 -153
  82. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.d.ts +20 -0
  83. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/mock-pipeline.js +432 -0
  84. package/dist/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +49 -24
  85. package/dist/lib/external/mcp/handlers/bootstrap/refine.js +8 -0
  86. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.d.ts +1 -1
  87. package/dist/lib/external/mcp/handlers/bootstrap/shared/bootstrap-phases.js +41 -37
  88. package/dist/lib/external/mcp/handlers/bootstrap-external.d.ts +9 -0
  89. package/dist/lib/external/mcp/handlers/bootstrap-external.js +3 -1
  90. package/dist/lib/external/mcp/handlers/bootstrap-internal.js +2 -0
  91. package/dist/lib/external/mcp/handlers/consolidated.js +2 -1
  92. package/dist/lib/external/mcp/handlers/dimension-complete-external.js +9 -4
  93. package/dist/lib/external/mcp/handlers/evolve-external.d.ts +1 -0
  94. package/dist/lib/external/mcp/handlers/evolve-external.js +18 -18
  95. package/dist/lib/external/mcp/handlers/guard.js +15 -24
  96. package/dist/lib/external/mcp/handlers/knowledge.js +5 -4
  97. package/dist/lib/external/mcp/handlers/panorama.js +9 -9
  98. package/dist/lib/external/mcp/handlers/rescan-external.js +7 -6
  99. package/dist/lib/external/mcp/handlers/rescan-internal.js +9 -5
  100. package/dist/lib/external/mcp/handlers/search.js +3 -1
  101. package/dist/lib/external/mcp/handlers/skill.js +4 -4
  102. package/dist/lib/external/mcp/handlers/structure.js +8 -12
  103. package/dist/lib/external/mcp/handlers/system.js +10 -34
  104. package/dist/lib/http/routes/ai.js +109 -30
  105. package/dist/lib/http/routes/candidates.js +11 -4
  106. package/dist/lib/http/routes/commands.js +10 -1
  107. package/dist/lib/http/routes/guardReport.js +3 -5
  108. package/dist/lib/http/routes/health.js +11 -0
  109. package/dist/lib/http/routes/modules.js +27 -0
  110. package/dist/lib/http/routes/panorama.js +12 -12
  111. package/dist/lib/http/routes/recipes.js +66 -8
  112. package/dist/lib/http/routes/remote.js +3 -13
  113. package/dist/lib/http/routes/search.js +11 -8
  114. package/dist/lib/http/utils/routeHelpers.js +2 -1
  115. package/dist/lib/infrastructure/audit/AuditLogger.d.ts +20 -3
  116. package/dist/lib/infrastructure/audit/AuditStore.d.ts +28 -29
  117. package/dist/lib/infrastructure/audit/AuditStore.js +81 -88
  118. package/dist/lib/infrastructure/database/drizzle/schema.d.ts +180 -2
  119. package/dist/lib/infrastructure/database/drizzle/schema.js +23 -3
  120. package/dist/lib/injection/ServiceContainer.d.ts +6 -5
  121. package/dist/lib/injection/ServiceContainer.js +18 -31
  122. package/dist/lib/injection/ServiceMap.d.ts +22 -0
  123. package/dist/lib/injection/modules/AiModule.d.ts +6 -9
  124. package/dist/lib/injection/modules/AiModule.js +82 -39
  125. package/dist/lib/injection/modules/AppModule.js +2 -1
  126. package/dist/lib/injection/modules/GuardModule.js +5 -5
  127. package/dist/lib/injection/modules/InfraModule.js +60 -0
  128. package/dist/lib/injection/modules/KnowledgeModule.js +86 -51
  129. package/dist/lib/injection/modules/PanoramaModule.js +16 -10
  130. package/dist/lib/injection/modules/VectorModule.js +3 -0
  131. package/dist/lib/repository/audit/AuditRepository.d.ts +107 -0
  132. package/dist/lib/repository/audit/AuditRepository.js +272 -0
  133. package/dist/lib/repository/base/RepositoryBase.d.ts +46 -0
  134. package/dist/lib/repository/base/RepositoryBase.js +32 -0
  135. package/dist/lib/repository/bootstrap/BootstrapRepository.d.ts +94 -0
  136. package/dist/lib/repository/bootstrap/BootstrapRepository.js +246 -0
  137. package/dist/lib/repository/code/CodeEntityRepository.d.ts +91 -0
  138. package/dist/lib/repository/code/CodeEntityRepository.js +361 -0
  139. package/dist/lib/repository/delivery/DeliveryRepoAdapter.d.ts +39 -0
  140. package/dist/lib/repository/delivery/DeliveryRepoAdapter.js +23 -0
  141. package/dist/lib/repository/evolution/LifecycleEventRepository.d.ts +51 -0
  142. package/dist/lib/repository/evolution/LifecycleEventRepository.js +119 -0
  143. package/dist/lib/repository/evolution/ProposalRepository.d.ts +9 -12
  144. package/dist/lib/repository/evolution/ProposalRepository.js +114 -57
  145. package/dist/lib/repository/guard/GuardViolationRepository.d.ts +104 -0
  146. package/dist/lib/repository/guard/GuardViolationRepository.js +217 -0
  147. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.d.ts +129 -0
  148. package/dist/lib/repository/knowledge/KnowledgeEdgeRepository.js +475 -0
  149. package/dist/lib/repository/knowledge/KnowledgeFileStore.d.ts +39 -0
  150. package/dist/lib/repository/knowledge/KnowledgeFileStore.js +12 -0
  151. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.d.ts +295 -11
  152. package/dist/lib/repository/knowledge/KnowledgeRepository.impl.js +608 -13
  153. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.d.ts +61 -0
  154. package/dist/lib/repository/knowledge/KnowledgeUnitOfWork.js +156 -0
  155. package/dist/lib/repository/memory/MemoryRepository.d.ts +90 -0
  156. package/dist/lib/repository/memory/MemoryRepository.js +260 -0
  157. package/dist/lib/repository/search/SearchRepoAdapter.d.ts +92 -0
  158. package/dist/lib/repository/search/SearchRepoAdapter.js +124 -0
  159. package/dist/lib/repository/session/SessionRepository.d.ts +46 -0
  160. package/dist/lib/repository/session/SessionRepository.js +110 -0
  161. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.d.ts +66 -0
  162. package/dist/lib/repository/sourceref/RecipeSourceRefRepository.js +182 -0
  163. package/dist/lib/repository/sync/SyncRepoAdapter.d.ts +58 -0
  164. package/dist/lib/repository/sync/SyncRepoAdapter.js +58 -0
  165. package/dist/lib/service/bootstrap/UiStartupTasks.js +5 -6
  166. package/dist/lib/service/bootstrap/bootstrap-event-types.d.ts +0 -1
  167. package/dist/lib/service/bootstrap/bootstrap-event-types.js +0 -1
  168. package/dist/lib/service/cleanup/CleanupService.d.ts +54 -7
  169. package/dist/lib/service/cleanup/CleanupService.js +291 -40
  170. package/dist/lib/service/delivery/CursorDeliveryPipeline.js +6 -8
  171. package/dist/lib/service/evolution/ConsolidationAdvisor.d.ts +4 -9
  172. package/dist/lib/service/evolution/ConsolidationAdvisor.js +34 -70
  173. package/dist/lib/service/evolution/ContentPatcher.d.ts +4 -12
  174. package/dist/lib/service/evolution/ContentPatcher.js +48 -19
  175. package/dist/lib/service/evolution/ContradictionDetector.d.ts +3 -7
  176. package/dist/lib/service/evolution/ContradictionDetector.js +17 -24
  177. package/dist/lib/service/evolution/DecayDetector.d.ts +10 -9
  178. package/dist/lib/service/evolution/DecayDetector.js +63 -57
  179. package/dist/lib/service/evolution/EnhancementSuggester.d.ts +3 -9
  180. package/dist/lib/service/evolution/EnhancementSuggester.js +42 -86
  181. package/dist/lib/service/evolution/KnowledgeMetabolism.d.ts +4 -4
  182. package/dist/lib/service/evolution/KnowledgeMetabolism.js +102 -71
  183. package/dist/lib/service/evolution/ProposalExecutor.d.ts +5 -12
  184. package/dist/lib/service/evolution/ProposalExecutor.js +64 -69
  185. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.d.ts +9 -14
  186. package/dist/lib/service/evolution/RecipeLifecycleSupervisor.js +94 -155
  187. package/dist/lib/service/evolution/RecipeRelevanceAuditor.d.ts +4 -1
  188. package/dist/lib/service/evolution/RecipeRelevanceAuditor.js +50 -49
  189. package/dist/lib/service/evolution/RedundancyAnalyzer.d.ts +3 -7
  190. package/dist/lib/service/evolution/RedundancyAnalyzer.js +15 -22
  191. package/dist/lib/service/evolution/StagingManager.d.ts +6 -15
  192. package/dist/lib/service/evolution/StagingManager.js +37 -95
  193. package/dist/lib/service/evolution/createSupersedeProposal.d.ts +1 -1
  194. package/dist/lib/service/evolution/createSupersedeProposal.js +7 -8
  195. package/dist/lib/service/guard/CoverageAnalyzer.d.ts +3 -7
  196. package/dist/lib/service/guard/CoverageAnalyzer.js +9 -11
  197. package/dist/lib/service/guard/GuardCheckEngine.d.ts +3 -0
  198. package/dist/lib/service/guard/GuardCheckEngine.js +14 -22
  199. package/dist/lib/service/guard/ReverseGuard.d.ts +4 -7
  200. package/dist/lib/service/guard/ReverseGuard.js +21 -31
  201. package/dist/lib/service/guard/ViolationsStore.d.ts +15 -21
  202. package/dist/lib/service/guard/ViolationsStore.js +75 -69
  203. package/dist/lib/service/knowledge/CodeEntityGraph.d.ts +45 -63
  204. package/dist/lib/service/knowledge/CodeEntityGraph.js +418 -496
  205. package/dist/lib/service/knowledge/ConfidenceRouter.js +18 -9
  206. package/dist/lib/service/knowledge/KnowledgeFileWriter.d.ts +2 -1
  207. package/dist/lib/service/knowledge/KnowledgeGraphService.d.ts +18 -60
  208. package/dist/lib/service/knowledge/KnowledgeGraphService.js +58 -109
  209. package/dist/lib/service/knowledge/KnowledgeService.d.ts +15 -1
  210. package/dist/lib/service/knowledge/KnowledgeService.js +97 -46
  211. package/dist/lib/service/knowledge/RecipeProductionGateway.d.ts +0 -2
  212. package/dist/lib/service/knowledge/RecipeProductionGateway.js +0 -2
  213. package/dist/lib/service/knowledge/SourceRefReconciler.d.ts +5 -13
  214. package/dist/lib/service/knowledge/SourceRefReconciler.js +58 -78
  215. package/dist/lib/service/module/ModuleService.js +10 -19
  216. package/dist/lib/service/panorama/CouplingAnalyzer.d.ts +14 -3
  217. package/dist/lib/service/panorama/CouplingAnalyzer.js +137 -32
  218. package/dist/lib/service/panorama/DimensionAnalyzer.d.ts +7 -4
  219. package/dist/lib/service/panorama/DimensionAnalyzer.js +94 -33
  220. package/dist/lib/service/panorama/LayerInferrer.d.ts +16 -1
  221. package/dist/lib/service/panorama/LayerInferrer.js +118 -1
  222. package/dist/lib/service/panorama/ModuleDiscoverer.d.ts +14 -4
  223. package/dist/lib/service/panorama/ModuleDiscoverer.js +209 -61
  224. package/dist/lib/service/panorama/PanoramaAggregator.d.ts +15 -4
  225. package/dist/lib/service/panorama/PanoramaAggregator.js +128 -62
  226. package/dist/lib/service/panorama/PanoramaScanner.d.ts +5 -1
  227. package/dist/lib/service/panorama/PanoramaScanner.js +60 -31
  228. package/dist/lib/service/panorama/PanoramaService.d.ts +11 -8
  229. package/dist/lib/service/panorama/PanoramaService.js +49 -69
  230. package/dist/lib/service/panorama/PanoramaTypes.d.ts +41 -0
  231. package/dist/lib/service/panorama/RoleRefiner.d.ts +10 -5
  232. package/dist/lib/service/panorama/RoleRefiner.js +92 -282
  233. package/dist/lib/service/panorama/TechStackProfiler.d.ts +13 -0
  234. package/dist/lib/service/panorama/TechStackProfiler.js +79 -0
  235. package/dist/lib/service/quality/QualityScorer.d.ts +45 -26
  236. package/dist/lib/service/quality/QualityScorer.js +157 -83
  237. package/dist/lib/service/search/SearchEngine.d.ts +1 -0
  238. package/dist/lib/service/search/SearchEngine.js +32 -37
  239. package/dist/lib/service/signal/HitRecorder.js +5 -5
  240. package/dist/lib/service/skills/RuleRecallStrategy.js +7 -3
  241. package/dist/lib/service/skills/SignalCollector.d.ts +6 -8
  242. package/dist/lib/service/skills/SignalCollector.js +34 -60
  243. package/dist/lib/service/skills/SkillAdvisor.d.ts +7 -13
  244. package/dist/lib/service/skills/SkillAdvisor.js +30 -79
  245. package/dist/lib/service/vector/ContextualEnricher.d.ts +1 -0
  246. package/dist/lib/service/vector/ContextualEnricher.js +4 -0
  247. package/dist/lib/service/vector/SyncCoordinator.d.ts +3 -1
  248. package/dist/lib/service/vector/SyncCoordinator.js +25 -3
  249. package/dist/lib/service/vector/VectorService.d.ts +2 -0
  250. package/dist/lib/service/vector/VectorService.js +3 -0
  251. package/dist/lib/service/wiki/WikiGenerator.js +1 -1
  252. package/dist/lib/shared/LanguageProfiles.d.ts +109 -0
  253. package/dist/lib/shared/LanguageProfiles.js +939 -0
  254. package/dist/lib/shared/LanguageService.d.ts +6 -0
  255. package/dist/lib/shared/LanguageService.js +19 -0
  256. package/dist/lib/shared/constants.d.ts +19 -19
  257. package/dist/lib/shared/constants.js +10 -10
  258. package/dist/lib/shared/developer-identity.d.ts +18 -0
  259. package/dist/lib/shared/developer-identity.js +62 -0
  260. package/dist/lib/shared/schemas/http-requests.d.ts +8 -17
  261. package/dist/lib/shared/schemas/http-requests.js +9 -6
  262. package/dist/lib/shared/schemas/mcp-tools.d.ts +1 -1
  263. package/dist/lib/types/knowledge-wire.d.ts +1 -0
  264. package/dist/lib/types/project-snapshot-builder.d.ts +0 -1
  265. package/dist/lib/types/project-snapshot-builder.js +0 -1
  266. package/dist/lib/types/project-snapshot.d.ts +0 -1
  267. package/dist/lib/types/project-snapshot.js +0 -1
  268. package/dist/lib/types/snapshot-views.d.ts +0 -2
  269. package/dist/lib/types/snapshot-views.js +0 -1
  270. package/package.json +2 -1
  271. package/dashboard/dist/assets/icons-D1aVZYFW.js +0 -1
  272. package/dashboard/dist/assets/index-CxHOu8Hd.css +0 -1
  273. package/dashboard/dist/assets/index-DDdAOpYT.js +0 -128
  274. package/dist/lib/repository/base/BaseRepository.d.ts +0 -53
  275. package/dist/lib/repository/base/BaseRepository.js +0 -226
@@ -0,0 +1,171 @@
1
+ /**
2
+ * @module GradleDslParser
3
+ * @description Gradle DSL 轻量解析器 — 从 settings.gradle.kts / build.gradle.kts 提取项目拓扑
4
+ *
5
+ * 支持解析:
6
+ * - settings.gradle.kts: rootProject.name + include() 模块声明
7
+ * - build.gradle.kts: plugins {} + dependencies {} (project-to-project)
8
+ * - settings.gradle (Groovy 语法)
9
+ *
10
+ * 同时支持 Kotlin DSL 和 Groovy DSL 的正则模式。
11
+ */
12
+ // ── settings.gradle 解析模式 ─────────────────────────
13
+ const SETTINGS_ROOT_NAME_KT = /rootProject\.name\s*=\s*"([^"]+)"/;
14
+ const SETTINGS_ROOT_NAME_GR = /rootProject\.name\s*=\s*'([^']+)'/;
15
+ // Kotlin DSL: include(":core:network") 或 include(":app", ":core")
16
+ const INCLUDE_KT = /include\(\s*((?:"[^"]+"(?:\s*,\s*)?)+)\s*\)/g;
17
+ // Groovy DSL: include ':core:network' 或 include ':app', ':core'
18
+ const INCLUDE_GR = /include\s+((?:'[^']+'(?:\s*,\s*)?)+)/g;
19
+ // ── build.gradle 解析模式 ────────────────────────────
20
+ // Kotlin DSL: id("myapp.android.feature")
21
+ const PLUGIN_KT = /id\(\s*"([^"]+)"\s*\)/g;
22
+ // Groovy DSL: id 'myapp.android.feature'
23
+ const PLUGIN_GR = /id\s+'([^']+)'/g;
24
+ // Kotlin DSL: implementation(project(":core:network"))
25
+ const PROJECT_DEP_KT = /(implementation|api|compileOnly|testImplementation|runtimeOnly|kapt|ksp)\s*\(\s*project\(\s*"([^"]+)"\s*\)\s*\)/g;
26
+ // Groovy DSL: implementation project(':core:network')
27
+ const PROJECT_DEP_GR = /(implementation|api|compileOnly|testImplementation|runtimeOnly|kapt|ksp)\s+project\(\s*['"]([^'"]+)['"]\s*\)/g;
28
+ // kotlin("multiplatform") plugin detection
29
+ const KMP_PLUGIN_RE = /kotlin\(\s*"multiplatform"\s*\)/;
30
+ // ── 公开 API ────────────────────────────────────────
31
+ /**
32
+ * 解析 settings.gradle.kts / settings.gradle 内容
33
+ * 提取 rootProject 名和所有 include 模块
34
+ *
35
+ * 当传入 build 文件内容时(附带 module 参数),解析 plugins 和 dependencies 到该模块上
36
+ */
37
+ export function parseGradleProject(content, existingModule) {
38
+ const result = {
39
+ rootProjectName: '',
40
+ includedModules: [],
41
+ };
42
+ // 如果传入了 existingModule,解析 build 文件内容
43
+ if (existingModule) {
44
+ const updatedMod = parseBuildFileForModule(content, existingModule);
45
+ result.includedModules = [updatedMod];
46
+ return result;
47
+ }
48
+ // 解析 rootProject.name
49
+ const rootNameKt = content.match(SETTINGS_ROOT_NAME_KT);
50
+ const rootNameGr = content.match(SETTINGS_ROOT_NAME_GR);
51
+ result.rootProjectName = rootNameKt?.[1] ?? rootNameGr?.[1] ?? '';
52
+ // 解析 include 声明
53
+ const modules = new Map();
54
+ // Kotlin DSL includes
55
+ const ktContent = content;
56
+ let m;
57
+ const ktIncludeRe = new RegExp(INCLUDE_KT.source, 'g');
58
+ while ((m = ktIncludeRe.exec(ktContent)) !== null) {
59
+ const innerStr = m[1];
60
+ const pathRe = /"([^"]+)"/g;
61
+ let pathMatch;
62
+ while ((pathMatch = pathRe.exec(innerStr)) !== null) {
63
+ const modPath = pathMatch[1];
64
+ if (!modules.has(modPath)) {
65
+ modules.set(modPath, {
66
+ path: modPath,
67
+ directory: modPath.replace(/^:/, '').replace(/:/g, '/'),
68
+ dependencies: [],
69
+ });
70
+ }
71
+ }
72
+ }
73
+ // Groovy DSL includes
74
+ const grIncludeRe = new RegExp(INCLUDE_GR.source, 'g');
75
+ while ((m = grIncludeRe.exec(content)) !== null) {
76
+ const innerStr = m[1];
77
+ const pathRe = /'([^']+)'/g;
78
+ let pathMatch;
79
+ while ((pathMatch = pathRe.exec(innerStr)) !== null) {
80
+ const modPath = pathMatch[1];
81
+ if (!modules.has(modPath)) {
82
+ modules.set(modPath, {
83
+ path: modPath,
84
+ directory: modPath.replace(/^:/, '').replace(/:/g, '/'),
85
+ dependencies: [],
86
+ });
87
+ }
88
+ }
89
+ }
90
+ // 检测 version catalog
91
+ if (content.includes('libs.versions.toml') || content.includes('versionCatalogs')) {
92
+ result.versionCatalog = 'gradle/libs.versions.toml';
93
+ }
94
+ result.includedModules = [...modules.values()];
95
+ return result;
96
+ }
97
+ /**
98
+ * 检测 build 文件中是否使用了 Kotlin Multiplatform 插件
99
+ */
100
+ export function isKmpBuildFile(content) {
101
+ return KMP_PLUGIN_RE.test(content);
102
+ }
103
+ // ── 内部函数 ────────────────────────────────────────
104
+ function parseBuildFileForModule(content, module) {
105
+ const result = { ...module, dependencies: [] };
106
+ // 提取 convention plugin
107
+ const pluginKtRe = new RegExp(PLUGIN_KT.source, 'g');
108
+ const pluginGrRe = new RegExp(PLUGIN_GR.source, 'g');
109
+ let m;
110
+ while ((m = pluginKtRe.exec(content)) !== null) {
111
+ const pluginId = m[1];
112
+ // Convention plugins 通常是项目自定义的(包含项目名前缀)
113
+ if (pluginId.includes('.') &&
114
+ !pluginId.startsWith('com.android') &&
115
+ !pluginId.startsWith('org.jetbrains')) {
116
+ result.conventionPlugin = pluginId;
117
+ break;
118
+ }
119
+ }
120
+ if (!result.conventionPlugin) {
121
+ while ((m = pluginGrRe.exec(content)) !== null) {
122
+ const pluginId = m[1];
123
+ if (pluginId.includes('.') &&
124
+ !pluginId.startsWith('com.android') &&
125
+ !pluginId.startsWith('org.jetbrains')) {
126
+ result.conventionPlugin = pluginId;
127
+ break;
128
+ }
129
+ }
130
+ }
131
+ // 提取 project dependencies
132
+ const depKtRe = new RegExp(PROJECT_DEP_KT.source, 'g');
133
+ const depGrRe = new RegExp(PROJECT_DEP_GR.source, 'g');
134
+ while ((m = depKtRe.exec(content)) !== null) {
135
+ result.dependencies.push({
136
+ configuration: m[1],
137
+ target: m[2],
138
+ isProject: true,
139
+ });
140
+ }
141
+ while ((m = depGrRe.exec(content)) !== null) {
142
+ result.dependencies.push({
143
+ configuration: m[1],
144
+ target: m[2],
145
+ isProject: true,
146
+ });
147
+ }
148
+ return result;
149
+ }
150
+ /**
151
+ * 从 convention plugin id 推断模块角色
152
+ * 例: "myapp.android.feature" → "feature"
153
+ */
154
+ export function inferConventionRole(pluginId) {
155
+ const parts = pluginId.split('.');
156
+ const last = parts[parts.length - 1];
157
+ const ROLE_KEYWORDS = {
158
+ feature: 'feature',
159
+ library: 'library',
160
+ app: 'application',
161
+ application: 'application',
162
+ core: 'core',
163
+ data: 'data',
164
+ domain: 'domain',
165
+ ui: 'ui',
166
+ test: 'test',
167
+ compose: 'compose',
168
+ hilt: 'di',
169
+ };
170
+ return ROLE_KEYWORDS[last] ?? undefined;
171
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @module JsonConfigParser
3
+ * @description JSON 配置文件解析器 — 支持 Nx project.json、Flutter 插件依赖、React Native 检测
4
+ *
5
+ * 每个解析函数接受文件内容字符串,返回类型化结果。
6
+ */
7
+ export interface ParsedNxWorkspace {
8
+ projects: NxProject[];
9
+ }
10
+ export interface NxProject {
11
+ name: string;
12
+ root: string;
13
+ projectType: string;
14
+ tags: string[];
15
+ }
16
+ export interface ParsedFlutterPluginsDeps {
17
+ plugins: FlutterPlugin[];
18
+ flutterSdkVersion?: string;
19
+ }
20
+ export interface FlutterPlugin {
21
+ name: string;
22
+ path: string;
23
+ platform: string;
24
+ }
25
+ export interface ParsedReactNativeProject {
26
+ isReactNative: boolean;
27
+ name: string;
28
+ rnVersion?: string;
29
+ hasFabric?: boolean;
30
+ hasTurboModules?: boolean;
31
+ }
32
+ /**
33
+ * 解析 Nx project.json 内容
34
+ * 每个 project.json 描述一个项目
35
+ */
36
+ export declare function parseNxWorkspace(content: string): ParsedNxWorkspace;
37
+ /**
38
+ * 解析 .flutter-plugins-dependencies 文件内容
39
+ * 该文件由 Flutter 工具链自动生成
40
+ */
41
+ export declare function parseFlutterPluginsDeps(content: string): ParsedFlutterPluginsDeps;
42
+ /**
43
+ * 解析 package.json 内容,判断是否是 React Native 项目
44
+ */
45
+ export declare function parseReactNativeProject(content: string): ParsedReactNativeProject;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @module JsonConfigParser
3
+ * @description JSON 配置文件解析器 — 支持 Nx project.json、Flutter 插件依赖、React Native 检测
4
+ *
5
+ * 每个解析函数接受文件内容字符串,返回类型化结果。
6
+ */
7
+ // ── Nx 解析 ─────────────────────────────────────────
8
+ /**
9
+ * 解析 Nx project.json 内容
10
+ * 每个 project.json 描述一个项目
11
+ */
12
+ export function parseNxWorkspace(content) {
13
+ const result = { projects: [] };
14
+ try {
15
+ const json = JSON.parse(content);
16
+ const name = json.name ?? '';
17
+ const root = json.root ?? json.sourceRoot ?? '.';
18
+ const projectType = json.projectType ?? 'library';
19
+ const tags = Array.isArray(json.tags) ? json.tags : [];
20
+ if (name) {
21
+ result.projects.push({ name, root, projectType, tags });
22
+ }
23
+ }
24
+ catch {
25
+ // JSON 解析失败时返回空结果
26
+ }
27
+ return result;
28
+ }
29
+ // ── Flutter 解析 ────────────────────────────────────
30
+ /**
31
+ * 解析 .flutter-plugins-dependencies 文件内容
32
+ * 该文件由 Flutter 工具链自动生成
33
+ */
34
+ export function parseFlutterPluginsDeps(content) {
35
+ const result = { plugins: [] };
36
+ try {
37
+ const json = JSON.parse(content);
38
+ // dependencyGraph 数组包含 Flutter embedding 信息
39
+ const depGraph = json.dependencyGraph;
40
+ if (Array.isArray(depGraph)) {
41
+ for (const entry of depGraph) {
42
+ if (typeof entry === 'object' && entry !== null) {
43
+ const rec = entry;
44
+ const name = rec.name ?? '';
45
+ if (name && name !== 'flutter') {
46
+ result.plugins.push({
47
+ name,
48
+ path: rec.path ?? '',
49
+ platform: 'flutter',
50
+ });
51
+ }
52
+ }
53
+ }
54
+ }
55
+ // 也解析 plugins.ios / plugins.android 中的平台插件
56
+ const plugins = json.plugins;
57
+ if (typeof plugins === 'object' && plugins !== null) {
58
+ const platformPlugins = plugins;
59
+ for (const [platform, list] of Object.entries(platformPlugins)) {
60
+ if (Array.isArray(list)) {
61
+ for (const p of list) {
62
+ if (typeof p === 'object' && p !== null) {
63
+ const rec = p;
64
+ const name = rec.name ?? '';
65
+ // 避免重复
66
+ if (name &&
67
+ !result.plugins.some((existing) => existing.name === name && existing.platform === platform)) {
68
+ result.plugins.push({
69
+ name,
70
+ path: rec.path ?? '',
71
+ platform,
72
+ });
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ // Flutter SDK 版本
80
+ if (typeof json.flutterVersion === 'string') {
81
+ result.flutterSdkVersion = json.flutterVersion;
82
+ }
83
+ }
84
+ catch {
85
+ // JSON 解析失败时返回空结果
86
+ }
87
+ return result;
88
+ }
89
+ // ── React Native 解析 ──────────────────────────────
90
+ /**
91
+ * 解析 package.json 内容,判断是否是 React Native 项目
92
+ */
93
+ export function parseReactNativeProject(content) {
94
+ const result = {
95
+ isReactNative: false,
96
+ name: '',
97
+ };
98
+ try {
99
+ const json = JSON.parse(content);
100
+ result.name = json.name ?? '';
101
+ const deps = (json.dependencies ?? {});
102
+ const devDeps = (json.devDependencies ?? {});
103
+ if (deps['react-native'] || devDeps['react-native']) {
104
+ result.isReactNative = true;
105
+ result.rnVersion = deps['react-native'] ?? devDeps['react-native'];
106
+ }
107
+ // Fabric (new architecture) 检测
108
+ if (result.isReactNative) {
109
+ const scripts = (json.scripts ?? {});
110
+ result.hasFabric =
111
+ deps['react-native-codegen'] !== undefined ||
112
+ Object.values(scripts).some((s) => s.includes('codegen'));
113
+ // TurboModules 检测
114
+ result.hasTurboModules =
115
+ typeof json.codegenConfig === 'object' || deps['react-native-turbo-modules'] !== undefined;
116
+ }
117
+ }
118
+ catch {
119
+ // JSON 解析失败时返回空结果
120
+ }
121
+ return result;
122
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @module RubyDslParser
3
+ * @description Ruby DSL 轻量解析器 — 从 Boxfile / podspec 类文件中提取项目结构信息
4
+ *
5
+ * 不需要完整的 Ruby 解析器,使用正则 + 上下文状态机提取:
6
+ * - 层级 (layer) 声明与层间访问规则
7
+ * - 模块 (box) 声明(本地/远程)
8
+ * - 宿主应用信息
9
+ * - 模块级 spec 依赖/源文件路径
10
+ *
11
+ * 支持 EasyBox (Boxfile + *.boxspec) 和结构类似的自研工具。
12
+ */
13
+ export interface ParsedModule {
14
+ name: string;
15
+ version: string;
16
+ isLocal: boolean;
17
+ localPath?: string;
18
+ group?: string;
19
+ }
20
+ export interface ParsedLayer {
21
+ name: string;
22
+ order: number;
23
+ accessibleLayers: string[];
24
+ modules: ParsedModule[];
25
+ }
26
+ export interface ParsedProjectConfig {
27
+ hostApp?: {
28
+ name: string;
29
+ version: string;
30
+ };
31
+ layers: ParsedLayer[];
32
+ globalDependencies: ParsedModule[];
33
+ }
34
+ export interface ParsedModuleSpec {
35
+ name: string;
36
+ version: string;
37
+ sources: string;
38
+ dependencies: string[];
39
+ publicHeaders: string[];
40
+ deploymentTarget?: string;
41
+ }
42
+ /**
43
+ * 解析 Boxfile 内容,提取层级、模块、宿主应用信息
44
+ */
45
+ export declare function parseBoxfile(content: string): ParsedProjectConfig;
46
+ /**
47
+ * 解析 boxspec/podspec 文件内容,提取模块元数据
48
+ */
49
+ export declare function parseModuleSpec(content: string): ParsedModuleSpec;
@@ -0,0 +1,282 @@
1
+ /**
2
+ * @module RubyDslParser
3
+ * @description Ruby DSL 轻量解析器 — 从 Boxfile / podspec 类文件中提取项目结构信息
4
+ *
5
+ * 不需要完整的 Ruby 解析器,使用正则 + 上下文状态机提取:
6
+ * - 层级 (layer) 声明与层间访问规则
7
+ * - 模块 (box) 声明(本地/远程)
8
+ * - 宿主应用信息
9
+ * - 模块级 spec 依赖/源文件路径
10
+ *
11
+ * 支持 EasyBox (Boxfile + *.boxspec) 和结构类似的自研工具。
12
+ */
13
+ // ── Boxfile 解析 ────────────────────────────────────
14
+ /**
15
+ * 解析 Boxfile 内容,提取层级、模块、宿主应用信息
16
+ */
17
+ export function parseBoxfile(content) {
18
+ const result = {
19
+ layers: [],
20
+ globalDependencies: [],
21
+ };
22
+ // 提取 host_app
23
+ const hostAppMatch = content.match(/host_app\s+['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]+)['"])?/);
24
+ if (hostAppMatch) {
25
+ result.hostApp = {
26
+ name: hostAppMatch[1],
27
+ version: hostAppMatch[2] || '0.0.0',
28
+ };
29
+ }
30
+ // 按 layer block 分割解析
31
+ const layerBlocks = extractLayerBlocks(content);
32
+ let layerOrder = 0;
33
+ for (const block of layerBlocks) {
34
+ const layer = {
35
+ name: block.name,
36
+ order: layerOrder++,
37
+ accessibleLayers: extractAccessLayers(block.body),
38
+ modules: extractModules(block.body),
39
+ };
40
+ result.layers.push(layer);
41
+ }
42
+ // 提取 layer 外层的全局模块声明
43
+ const outsideLayerContent = removeLayerBlocks(content);
44
+ result.globalDependencies = extractModules(outsideLayerContent);
45
+ return result;
46
+ }
47
+ // ── *.boxspec / *.podspec 解析 ────────────────────────
48
+ /**
49
+ * 解析 boxspec/podspec 文件内容,提取模块元数据
50
+ */
51
+ export function parseModuleSpec(content) {
52
+ return {
53
+ name: extractSpecField(content, 'name') || 'unknown',
54
+ version: extractSpecField(content, 'version') || '0.0.0',
55
+ sources: extractSpecField(content, 'source_files') ||
56
+ extractSpecField(content, 'sources') ||
57
+ extractSpecField(content, 'source') ||
58
+ '',
59
+ dependencies: extractSpecDependencies(content),
60
+ publicHeaders: extractSpecArrayField(content, 'public_headers') ||
61
+ extractSpecArrayField(content, 'public_header_files') ||
62
+ [],
63
+ deploymentTarget: extractSpecDeploymentTarget(content),
64
+ };
65
+ }
66
+ /**
67
+ * 提取所有 layer 'Name' do ... end 块
68
+ * 使用 do/end 嵌套计数处理嵌套 block
69
+ */
70
+ function extractLayerBlocks(content) {
71
+ const blocks = [];
72
+ const layerRe = /layer\s+['"](\w+)['"]\s+do\b/g;
73
+ let match;
74
+ while ((match = layerRe.exec(content)) !== null) {
75
+ const name = match[1];
76
+ const startIndex = match.index;
77
+ const bodyStart = match.index + match[0].length;
78
+ const endIndex = findMatchingEnd(content, bodyStart);
79
+ if (endIndex === -1) {
80
+ continue;
81
+ }
82
+ blocks.push({
83
+ name,
84
+ body: content.substring(bodyStart, endIndex),
85
+ startIndex,
86
+ endIndex: endIndex + 3, // 'end' is 3 chars
87
+ });
88
+ }
89
+ return blocks;
90
+ }
91
+ /**
92
+ * 从 do 之后的位置开始,找到匹配的 end
93
+ * 处理嵌套的 do...end 块(如 group do ... end)
94
+ */
95
+ function findMatchingEnd(content, startPos) {
96
+ let depth = 1;
97
+ // 逐行扫描以正确识别 do/end 关键字(避免匹配字符串内的)
98
+ const lines = content.substring(startPos).split('\n');
99
+ let pos = startPos;
100
+ for (const line of lines) {
101
+ const trimmed = line.trim();
102
+ // 跳过注释行
103
+ if (trimmed.startsWith('#')) {
104
+ pos += line.length + 1;
105
+ continue;
106
+ }
107
+ // 计算该行的 do 和 end
108
+ // 匹配行尾的 do(不匹配字符串内的)
109
+ if (/\bdo\b\s*(?:#.*)?$/.test(trimmed)) {
110
+ depth++;
111
+ }
112
+ // 匹配行首的 end(独立的 end 关键字)
113
+ if (/^\s*end\b/.test(line)) {
114
+ depth--;
115
+ if (depth === 0) {
116
+ return pos;
117
+ }
118
+ }
119
+ pos += line.length + 1;
120
+ }
121
+ return -1;
122
+ }
123
+ /**
124
+ * 移除所有 layer 块,返回剩余内容(用于提取全局模块)
125
+ */
126
+ function removeLayerBlocks(content) {
127
+ const blocks = extractLayerBlocks(content);
128
+ if (blocks.length === 0) {
129
+ return content;
130
+ }
131
+ let result = '';
132
+ let lastEnd = 0;
133
+ for (const block of blocks) {
134
+ result += content.substring(lastEnd, block.startIndex);
135
+ lastEnd = block.endIndex;
136
+ }
137
+ result += content.substring(lastEnd);
138
+ return result;
139
+ }
140
+ // ── Box/模块提取 ────────────────────────────────────
141
+ /**
142
+ * 从内容中提取所有 box 声明
143
+ *
144
+ * 支持格式:
145
+ * box 'Name', 'Version'
146
+ * box 'Name', :path => 'LocalModule/Name'
147
+ * box 'Name', path: 'LocalModule/Name'
148
+ * box 'Name', '~> 1.0', :path => '...'
149
+ */
150
+ function extractModules(content) {
151
+ const modules = [];
152
+ const seen = new Set();
153
+ // 当前 group 上下文跟踪
154
+ let currentGroup;
155
+ const lines = content.split('\n');
156
+ for (const line of lines) {
157
+ const trimmed = line.trim();
158
+ // 跳过注释
159
+ if (trimmed.startsWith('#')) {
160
+ continue;
161
+ }
162
+ // 检查 group 开始
163
+ const groupMatch = trimmed.match(/group\s+['"]([^'"]+)['"]\s+do/);
164
+ if (groupMatch) {
165
+ currentGroup = groupMatch[1];
166
+ continue;
167
+ }
168
+ // 检查 group/layer 结束
169
+ if (/^\s*end\b/.test(line) && currentGroup) {
170
+ currentGroup = undefined;
171
+ continue;
172
+ }
173
+ // 解析 box 声明
174
+ const boxMatch = trimmed.match(/^box\s+['"]([^'"]+)['"]/);
175
+ if (!boxMatch) {
176
+ continue;
177
+ }
178
+ const name = boxMatch[1];
179
+ if (seen.has(name)) {
180
+ continue;
181
+ }
182
+ seen.add(name);
183
+ const rest = trimmed.substring(boxMatch[0].length);
184
+ // 检查是否有 :path(本地模块)
185
+ const pathMatch = rest.match(/:path\s*=>\s*['"]([^'"]+)['"]|path:\s*['"]([^'"]+)['"]/);
186
+ const isLocal = pathMatch !== null;
187
+ const localPath = pathMatch ? pathMatch[1] || pathMatch[2] : undefined;
188
+ // 提取版本号
189
+ let version = '';
190
+ const versionMatch = rest.match(/,\s*['"]([^'"]+)['"]/);
191
+ if (versionMatch && !versionMatch[1].includes('/')) {
192
+ version = versionMatch[1];
193
+ }
194
+ modules.push({
195
+ name,
196
+ version,
197
+ isLocal,
198
+ localPath,
199
+ group: currentGroup,
200
+ });
201
+ }
202
+ return modules;
203
+ }
204
+ // ── Access 规则提取 ─────────────────────────────────
205
+ /**
206
+ * 提取 access 声明中的层名列表
207
+ *
208
+ * 支持格式:
209
+ * access 'Layer1', 'Layer2', 'Layer3'
210
+ * access "Layer1", "Layer2"
211
+ */
212
+ function extractAccessLayers(content) {
213
+ const layers = [];
214
+ const accessRe = /access\s+(.+)/g;
215
+ let match;
216
+ while ((match = accessRe.exec(content)) !== null) {
217
+ const rest = match[1];
218
+ const nameRe = /['"]([^'"]+)['"]/g;
219
+ let nameMatch;
220
+ while ((nameMatch = nameRe.exec(rest)) !== null) {
221
+ if (!layers.includes(nameMatch[1])) {
222
+ layers.push(nameMatch[1]);
223
+ }
224
+ }
225
+ }
226
+ return layers;
227
+ }
228
+ // ── Spec 字段提取 ───────────────────────────────────
229
+ /**
230
+ * 从 podspec/boxspec 中提取单值字段
231
+ * 支持: s.name = 'Value' 和 spec.name = 'Value'
232
+ */
233
+ function extractSpecField(content, field) {
234
+ const re = new RegExp(`\\b\\w+\\.${field}\\s*=\\s*['"]([^'"]+)['"]`, 'i');
235
+ const match = content.match(re);
236
+ return match ? match[1] : undefined;
237
+ }
238
+ /**
239
+ * 从 podspec/boxspec 中提取 dependency 声明列表
240
+ *
241
+ * 支持:
242
+ * s.dependency 'ModuleName'
243
+ * s.dependency 'ModuleName', '~> 1.0'
244
+ * s.dependency "ModuleName"
245
+ */
246
+ function extractSpecDependencies(content) {
247
+ const deps = [];
248
+ const re = /\b\w+\.dependency\s+['"]([^'"]+)['"]/g;
249
+ let match;
250
+ while ((match = re.exec(content)) !== null) {
251
+ if (!deps.includes(match[1])) {
252
+ deps.push(match[1]);
253
+ }
254
+ }
255
+ return deps;
256
+ }
257
+ /**
258
+ * 从 podspec/boxspec 中提取数组字段
259
+ * 支持: s.public_headers = ['path1', 'path2']
260
+ */
261
+ function extractSpecArrayField(content, field) {
262
+ const re = new RegExp(`\\b\\w+\\.${field}\\s*=\\s*\\[([^\\]]+)\\]`, 'i');
263
+ const match = content.match(re);
264
+ if (!match) {
265
+ return undefined;
266
+ }
267
+ const items = [];
268
+ const itemRe = /['"]([^'"]+)['"]/g;
269
+ let m;
270
+ while ((m = itemRe.exec(match[1])) !== null) {
271
+ items.push(m[1]);
272
+ }
273
+ return items.length > 0 ? items : undefined;
274
+ }
275
+ /**
276
+ * 提取部署目标版本
277
+ * 支持: s.ios.deployment_target = '13.0'
278
+ */
279
+ function extractSpecDeploymentTarget(content) {
280
+ const match = content.match(/\b\w+\.ios\.deployment_target\s*=\s*['"]([^'"]+)['"]/);
281
+ return match ? match[1] : undefined;
282
+ }