@sudosandwich/limps-headless 0.1.3

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 (335) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +339 -0
  3. package/bin/limps-headless +2 -0
  4. package/dist/analysis/index.d.ts +6 -0
  5. package/dist/analysis/index.d.ts.map +1 -0
  6. package/dist/analysis/index.js +6 -0
  7. package/dist/analysis/index.js.map +1 -0
  8. package/dist/analysis/ir/build-ir.d.ts +10 -0
  9. package/dist/analysis/ir/build-ir.d.ts.map +1 -0
  10. package/dist/analysis/ir/build-ir.js +102 -0
  11. package/dist/analysis/ir/build-ir.js.map +1 -0
  12. package/dist/analysis/ir/types.d.ts +44 -0
  13. package/dist/analysis/ir/types.d.ts.map +1 -0
  14. package/dist/analysis/ir/types.js +2 -0
  15. package/dist/analysis/ir/types.js.map +1 -0
  16. package/dist/analysis/module-graph.d.ts +20 -0
  17. package/dist/analysis/module-graph.d.ts.map +1 -0
  18. package/dist/analysis/module-graph.js +104 -0
  19. package/dist/analysis/module-graph.js.map +1 -0
  20. package/dist/analysis/passes/behavior-evidence.d.ts +9 -0
  21. package/dist/analysis/passes/behavior-evidence.d.ts.map +1 -0
  22. package/dist/analysis/passes/behavior-evidence.js +80 -0
  23. package/dist/analysis/passes/behavior-evidence.js.map +1 -0
  24. package/dist/analysis/passes/import-evidence.d.ts +3 -0
  25. package/dist/analysis/passes/import-evidence.d.ts.map +1 -0
  26. package/dist/analysis/passes/import-evidence.js +58 -0
  27. package/dist/analysis/passes/import-evidence.js.map +1 -0
  28. package/dist/analysis/passes/index.d.ts +15 -0
  29. package/dist/analysis/passes/index.d.ts.map +1 -0
  30. package/dist/analysis/passes/index.js +21 -0
  31. package/dist/analysis/passes/index.js.map +1 -0
  32. package/dist/analysis/passes/jsx-evidence.d.ts +8 -0
  33. package/dist/analysis/passes/jsx-evidence.d.ts.map +1 -0
  34. package/dist/analysis/passes/jsx-evidence.js +149 -0
  35. package/dist/analysis/passes/jsx-evidence.js.map +1 -0
  36. package/dist/analysis/ts-program.d.ts +12 -0
  37. package/dist/analysis/ts-program.d.ts.map +1 -0
  38. package/dist/analysis/ts-program.js +59 -0
  39. package/dist/analysis/ts-program.js.map +1 -0
  40. package/dist/analyzer/disambiguator.d.ts +20 -0
  41. package/dist/analyzer/disambiguator.d.ts.map +1 -0
  42. package/dist/analyzer/disambiguator.js +83 -0
  43. package/dist/analyzer/disambiguator.js.map +1 -0
  44. package/dist/analyzer/index.d.ts +26 -0
  45. package/dist/analyzer/index.d.ts.map +1 -0
  46. package/dist/analyzer/index.js +68 -0
  47. package/dist/analyzer/index.js.map +1 -0
  48. package/dist/analyzer/parser.d.ts +23 -0
  49. package/dist/analyzer/parser.d.ts.map +1 -0
  50. package/dist/analyzer/parser.js +58 -0
  51. package/dist/analyzer/parser.js.map +1 -0
  52. package/dist/analyzer/patterns.d.ts +42 -0
  53. package/dist/analyzer/patterns.d.ts.map +1 -0
  54. package/dist/analyzer/patterns.js +206 -0
  55. package/dist/analyzer/patterns.js.map +1 -0
  56. package/dist/analyzer/props.d.ts +16 -0
  57. package/dist/analyzer/props.d.ts.map +1 -0
  58. package/dist/analyzer/props.js +235 -0
  59. package/dist/analyzer/props.js.map +1 -0
  60. package/dist/analyzer/rules/checkbox-switch-toggle.d.ts +10 -0
  61. package/dist/analyzer/rules/checkbox-switch-toggle.d.ts.map +1 -0
  62. package/dist/analyzer/rules/checkbox-switch-toggle.js +26 -0
  63. package/dist/analyzer/rules/checkbox-switch-toggle.js.map +1 -0
  64. package/dist/analyzer/rules/dialog-popover.d.ts +10 -0
  65. package/dist/analyzer/rules/dialog-popover.d.ts.map +1 -0
  66. package/dist/analyzer/rules/dialog-popover.js +25 -0
  67. package/dist/analyzer/rules/dialog-popover.js.map +1 -0
  68. package/dist/analyzer/rules/index.d.ts +24 -0
  69. package/dist/analyzer/rules/index.d.ts.map +1 -0
  70. package/dist/analyzer/rules/index.js +51 -0
  71. package/dist/analyzer/rules/index.js.map +1 -0
  72. package/dist/analyzer/rules/tooltip-hovercard.d.ts +10 -0
  73. package/dist/analyzer/rules/tooltip-hovercard.d.ts.map +1 -0
  74. package/dist/analyzer/rules/tooltip-hovercard.js +21 -0
  75. package/dist/analyzer/rules/tooltip-hovercard.js.map +1 -0
  76. package/dist/analyzer/scorer.d.ts +12 -0
  77. package/dist/analyzer/scorer.d.ts.map +1 -0
  78. package/dist/analyzer/scorer.js +171 -0
  79. package/dist/analyzer/scorer.js.map +1 -0
  80. package/dist/analyzer/weights.d.ts +28 -0
  81. package/dist/analyzer/weights.d.ts.map +1 -0
  82. package/dist/analyzer/weights.js +40 -0
  83. package/dist/analyzer/weights.js.map +1 -0
  84. package/dist/audit/analyses/migration.d.ts +42 -0
  85. package/dist/audit/analyses/migration.d.ts.map +1 -0
  86. package/dist/audit/analyses/migration.js +91 -0
  87. package/dist/audit/analyses/migration.js.map +1 -0
  88. package/dist/audit/discover-components.d.ts +7 -0
  89. package/dist/audit/discover-components.d.ts.map +1 -0
  90. package/dist/audit/discover-components.js +486 -0
  91. package/dist/audit/discover-components.js.map +1 -0
  92. package/dist/audit/generate-report.d.ts +28 -0
  93. package/dist/audit/generate-report.d.ts.map +1 -0
  94. package/dist/audit/generate-report.js +333 -0
  95. package/dist/audit/generate-report.js.map +1 -0
  96. package/dist/audit/index.d.ts +8 -0
  97. package/dist/audit/index.d.ts.map +1 -0
  98. package/dist/audit/index.js +8 -0
  99. package/dist/audit/index.js.map +1 -0
  100. package/dist/audit/run-audit.d.ts +33 -0
  101. package/dist/audit/run-audit.d.ts.map +1 -0
  102. package/dist/audit/run-audit.js +287 -0
  103. package/dist/audit/run-audit.js.map +1 -0
  104. package/dist/audit/types.d.ts +135 -0
  105. package/dist/audit/types.d.ts.map +1 -0
  106. package/dist/audit/types.js +5 -0
  107. package/dist/audit/types.js.map +1 -0
  108. package/dist/cache/index.d.ts +110 -0
  109. package/dist/cache/index.d.ts.map +1 -0
  110. package/dist/cache/index.js +176 -0
  111. package/dist/cache/index.js.map +1 -0
  112. package/dist/cache/storage.d.ts +73 -0
  113. package/dist/cache/storage.d.ts.map +1 -0
  114. package/dist/cache/storage.js +176 -0
  115. package/dist/cache/storage.js.map +1 -0
  116. package/dist/cache/ttl.d.ts +62 -0
  117. package/dist/cache/ttl.d.ts.map +1 -0
  118. package/dist/cache/ttl.js +96 -0
  119. package/dist/cache/ttl.js.map +1 -0
  120. package/dist/cli/commands/analyze.d.ts +6 -0
  121. package/dist/cli/commands/analyze.d.ts.map +1 -0
  122. package/dist/cli/commands/analyze.js +43 -0
  123. package/dist/cli/commands/analyze.js.map +1 -0
  124. package/dist/cli/commands/audit.d.ts +6 -0
  125. package/dist/cli/commands/audit.d.ts.map +1 -0
  126. package/dist/cli/commands/audit.js +73 -0
  127. package/dist/cli/commands/audit.js.map +1 -0
  128. package/dist/cli/commands/check-updates.d.ts +6 -0
  129. package/dist/cli/commands/check-updates.d.ts.map +1 -0
  130. package/dist/cli/commands/check-updates.js +34 -0
  131. package/dist/cli/commands/check-updates.js.map +1 -0
  132. package/dist/cli/commands/diff.d.ts +7 -0
  133. package/dist/cli/commands/diff.d.ts.map +1 -0
  134. package/dist/cli/commands/diff.js +48 -0
  135. package/dist/cli/commands/diff.js.map +1 -0
  136. package/dist/cli/commands/extract.d.ts +6 -0
  137. package/dist/cli/commands/extract.d.ts.map +1 -0
  138. package/dist/cli/commands/extract.js +42 -0
  139. package/dist/cli/commands/extract.js.map +1 -0
  140. package/dist/cli/commands/list.d.ts +6 -0
  141. package/dist/cli/commands/list.d.ts.map +1 -0
  142. package/dist/cli/commands/list.js +33 -0
  143. package/dist/cli/commands/list.js.map +1 -0
  144. package/dist/cli/flags.d.ts +9 -0
  145. package/dist/cli/flags.d.ts.map +1 -0
  146. package/dist/cli/flags.js +22 -0
  147. package/dist/cli/flags.js.map +1 -0
  148. package/dist/cli/index.d.ts +5 -0
  149. package/dist/cli/index.d.ts.map +1 -0
  150. package/dist/cli/index.js +40 -0
  151. package/dist/cli/index.js.map +1 -0
  152. package/dist/config.d.ts +19 -0
  153. package/dist/config.d.ts.map +1 -0
  154. package/dist/config.js +23 -0
  155. package/dist/config.js.map +1 -0
  156. package/dist/differ/hints.d.ts +21 -0
  157. package/dist/differ/hints.d.ts.map +1 -0
  158. package/dist/differ/hints.js +105 -0
  159. package/dist/differ/hints.js.map +1 -0
  160. package/dist/differ/index.d.ts +25 -0
  161. package/dist/differ/index.d.ts.map +1 -0
  162. package/dist/differ/index.js +115 -0
  163. package/dist/differ/index.js.map +1 -0
  164. package/dist/differ/props.d.ts +36 -0
  165. package/dist/differ/props.d.ts.map +1 -0
  166. package/dist/differ/props.js +210 -0
  167. package/dist/differ/props.js.map +1 -0
  168. package/dist/differ/severity.d.ts +31 -0
  169. package/dist/differ/severity.d.ts.map +1 -0
  170. package/dist/differ/severity.js +65 -0
  171. package/dist/differ/severity.js.map +1 -0
  172. package/dist/differ/types.d.ts +109 -0
  173. package/dist/differ/types.d.ts.map +1 -0
  174. package/dist/differ/types.js +5 -0
  175. package/dist/differ/types.js.map +1 -0
  176. package/dist/extractor/classifier.d.ts +30 -0
  177. package/dist/extractor/classifier.d.ts.map +1 -0
  178. package/dist/extractor/classifier.js +150 -0
  179. package/dist/extractor/classifier.js.map +1 -0
  180. package/dist/extractor/forward-ref.d.ts +28 -0
  181. package/dist/extractor/forward-ref.d.ts.map +1 -0
  182. package/dist/extractor/forward-ref.js +134 -0
  183. package/dist/extractor/forward-ref.js.map +1 -0
  184. package/dist/extractor/index.d.ts +25 -0
  185. package/dist/extractor/index.d.ts.map +1 -0
  186. package/dist/extractor/index.js +43 -0
  187. package/dist/extractor/index.js.map +1 -0
  188. package/dist/extractor/interface.d.ts +40 -0
  189. package/dist/extractor/interface.d.ts.map +1 -0
  190. package/dist/extractor/interface.js +233 -0
  191. package/dist/extractor/interface.js.map +1 -0
  192. package/dist/extractor/jsdoc.d.ts +24 -0
  193. package/dist/extractor/jsdoc.d.ts.map +1 -0
  194. package/dist/extractor/jsdoc.js +74 -0
  195. package/dist/extractor/jsdoc.js.map +1 -0
  196. package/dist/extractor/project.d.ts +17 -0
  197. package/dist/extractor/project.d.ts.map +1 -0
  198. package/dist/extractor/project.js +33 -0
  199. package/dist/extractor/project.js.map +1 -0
  200. package/dist/extractor/props.d.ts +24 -0
  201. package/dist/extractor/props.d.ts.map +1 -0
  202. package/dist/extractor/props.js +78 -0
  203. package/dist/extractor/props.js.map +1 -0
  204. package/dist/extractor/type-resolver.d.ts +32 -0
  205. package/dist/extractor/type-resolver.d.ts.map +1 -0
  206. package/dist/extractor/type-resolver.js +129 -0
  207. package/dist/extractor/type-resolver.js.map +1 -0
  208. package/dist/fetcher/index.d.ts +7 -0
  209. package/dist/fetcher/index.d.ts.map +1 -0
  210. package/dist/fetcher/index.js +7 -0
  211. package/dist/fetcher/index.js.map +1 -0
  212. package/dist/fetcher/npm-registry.d.ts +45 -0
  213. package/dist/fetcher/npm-registry.d.ts.map +1 -0
  214. package/dist/fetcher/npm-registry.js +217 -0
  215. package/dist/fetcher/npm-registry.js.map +1 -0
  216. package/dist/fetcher/unified-package.d.ts +27 -0
  217. package/dist/fetcher/unified-package.d.ts.map +1 -0
  218. package/dist/fetcher/unified-package.js +99 -0
  219. package/dist/fetcher/unified-package.js.map +1 -0
  220. package/dist/fetcher/unpkg.d.ts +20 -0
  221. package/dist/fetcher/unpkg.d.ts.map +1 -0
  222. package/dist/fetcher/unpkg.js +58 -0
  223. package/dist/fetcher/unpkg.js.map +1 -0
  224. package/dist/index.d.ts +18 -0
  225. package/dist/index.d.ts.map +1 -0
  226. package/dist/index.js +41 -0
  227. package/dist/index.js.map +1 -0
  228. package/dist/providers/base.d.ts +10 -0
  229. package/dist/providers/base.d.ts.map +1 -0
  230. package/dist/providers/base.js +80 -0
  231. package/dist/providers/base.js.map +1 -0
  232. package/dist/providers/index.d.ts +10 -0
  233. package/dist/providers/index.d.ts.map +1 -0
  234. package/dist/providers/index.js +10 -0
  235. package/dist/providers/index.js.map +1 -0
  236. package/dist/providers/interface.d.ts +56 -0
  237. package/dist/providers/interface.d.ts.map +1 -0
  238. package/dist/providers/interface.js +5 -0
  239. package/dist/providers/interface.js.map +1 -0
  240. package/dist/providers/radix-backend.d.ts +11 -0
  241. package/dist/providers/radix-backend.d.ts.map +1 -0
  242. package/dist/providers/radix-backend.js +107 -0
  243. package/dist/providers/radix-backend.js.map +1 -0
  244. package/dist/providers/radix.d.ts +6 -0
  245. package/dist/providers/radix.d.ts.map +1 -0
  246. package/dist/providers/radix.js +21 -0
  247. package/dist/providers/radix.js.map +1 -0
  248. package/dist/providers/registry.d.ts +17 -0
  249. package/dist/providers/registry.d.ts.map +1 -0
  250. package/dist/providers/registry.js +55 -0
  251. package/dist/providers/registry.js.map +1 -0
  252. package/dist/rules/engine.d.ts +4 -0
  253. package/dist/rules/engine.d.ts.map +1 -0
  254. package/dist/rules/engine.js +37 -0
  255. package/dist/rules/engine.js.map +1 -0
  256. package/dist/rules/index.d.ts +6 -0
  257. package/dist/rules/index.d.ts.map +1 -0
  258. package/dist/rules/index.js +6 -0
  259. package/dist/rules/index.js.map +1 -0
  260. package/dist/rules/predicates.d.ts +10 -0
  261. package/dist/rules/predicates.d.ts.map +1 -0
  262. package/dist/rules/predicates.js +93 -0
  263. package/dist/rules/predicates.js.map +1 -0
  264. package/dist/rules/rulesets/base-ui.d.ts +3 -0
  265. package/dist/rules/rulesets/base-ui.d.ts.map +1 -0
  266. package/dist/rules/rulesets/base-ui.js +65 -0
  267. package/dist/rules/rulesets/base-ui.js.map +1 -0
  268. package/dist/rules/rulesets/radix-legacy.d.ts +3 -0
  269. package/dist/rules/rulesets/radix-legacy.d.ts.map +1 -0
  270. package/dist/rules/rulesets/radix-legacy.js +38 -0
  271. package/dist/rules/rulesets/radix-legacy.js.map +1 -0
  272. package/dist/rules/types.d.ts +57 -0
  273. package/dist/rules/types.d.ts.map +1 -0
  274. package/dist/rules/types.js +2 -0
  275. package/dist/rules/types.js.map +1 -0
  276. package/dist/signatures/disambiguation.d.ts +30 -0
  277. package/dist/signatures/disambiguation.d.ts.map +1 -0
  278. package/dist/signatures/disambiguation.js +99 -0
  279. package/dist/signatures/disambiguation.js.map +1 -0
  280. package/dist/signatures/distinguishing.d.ts +29 -0
  281. package/dist/signatures/distinguishing.d.ts.map +1 -0
  282. package/dist/signatures/distinguishing.js +108 -0
  283. package/dist/signatures/distinguishing.js.map +1 -0
  284. package/dist/signatures/generator.d.ts +20 -0
  285. package/dist/signatures/generator.d.ts.map +1 -0
  286. package/dist/signatures/generator.js +147 -0
  287. package/dist/signatures/generator.js.map +1 -0
  288. package/dist/signatures/index.d.ts +10 -0
  289. package/dist/signatures/index.d.ts.map +1 -0
  290. package/dist/signatures/index.js +10 -0
  291. package/dist/signatures/index.js.map +1 -0
  292. package/dist/signatures/inference.d.ts +37 -0
  293. package/dist/signatures/inference.d.ts.map +1 -0
  294. package/dist/signatures/inference.js +132 -0
  295. package/dist/signatures/inference.js.map +1 -0
  296. package/dist/tools/analyze-component.d.ts +41 -0
  297. package/dist/tools/analyze-component.d.ts.map +1 -0
  298. package/dist/tools/analyze-component.js +274 -0
  299. package/dist/tools/analyze-component.js.map +1 -0
  300. package/dist/tools/check-updates.d.ts +33 -0
  301. package/dist/tools/check-updates.d.ts.map +1 -0
  302. package/dist/tools/check-updates.js +81 -0
  303. package/dist/tools/check-updates.js.map +1 -0
  304. package/dist/tools/diff-versions.d.ts +39 -0
  305. package/dist/tools/diff-versions.d.ts.map +1 -0
  306. package/dist/tools/diff-versions.js +78 -0
  307. package/dist/tools/diff-versions.js.map +1 -0
  308. package/dist/tools/extract-primitive.d.ts +50 -0
  309. package/dist/tools/extract-primitive.d.ts.map +1 -0
  310. package/dist/tools/extract-primitive.js +145 -0
  311. package/dist/tools/extract-primitive.js.map +1 -0
  312. package/dist/tools/generate-report.d.ts +29 -0
  313. package/dist/tools/generate-report.d.ts.map +1 -0
  314. package/dist/tools/generate-report.js +36 -0
  315. package/dist/tools/generate-report.js.map +1 -0
  316. package/dist/tools/index.d.ts +11 -0
  317. package/dist/tools/index.d.ts.map +1 -0
  318. package/dist/tools/index.js +11 -0
  319. package/dist/tools/index.js.map +1 -0
  320. package/dist/tools/list-primitives.d.ts +41 -0
  321. package/dist/tools/list-primitives.d.ts.map +1 -0
  322. package/dist/tools/list-primitives.js +74 -0
  323. package/dist/tools/list-primitives.js.map +1 -0
  324. package/dist/tools/run-audit.d.ts +43 -0
  325. package/dist/tools/run-audit.d.ts.map +1 -0
  326. package/dist/tools/run-audit.js +60 -0
  327. package/dist/tools/run-audit.js.map +1 -0
  328. package/dist/types/index.d.ts +143 -0
  329. package/dist/types/index.d.ts.map +1 -0
  330. package/dist/types/index.js +5 -0
  331. package/dist/types/index.js.map +1 -0
  332. package/docs/architecture.md +88 -0
  333. package/docs/providers.md +47 -0
  334. package/docs/tools.md +143 -0
  335. package/package.json +59 -0
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Disambiguator for resolving ambiguous matches.
3
+ * Detects when top matches are too close and applies domain rules to resolve.
4
+ */
5
+ import { getDisambiguationRule, getDisambiguationRuleForGroup, } from './rules/index.js';
6
+ /**
7
+ * Check if matches are ambiguous (top 2 within 10 points).
8
+ */
9
+ export function isAmbiguous(matches) {
10
+ if (matches.length < 2) {
11
+ return false;
12
+ }
13
+ const topScore = matches[0].confidence;
14
+ const secondScore = matches[1].confidence;
15
+ return topScore - secondScore <= 10;
16
+ }
17
+ /**
18
+ * Disambiguate ambiguous matches using domain rules.
19
+ * Returns the best match after applying disambiguation rules.
20
+ */
21
+ export function disambiguate(matches, analysis) {
22
+ if (matches.length === 0) {
23
+ throw new Error('Cannot disambiguate empty matches');
24
+ }
25
+ // If not ambiguous, return top match
26
+ if (!isAmbiguous(matches)) {
27
+ return matches[0];
28
+ }
29
+ // Get top 2 matches
30
+ const topMatch = matches[0];
31
+ const secondMatch = matches[1];
32
+ // Try group-based disambiguation first (for 3+ primitives or special groups)
33
+ if (matches.length >= 2) {
34
+ const primitives = matches.slice(0, Math.min(3, matches.length)).map((m) => m.primitive);
35
+ const groupRule = getDisambiguationRuleForGroup(primitives);
36
+ if (groupRule) {
37
+ const result = groupRule(analysis);
38
+ if (result) {
39
+ const preferredMatch = matches.find((m) => m.primitive === result);
40
+ if (preferredMatch) {
41
+ return preferredMatch;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ // Try to find a disambiguation rule for the pair
47
+ const rule = getDisambiguationRule(topMatch.primitive, secondMatch.primitive);
48
+ if (rule) {
49
+ const result = rule(analysis);
50
+ if (result) {
51
+ // Find the match that matches the rule result
52
+ const preferredMatch = matches.find((m) => m.primitive === result);
53
+ if (preferredMatch) {
54
+ return preferredMatch;
55
+ }
56
+ }
57
+ }
58
+ // No rule found or rule couldn't disambiguate
59
+ // Return top match (highest confidence)
60
+ return topMatch;
61
+ }
62
+ /**
63
+ * Get disambiguation reasoning for a match.
64
+ * Returns a human-readable explanation of why a match was chosen.
65
+ */
66
+ export function getDisambiguationReasoning(matches, _analysis, chosenMatch) {
67
+ if (!isAmbiguous(matches)) {
68
+ return undefined;
69
+ }
70
+ const topMatch = matches[0];
71
+ const secondMatch = matches[1];
72
+ // If chosen match is not the top match, explain why
73
+ if (chosenMatch.primitive !== topMatch.primitive) {
74
+ const rule = getDisambiguationRule(topMatch.primitive, secondMatch.primitive);
75
+ if (rule) {
76
+ // Try to get a human-readable reason
77
+ // For now, return a generic message
78
+ return `Disambiguated from ${topMatch.primitive} using domain rules`;
79
+ }
80
+ }
81
+ return undefined;
82
+ }
83
+ //# sourceMappingURL=disambiguator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disambiguator.js","sourceRoot":"","sources":["../../src/analyzer/disambiguator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Component analyzer main module.
3
+ * Analyzes local React components and matches them against Radix signatures.
4
+ */
5
+ import type { ComponentAnalysis } from '../types/index.js';
6
+ import type { ModuleGraph } from '../analysis/module-graph.js';
7
+ import { scoreAgainstSignatures } from './scorer.js';
8
+ import { disambiguate, isAmbiguous } from './disambiguator.js';
9
+ /**
10
+ * Analyze a component file and return ComponentAnalysis.
11
+ */
12
+ export interface AnalyzeComponentOptions {
13
+ moduleGraph?: ModuleGraph;
14
+ }
15
+ export declare function analyzeComponent(filePath: string, options?: AnalyzeComponentOptions): Promise<ComponentAnalysis>;
16
+ /**
17
+ * Score component analysis against Radix signatures.
18
+ * Re-exported from scorer module.
19
+ */
20
+ export { scoreAgainstSignatures };
21
+ /**
22
+ * Disambiguate ambiguous matches.
23
+ * Re-exported from disambiguator module.
24
+ */
25
+ export { disambiguate, isAmbiguous };
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAe/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,CAAC,CAwD5B;AAED;;;GAGG;AACH,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Component analyzer main module.
3
+ * Analyzes local React components and matches them against Radix signatures.
4
+ */
5
+ import { buildComponentIr } from '../analysis/ir/build-ir.js';
6
+ import { collectEvidence } from '../analysis/passes/index.js';
7
+ import { parseComponent, getComponentNameFromPath } from './parser.js';
8
+ import { extractProps } from './props.js';
9
+ import { detectSubComponents, detectForwardRef, detectAsChild, detectAriaRoles, detectDataAttributes, inferStatePatternFromProps, inferCompositionPatternFromSubComponents, inferRenderingPatternFromAnalysis, } from './patterns.js';
10
+ import { scoreAgainstSignatures } from './scorer.js';
11
+ import { disambiguate, isAmbiguous } from './disambiguator.js';
12
+ export async function analyzeComponent(filePath, options = {}) {
13
+ // Parse the component file
14
+ const sourceFile = parseComponent(filePath);
15
+ if (!sourceFile) {
16
+ throw new Error(`Failed to parse component file: ${filePath}`);
17
+ }
18
+ // Get component name
19
+ const componentName = getComponentNameFromPath(filePath);
20
+ const sourceText = sourceFile.getFullText();
21
+ // Extract props
22
+ const propsInterface = extractProps(sourceFile, componentName);
23
+ // Detect sub-components
24
+ const subComponents = detectSubComponents(sourceFile, componentName);
25
+ // Infer patterns
26
+ const inferredStatePattern = inferStatePatternFromProps(propsInterface);
27
+ const inferredCompositionPattern = inferCompositionPatternFromSubComponents(subComponents);
28
+ const inferredRenderingPattern = inferRenderingPatternFromAnalysis(subComponents, propsInterface);
29
+ // Detect features
30
+ const usesForwardRef = detectForwardRef(sourceFile);
31
+ const hasAsChild = detectAsChild(sourceFile, propsInterface);
32
+ const ariaRoles = detectAriaRoles(sourceFile);
33
+ const dataAttributes = detectDataAttributes(sourceFile);
34
+ const ir = buildComponentIr({
35
+ filePath,
36
+ sourceText,
37
+ moduleGraph: options.moduleGraph,
38
+ });
39
+ const evidenceBundle = collectEvidence(ir, { filePath, sourceText });
40
+ ir.jsx = evidenceBundle.jsx;
41
+ ir.behaviors = evidenceBundle.behaviors;
42
+ ir.evidence = evidenceBundle.evidence;
43
+ return {
44
+ name: componentName,
45
+ filePath,
46
+ propsInterface,
47
+ subComponents,
48
+ inferredStatePattern,
49
+ inferredCompositionPattern,
50
+ inferredRenderingPattern,
51
+ usesForwardRef,
52
+ hasAsChild,
53
+ ariaRoles,
54
+ dataAttributes,
55
+ ir,
56
+ };
57
+ }
58
+ /**
59
+ * Score component analysis against Radix signatures.
60
+ * Re-exported from scorer module.
61
+ */
62
+ export { scoreAgainstSignatures };
63
+ /**
64
+ * Disambiguate ambiguous matches.
65
+ * Re-exported from disambiguator module.
66
+ */
67
+ export { disambiguate, isAmbiguous };
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,wCAAwC,EACxC,iCAAiC,GAClC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAS/D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,UAAmC,EAAE;IAErC,2BAA2B;IAC3B,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,QAAQ,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,qBAAqB;IACrB,MAAM,aAAa,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IAE5C,gBAAgB;IAChB,MAAM,cAAc,GAAG,YAAY,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAE/D,wBAAwB;IACxB,MAAM,aAAa,GAAG,mBAAmB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAErE,iBAAiB;IACjB,MAAM,oBAAoB,GAAG,0BAA0B,CAAC,cAAc,CAAC,CAAC;IACxE,MAAM,0BAA0B,GAC9B,wCAAwC,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,wBAAwB,GAAG,iCAAiC,CAChE,aAAa,EACb,cAAc,CACf,CAAC;IAEF,kBAAkB;IAClB,MAAM,cAAc,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,cAAc,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;IAExD,MAAM,EAAE,GAAG,gBAAgB,CAAC;QAC1B,QAAQ;QACR,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;KACjC,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,eAAe,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;IACrE,EAAE,CAAC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC;IAC5B,EAAE,CAAC,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC;IACxC,EAAE,CAAC,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC;IAEtC,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,QAAQ;QACR,cAAc;QACd,aAAa;QACb,oBAAoB;QACpB,0BAA0B;QAC1B,wBAAwB;QACxB,cAAc;QACd,UAAU;QACV,SAAS;QACT,cAAc;QACd,EAAE;KACH,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Component parser for local .tsx files.
3
+ * Parses React components to extract AST and component structure.
4
+ */
5
+ import { Project, SourceFile } from 'ts-morph';
6
+ /**
7
+ * Create a ts-morph Project for parsing local files.
8
+ * Uses file system (not in-memory) to read actual .tsx files.
9
+ */
10
+ export declare function createLocalProject(): Project;
11
+ /**
12
+ * Load a .tsx file and return its SourceFile.
13
+ * @param filePath - Path to the .tsx file
14
+ * @param project - Optional ts-morph Project (creates new if not provided)
15
+ * @returns SourceFile or null if file doesn't exist
16
+ */
17
+ export declare function parseComponent(filePath: string, project?: Project): SourceFile | null;
18
+ /**
19
+ * Get the component name from a file path.
20
+ * @example "/path/to/Modal.tsx" -> "Modal"
21
+ */
22
+ export declare function getComponentNameFromPath(filePath: string): string;
23
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/analyzer/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI/C;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAY5C;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,GAChB,UAAU,GAAG,IAAI,CAoBnB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGjE"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Component parser for local .tsx files.
3
+ * Parses React components to extract AST and component structure.
4
+ */
5
+ import { Project } from 'ts-morph';
6
+ import * as fs from 'node:fs';
7
+ import * as path from 'node:path';
8
+ /**
9
+ * Create a ts-morph Project for parsing local files.
10
+ * Uses file system (not in-memory) to read actual .tsx files.
11
+ */
12
+ export function createLocalProject() {
13
+ return new Project({
14
+ useInMemoryFileSystem: false,
15
+ compilerOptions: {
16
+ target: 99, // ESNext
17
+ module: 99, // ESNext
18
+ lib: ['lib.esnext.d.ts', 'lib.dom.d.ts'],
19
+ jsx: 2, // React
20
+ strict: true,
21
+ skipLibCheck: true,
22
+ },
23
+ });
24
+ }
25
+ /**
26
+ * Load a .tsx file and return its SourceFile.
27
+ * @param filePath - Path to the .tsx file
28
+ * @param project - Optional ts-morph Project (creates new if not provided)
29
+ * @returns SourceFile or null if file doesn't exist
30
+ */
31
+ export function parseComponent(filePath, project) {
32
+ // Normalize path
33
+ const normalizedPath = path.resolve(filePath);
34
+ // Check if file exists
35
+ if (!fs.existsSync(normalizedPath)) {
36
+ return null;
37
+ }
38
+ // Create project if not provided
39
+ const proj = project || createLocalProject();
40
+ // Add the file to the project
41
+ // ts-morph will read from disk automatically
42
+ try {
43
+ return proj.addSourceFileAtPath(normalizedPath);
44
+ }
45
+ catch (error) {
46
+ // File might not be valid TypeScript/TSX
47
+ return null;
48
+ }
49
+ }
50
+ /**
51
+ * Get the component name from a file path.
52
+ * @example "/path/to/Modal.tsx" -> "Modal"
53
+ */
54
+ export function getComponentNameFromPath(filePath) {
55
+ const basename = path.basename(filePath, path.extname(filePath));
56
+ return basename;
57
+ }
58
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/analyzer/parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAc,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,OAAO,CAAC;QACjB,qBAAqB,EAAE,KAAK;QAC5B,eAAe,EAAE;YACf,MAAM,EAAE,EAAE,EAAE,SAAS;YACrB,MAAM,EAAE,EAAE,EAAE,SAAS;YACrB,GAAG,EAAE,CAAC,iBAAiB,EAAE,cAAc,CAAC;YACxC,GAAG,EAAE,CAAC,EAAE,QAAQ;YAChB,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,IAAI;SACnB;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAgB,EAChB,OAAiB;IAEjB,iBAAiB;IACjB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE9C,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iCAAiC;IACjC,MAAM,IAAI,GAAG,OAAO,IAAI,kBAAkB,EAAE,CAAC;IAE7C,8BAA8B;IAC9B,6CAA6C;IAC7C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yCAAyC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Pattern detection and inference for local components.
3
+ * Detects sub-components, features (forwardRef, asChild, aria, data attributes),
4
+ * and infers state/composition/rendering patterns.
5
+ */
6
+ import { type SourceFile } from 'ts-morph';
7
+ import type { StatePattern, CompositionPattern, RenderingPattern, PropDefinition } from '../types/index.js';
8
+ /**
9
+ * Detect sub-components from a component file.
10
+ * Handles patterns like: Modal.Root, Modal.Content, Modal.Trigger
11
+ */
12
+ export declare function detectSubComponents(sourceFile: SourceFile, componentName: string): string[];
13
+ /**
14
+ * Detect if component uses forwardRef.
15
+ */
16
+ export declare function detectForwardRef(sourceFile: SourceFile): boolean;
17
+ /**
18
+ * Detect if component has asChild prop.
19
+ */
20
+ export declare function detectAsChild(sourceFile: SourceFile, props: Map<string, PropDefinition>): boolean;
21
+ /**
22
+ * Detect aria roles from JSX.
23
+ */
24
+ export declare function detectAriaRoles(sourceFile: SourceFile): string[];
25
+ /**
26
+ * Detect data attributes from JSX.
27
+ */
28
+ export declare function detectDataAttributes(sourceFile: SourceFile): string[];
29
+ /**
30
+ * Infer state pattern from props.
31
+ */
32
+ export declare function inferStatePatternFromProps(props: Map<string, PropDefinition>): StatePattern;
33
+ /**
34
+ * Infer composition pattern from sub-components.
35
+ * For local components, we need to convert sub-component names to SubComponentDefinition format.
36
+ */
37
+ export declare function inferCompositionPatternFromSubComponents(subComponents: string[]): CompositionPattern;
38
+ /**
39
+ * Infer rendering pattern from sub-components and props.
40
+ */
41
+ export declare function inferRenderingPatternFromAnalysis(subComponents: string[], props: Map<string, PropDefinition>): RenderingPattern;
42
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/analyzer/patterns.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAO3B;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,EAAE,CA6EV;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAyChE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACjC,OAAO,CAgBT;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CA0BhE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAcrE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACjC,YAAY,CAGd;AAED;;;GAGG;AACH,wBAAgB,wCAAwC,CACtD,aAAa,EAAE,MAAM,EAAE,GACtB,kBAAkB,CASpB;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,MAAM,EAAE,EACvB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACjC,gBAAgB,CAUlB"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Pattern detection and inference for local components.
3
+ * Detects sub-components, features (forwardRef, asChild, aria, data attributes),
4
+ * and infers state/composition/rendering patterns.
5
+ */
6
+ import { SyntaxKind } from 'ts-morph';
7
+ import { inferStatePattern, inferCompositionPattern, inferRenderingPattern, } from '../signatures/inference.js';
8
+ /**
9
+ * Detect sub-components from a component file.
10
+ * Handles patterns like: Modal.Root, Modal.Content, Modal.Trigger
11
+ */
12
+ export function detectSubComponents(sourceFile, componentName) {
13
+ const subComponents = [];
14
+ const text = sourceFile.getFullText();
15
+ const escapedComponentName = escapeRegExp(componentName);
16
+ // Look for property assignments: ComponentName.SubName = ...
17
+ // Pattern: Modal.Root = function Root() { ... }
18
+ // or: Modal.Root = () => { ... }
19
+ const propertyAssignmentRegex = new RegExp(`${escapedComponentName}\\.(\\w+)\\s*=`, 'g');
20
+ let match;
21
+ while ((match = propertyAssignmentRegex.exec(text)) !== null) {
22
+ const subName = match[1];
23
+ if (subName && !subComponents.includes(subName)) {
24
+ subComponents.push(subName);
25
+ }
26
+ }
27
+ // Look for compound export pattern
28
+ // export { Root, Content, Trigger } from './components'
29
+ // or: export function Root() { ... }
30
+ const subComponentNames = [
31
+ 'Root',
32
+ 'Trigger',
33
+ 'Content',
34
+ 'Title',
35
+ 'Description',
36
+ 'Close',
37
+ 'Overlay',
38
+ 'Portal',
39
+ 'Arrow',
40
+ 'Item',
41
+ 'Indicator',
42
+ 'Thumb',
43
+ 'Track',
44
+ 'Range',
45
+ 'Viewport',
46
+ 'Scrollbar',
47
+ 'Corner',
48
+ 'Action',
49
+ 'Cancel',
50
+ 'Group',
51
+ 'Label',
52
+ 'Separator',
53
+ 'Sub',
54
+ 'List',
55
+ 'Value',
56
+ 'Icon',
57
+ 'Image',
58
+ 'Fallback',
59
+ ];
60
+ // Check exported functions/variables with sub-component names
61
+ for (const func of sourceFile.getFunctions()) {
62
+ const funcName = func.getName();
63
+ if (funcName && func.isExported() && subComponentNames.includes(funcName)) {
64
+ if (!subComponents.includes(funcName)) {
65
+ subComponents.push(funcName);
66
+ }
67
+ }
68
+ }
69
+ // Check export declarations
70
+ for (const exportDecl of sourceFile.getExportDeclarations()) {
71
+ for (const named of exportDecl.getNamedExports()) {
72
+ const exportName = named.getName();
73
+ if (subComponentNames.includes(exportName)) {
74
+ if (!subComponents.includes(exportName)) {
75
+ subComponents.push(exportName);
76
+ }
77
+ }
78
+ }
79
+ }
80
+ return subComponents;
81
+ }
82
+ /**
83
+ * Detect if component uses forwardRef.
84
+ */
85
+ export function detectForwardRef(sourceFile) {
86
+ const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
87
+ for (const call of callExpressions) {
88
+ const expression = call.getExpression();
89
+ if (expression.getKind() === SyntaxKind.Identifier &&
90
+ expression.getText() === 'forwardRef') {
91
+ return true;
92
+ }
93
+ if (expression.getKind() === SyntaxKind.PropertyAccessExpression) {
94
+ const property = expression.asKindOrThrow(SyntaxKind.PropertyAccessExpression);
95
+ if (property.getName() === 'forwardRef' &&
96
+ property.getExpression().getText() === 'React') {
97
+ return true;
98
+ }
99
+ }
100
+ }
101
+ const typeReferences = sourceFile.getDescendantsOfKind(SyntaxKind.TypeReference);
102
+ for (const typeRef of typeReferences) {
103
+ const typeName = typeRef.getTypeName().getText();
104
+ if (typeName === 'ForwardRefExoticComponent' ||
105
+ typeName.endsWith('.ForwardRefExoticComponent')) {
106
+ return true;
107
+ }
108
+ }
109
+ return false;
110
+ }
111
+ /**
112
+ * Detect if component has asChild prop.
113
+ */
114
+ export function detectAsChild(sourceFile, props) {
115
+ if (props.has('asChild')) {
116
+ return true;
117
+ }
118
+ const jsxAttributes = sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute);
119
+ for (const attr of jsxAttributes) {
120
+ const name = attr.getNameNode().getText();
121
+ if (name === 'asChild' || name === 'as-child') {
122
+ return true;
123
+ }
124
+ }
125
+ return false;
126
+ }
127
+ /**
128
+ * Detect aria roles from JSX.
129
+ */
130
+ export function detectAriaRoles(sourceFile) {
131
+ const roles = [];
132
+ const text = sourceFile.getFullText();
133
+ // Match role="..." patterns
134
+ const roleMatches = text.matchAll(/role=["']([^"']+)["']/g);
135
+ for (const match of roleMatches) {
136
+ const role = match[1];
137
+ if (role && !roles.includes(role)) {
138
+ roles.push(role);
139
+ }
140
+ }
141
+ // Also check for aria-* attributes that imply roles
142
+ const ariaMatches = text.matchAll(/aria-(\w+)=["'][^"']*["']/g);
143
+ for (const match of ariaMatches) {
144
+ const ariaAttr = match[1];
145
+ // Some aria attributes imply roles
146
+ if (ariaAttr === 'label' || ariaAttr === 'labelledby') {
147
+ if (!roles.includes('label')) {
148
+ roles.push('label');
149
+ }
150
+ }
151
+ }
152
+ return roles;
153
+ }
154
+ /**
155
+ * Detect data attributes from JSX.
156
+ */
157
+ export function detectDataAttributes(sourceFile) {
158
+ const attributes = [];
159
+ const text = sourceFile.getFullText();
160
+ // Match data-* attributes
161
+ const dataMatches = text.matchAll(/data-(\w+(?:-\w+)*)=["'][^"']*["']/g);
162
+ for (const match of dataMatches) {
163
+ const attr = `data-${match[1]}`;
164
+ if (!attributes.includes(attr)) {
165
+ attributes.push(attr);
166
+ }
167
+ }
168
+ return attributes;
169
+ }
170
+ /**
171
+ * Infer state pattern from props.
172
+ */
173
+ export function inferStatePatternFromProps(props) {
174
+ const propsArray = Array.from(props.values());
175
+ return inferStatePattern(propsArray);
176
+ }
177
+ /**
178
+ * Infer composition pattern from sub-components.
179
+ * For local components, we need to convert sub-component names to SubComponentDefinition format.
180
+ */
181
+ export function inferCompositionPatternFromSubComponents(subComponents) {
182
+ // Convert string array to SubComponentDefinition format
183
+ const subComponentDefs = subComponents.map((name) => ({
184
+ name,
185
+ props: [],
186
+ isRequired: false,
187
+ }));
188
+ return inferCompositionPattern(subComponentDefs);
189
+ }
190
+ /**
191
+ * Infer rendering pattern from sub-components and props.
192
+ */
193
+ export function inferRenderingPatternFromAnalysis(subComponents, props) {
194
+ // Convert to SubComponentDefinition format
195
+ const subComponentDefs = subComponents.map((name) => ({
196
+ name,
197
+ props: [],
198
+ isRequired: false,
199
+ }));
200
+ const propsArray = Array.from(props.values());
201
+ return inferRenderingPattern(subComponentDefs, propsArray);
202
+ }
203
+ function escapeRegExp(input) {
204
+ return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
205
+ }
206
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/analyzer/patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Props extraction from local component files.
3
+ * Handles various prop patterns: interfaces, inline props, FC generics, ForwardRef.
4
+ */
5
+ import type { SourceFile } from 'ts-morph';
6
+ import type { PropDefinition } from '../types/index.js';
7
+ /**
8
+ * Extract props from a component file.
9
+ * Tries multiple patterns:
10
+ * 1. Named Props interface (e.g., ModalProps)
11
+ * 2. Inline props in function parameters
12
+ * 3. FC generic (const Modal: FC<ModalProps>)
13
+ * 4. ForwardRefExoticComponent
14
+ */
15
+ export declare function extractProps(sourceFile: SourceFile, componentName?: string): Map<string, PropDefinition>;
16
+ //# sourceMappingURL=props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/analyzer/props.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,mBAAmB,CAAC;AASjE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAuD7B"}