@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,235 @@
1
+ /**
2
+ * Props extraction from local component files.
3
+ * Handles various prop patterns: interfaces, inline props, FC generics, ForwardRef.
4
+ */
5
+ import { extractPropsFromInterface } from '../extractor/props.js';
6
+ import { findForwardRefDeclarations, extractPropsFromForwardRef, } from '../extractor/forward-ref.js';
7
+ import { classifyProp } from '../extractor/classifier.js';
8
+ import { filterReactInternals } from '../extractor/type-resolver.js';
9
+ /**
10
+ * Extract props from a component file.
11
+ * Tries multiple patterns:
12
+ * 1. Named Props interface (e.g., ModalProps)
13
+ * 2. Inline props in function parameters
14
+ * 3. FC generic (const Modal: FC<ModalProps>)
15
+ * 4. ForwardRefExoticComponent
16
+ */
17
+ export function extractProps(sourceFile, componentName) {
18
+ const propsMap = new Map();
19
+ // Try to find named Props interface first
20
+ const propsInterface = findPropsInterface(sourceFile, componentName);
21
+ if (propsInterface) {
22
+ const rawProps = extractPropsFromInterface(propsInterface);
23
+ for (const rawProp of rawProps) {
24
+ const classified = classifyProp(rawProp);
25
+ propsMap.set(classified.name, classified);
26
+ }
27
+ return propsMap;
28
+ }
29
+ // Try ForwardRef declarations
30
+ const forwardRefDecls = findForwardRefDeclarations(sourceFile);
31
+ if (forwardRefDecls.length > 0) {
32
+ for (const decl of forwardRefDecls) {
33
+ if (componentName && decl.name !== componentName)
34
+ continue;
35
+ const rawProps = extractPropsFromForwardRef(sourceFile, decl);
36
+ if (rawProps) {
37
+ const filtered = filterReactInternals(rawProps);
38
+ for (const rawProp of filtered) {
39
+ const classified = classifyProp(rawProp);
40
+ propsMap.set(classified.name, classified);
41
+ }
42
+ return propsMap;
43
+ }
44
+ }
45
+ }
46
+ // Try function component with inline props
47
+ const funcDecl = findFunctionComponent(sourceFile, componentName);
48
+ if (funcDecl) {
49
+ const rawProps = extractPropsFromFunction(funcDecl);
50
+ for (const rawProp of rawProps) {
51
+ const classified = classifyProp(rawProp);
52
+ propsMap.set(classified.name, classified);
53
+ }
54
+ return propsMap;
55
+ }
56
+ // Try FC generic pattern
57
+ const fcDecl = findFCComponent(sourceFile, componentName);
58
+ if (fcDecl) {
59
+ const rawProps = extractPropsFromFC(fcDecl, sourceFile);
60
+ for (const rawProp of rawProps) {
61
+ const classified = classifyProp(rawProp);
62
+ propsMap.set(classified.name, classified);
63
+ }
64
+ return propsMap;
65
+ }
66
+ return propsMap;
67
+ }
68
+ /**
69
+ * Find a Props interface (e.g., ModalProps, DialogProps).
70
+ */
71
+ function findPropsInterface(sourceFile, componentName) {
72
+ const interfaces = sourceFile.getInterfaces();
73
+ // If component name provided, look for ComponentNameProps
74
+ if (componentName) {
75
+ const propsName = `${componentName}Props`;
76
+ const iface = sourceFile.getInterface(propsName);
77
+ if (iface)
78
+ return iface;
79
+ }
80
+ // Look for any interface ending in "Props"
81
+ for (const iface of interfaces) {
82
+ if (iface.getName().endsWith('Props')) {
83
+ return iface;
84
+ }
85
+ }
86
+ return null;
87
+ }
88
+ /**
89
+ * Find a function component declaration.
90
+ */
91
+ function findFunctionComponent(sourceFile, componentName) {
92
+ const functions = sourceFile.getFunctions();
93
+ if (componentName) {
94
+ const func = sourceFile.getFunction(componentName);
95
+ if (func)
96
+ return func;
97
+ }
98
+ // Look for exported function (common pattern)
99
+ for (const func of functions) {
100
+ if (func.isExported()) {
101
+ return func;
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+ /**
107
+ * Extract props from a function component with inline props.
108
+ * Handles: function Modal({ open, onOpenChange }: { open: boolean; ... }) { ... }
109
+ */
110
+ function extractPropsFromFunction(func) {
111
+ const params = func.getParameters();
112
+ if (params.length === 0)
113
+ return [];
114
+ // First parameter is usually the props
115
+ const propsParam = params[0];
116
+ const typeNode = propsParam.getTypeNode();
117
+ if (!typeNode) {
118
+ // Try to infer from type
119
+ const type = propsParam.getType();
120
+ return extractPropsFromType(type);
121
+ }
122
+ // Extract from type node
123
+ return extractPropsFromTypeNode(typeNode);
124
+ }
125
+ /**
126
+ * Extract props from a TypeNode (inline type literal).
127
+ */
128
+ function extractPropsFromTypeNode(typeNode) {
129
+ const props = [];
130
+ const type = typeNode.getType();
131
+ // Get properties from the type
132
+ for (const prop of type.getProperties()) {
133
+ const name = prop.getName();
134
+ const declarations = prop.getDeclarations();
135
+ const propDecl = declarations[0];
136
+ if (!propDecl)
137
+ continue;
138
+ const propType = prop.getTypeAtLocation(propDecl);
139
+ const typeText = propType.getText();
140
+ // Check if optional
141
+ const isOptional = propDecl.getKindName() === 'PropertySignature'
142
+ ? propDecl
143
+ .hasQuestionToken?.() ?? false
144
+ : typeText.includes('undefined');
145
+ props.push({
146
+ name,
147
+ type: simplifyTypeText(typeText),
148
+ required: !isOptional,
149
+ });
150
+ }
151
+ return props;
152
+ }
153
+ /**
154
+ * Extract props from a Type (from type checker).
155
+ */
156
+ function extractPropsFromType(type) {
157
+ const props = [];
158
+ for (const prop of type.getProperties()) {
159
+ const name = prop.getName();
160
+ const declarations = prop.getDeclarations();
161
+ const propDecl = declarations[0];
162
+ if (!propDecl)
163
+ continue;
164
+ const propType = prop.getTypeAtLocation(propDecl);
165
+ const typeText = propType.getText();
166
+ // Check if optional (union with undefined)
167
+ const isOptional = typeText.includes('undefined');
168
+ props.push({
169
+ name,
170
+ type: simplifyTypeText(typeText),
171
+ required: !isOptional,
172
+ });
173
+ }
174
+ return props;
175
+ }
176
+ /**
177
+ * Find a React.FC component declaration.
178
+ * Handles: const Modal: FC<ModalProps> = ...
179
+ */
180
+ function findFCComponent(sourceFile, componentName) {
181
+ for (const statement of sourceFile.getVariableStatements()) {
182
+ for (const decl of statement.getDeclarations()) {
183
+ const name = decl.getName();
184
+ if (componentName && name !== componentName)
185
+ continue;
186
+ const typeNode = decl.getTypeNode();
187
+ if (!typeNode)
188
+ continue;
189
+ const typeText = typeNode.getText();
190
+ if (typeText.includes('FC<') || typeText.includes('React.FC<')) {
191
+ return decl;
192
+ }
193
+ }
194
+ }
195
+ return null;
196
+ }
197
+ /**
198
+ * Extract props from a React.FC declaration.
199
+ */
200
+ function extractPropsFromFC(decl, sourceFile) {
201
+ const typeNode = decl.getTypeNode();
202
+ if (!typeNode)
203
+ return [];
204
+ const type = typeNode.getType();
205
+ const typeArgs = type.getTypeArguments();
206
+ if (typeArgs.length === 0)
207
+ return [];
208
+ // First type argument is the props type
209
+ const propsType = typeArgs[0];
210
+ // Try to get the interface name
211
+ const typeText = typeNode.getText();
212
+ const match = typeText.match(/(?:React\.)?FC<(\w+)>/);
213
+ if (match) {
214
+ const propsTypeName = match[1];
215
+ const propsInterface = sourceFile.getInterface(propsTypeName);
216
+ if (propsInterface) {
217
+ return extractPropsFromInterface(propsInterface);
218
+ }
219
+ }
220
+ // Fallback: extract from type directly
221
+ return extractPropsFromType(propsType);
222
+ }
223
+ /**
224
+ * Simplify complex type text for readability.
225
+ */
226
+ function simplifyTypeText(text) {
227
+ return text
228
+ .replace(/React\.ReactNode/g, 'ReactNode')
229
+ .replace(/React\.ReactElement/g, 'ReactElement')
230
+ .replace(/React\.CSSProperties/g, 'CSSProperties')
231
+ .replace(/React\.HTMLAttributes<.*?>/g, 'HTMLAttributes')
232
+ .replace(/React\.ComponentPropsWithoutRef<.*?>/g, 'ComponentProps')
233
+ .replace(/import\(".*?"\)\./g, '');
234
+ }
235
+ //# sourceMappingURL=props.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props.js","sourceRoot":"","sources":["../../src/analyzer/props.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Disambiguation rule for Checkbox vs Switch vs Toggle.
3
+ */
4
+ import type { ComponentAnalysis } from '../../types/index.js';
5
+ /**
6
+ * Disambiguate between Checkbox, Switch, and Toggle.
7
+ * Returns the preferred primitive or null if cannot disambiguate.
8
+ */
9
+ export declare function disambiguateCheckboxSwitchToggle(analysis: ComponentAnalysis): 'Checkbox' | 'Switch' | 'Toggle' | null;
10
+ //# sourceMappingURL=checkbox-switch-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-switch-toggle.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/checkbox-switch-toggle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,iBAAiB,GAC1B,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAqBzC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Disambiguation rule for Checkbox vs Switch vs Toggle.
3
+ */
4
+ /**
5
+ * Disambiguate between Checkbox, Switch, and Toggle.
6
+ * Returns the preferred primitive or null if cannot disambiguate.
7
+ */
8
+ export function disambiguateCheckboxSwitchToggle(analysis) {
9
+ const props = analysis.propsInterface;
10
+ const subComponents = analysis.subComponents;
11
+ // Switch: has Thumb sub-component (distinctive)
12
+ if (subComponents.includes('Thumb')) {
13
+ return 'Switch';
14
+ }
15
+ // Toggle: has pressed state (distinctive)
16
+ if (props.has('pressed') || props.has('defaultPressed')) {
17
+ return 'Toggle';
18
+ }
19
+ // Checkbox: has checked state (but not pressed)
20
+ if (props.has('checked') || props.has('defaultChecked')) {
21
+ return 'Checkbox';
22
+ }
23
+ // Cannot disambiguate
24
+ return null;
25
+ }
26
+ //# sourceMappingURL=checkbox-switch-toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkbox-switch-toggle.js","sourceRoot":"","sources":["../../../src/analyzer/rules/checkbox-switch-toggle.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,MAAM,UAAU,gCAAgC,CAC9C,QAA2B;IAE3B,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC;IACtC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;IAE7C,gDAAgD;IAChD,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,0CAA0C;IAC1C,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,gDAAgD;IAChD,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACxD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,sBAAsB;IACtB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Disambiguation rule for Dialog vs Popover.
3
+ */
4
+ import type { ComponentAnalysis } from '../../types/index.js';
5
+ /**
6
+ * Disambiguate between Dialog and Popover.
7
+ * Returns the preferred primitive or null if cannot disambiguate.
8
+ */
9
+ export declare function disambiguateDialogPopover(analysis: ComponentAnalysis): 'Dialog' | 'Popover' | null;
10
+ //# sourceMappingURL=dialog-popover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-popover.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/dialog-popover.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,iBAAiB,GAC1B,QAAQ,GAAG,SAAS,GAAG,IAAI,CAoB7B"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Disambiguation rule for Dialog vs Popover.
3
+ */
4
+ /**
5
+ * Disambiguate between Dialog and Popover.
6
+ * Returns the preferred primitive or null if cannot disambiguate.
7
+ */
8
+ export function disambiguateDialogPopover(analysis) {
9
+ const props = analysis.propsInterface;
10
+ // Dialog: has modal prop
11
+ if (props.has('modal')) {
12
+ return 'Dialog';
13
+ }
14
+ // Dialog: has Overlay sub-component
15
+ if (analysis.subComponents.includes('Overlay')) {
16
+ return 'Dialog';
17
+ }
18
+ // Popover: has side or align props (positioning props)
19
+ if (props.has('side') || props.has('align')) {
20
+ return 'Popover';
21
+ }
22
+ // Cannot disambiguate
23
+ return null;
24
+ }
25
+ //# sourceMappingURL=dialog-popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog-popover.js","sourceRoot":"","sources":["../../../src/analyzer/rules/dialog-popover.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAA2B;IAE3B,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC;IAEtC,yBAAyB;IACzB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACvB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,oCAAoC;IACpC,IAAI,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,uDAAuD;IACvD,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,sBAAsB;IACtB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Disambiguation rules registry.
3
+ */
4
+ import type { ComponentAnalysis } from '../../types/index.js';
5
+ /**
6
+ * Disambiguation rule function type.
7
+ */
8
+ export type DisambiguationRule = (analysis: ComponentAnalysis) => string | null;
9
+ /**
10
+ * Disambiguation rules map.
11
+ * Key: pair of primitives (sorted alphabetically, joined with '-')
12
+ * Value: disambiguation function
13
+ */
14
+ export declare const DISAMBIGUATION_RULES: Map<string, DisambiguationRule>;
15
+ /**
16
+ * Get disambiguation rule for a pair of primitives.
17
+ */
18
+ export declare function getDisambiguationRule(primitive1: string, primitive2: string): DisambiguationRule | null;
19
+ /**
20
+ * Get disambiguation rule for multiple primitives.
21
+ * Also checks if the provided primitives are a subset of any registered rule.
22
+ */
23
+ export declare function getDisambiguationRuleForGroup(primitives: string[]): DisambiguationRule | null;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAK9D;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,QAAQ,EAAE,iBAAiB,KACxB,MAAM,GAAG,IAAI,CAAC;AAEnB;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,iCAI/B,CAAC;AAEH;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,kBAAkB,GAAG,IAAI,CAM3B;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,MAAM,EAAE,GACnB,kBAAkB,GAAG,IAAI,CAuB3B"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Disambiguation rules registry.
3
+ */
4
+ import { disambiguateDialogPopover } from './dialog-popover.js';
5
+ import { disambiguateTooltipHoverCard } from './tooltip-hovercard.js';
6
+ import { disambiguateCheckboxSwitchToggle } from './checkbox-switch-toggle.js';
7
+ /**
8
+ * Disambiguation rules map.
9
+ * Key: pair of primitives (sorted alphabetically, joined with '-')
10
+ * Value: disambiguation function
11
+ */
12
+ export const DISAMBIGUATION_RULES = new Map([
13
+ ['Dialog-Popover', disambiguateDialogPopover],
14
+ ['HoverCard-Tooltip', disambiguateTooltipHoverCard],
15
+ ['Checkbox-Switch-Toggle', disambiguateCheckboxSwitchToggle],
16
+ ]);
17
+ /**
18
+ * Get disambiguation rule for a pair of primitives.
19
+ */
20
+ export function getDisambiguationRule(primitive1, primitive2) {
21
+ // Sort primitives alphabetically for consistent key lookup
22
+ const sorted = [primitive1, primitive2].sort();
23
+ const key = sorted.join('-');
24
+ return DISAMBIGUATION_RULES.get(key) || null;
25
+ }
26
+ /**
27
+ * Get disambiguation rule for multiple primitives.
28
+ * Also checks if the provided primitives are a subset of any registered rule.
29
+ */
30
+ export function getDisambiguationRuleForGroup(primitives) {
31
+ // Sort primitives alphabetically for consistent key lookup
32
+ const sorted = [...primitives].sort();
33
+ const key = sorted.join('-');
34
+ // Try exact match first
35
+ const exactMatch = DISAMBIGUATION_RULES.get(key);
36
+ if (exactMatch) {
37
+ return exactMatch;
38
+ }
39
+ // Try to find a rule where the provided primitives are a subset
40
+ // e.g., ['Checkbox', 'Switch'] should match 'Checkbox-Switch-Toggle'
41
+ for (const [ruleKey, rule] of DISAMBIGUATION_RULES.entries()) {
42
+ const rulePrimitives = ruleKey.split('-');
43
+ // Check if all provided primitives are in the rule
44
+ const allMatch = sorted.every((p) => rulePrimitives.includes(p));
45
+ if (allMatch && sorted.length >= 2) {
46
+ return rule;
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzer/rules/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,6BAA6B,CAAC;AAS/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAA6B;IACtE,CAAC,gBAAgB,EAAE,yBAAyB,CAAC;IAC7C,CAAC,mBAAmB,EAAE,4BAA4B,CAAC;IACnD,CAAC,wBAAwB,EAAE,gCAAgC,CAAC;CAC7D,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,UAAkB;IAElB,2DAA2D;IAC3D,MAAM,MAAM,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE7B,OAAO,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAC3C,UAAoB;IAEpB,2DAA2D;IAC3D,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE7B,wBAAwB;IACxB,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,gEAAgE;IAChE,qEAAqE;IACrE,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,CAAC;QAC7D,MAAM,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1C,mDAAmD;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Disambiguation rule for Tooltip vs HoverCard.
3
+ */
4
+ import type { ComponentAnalysis } from '../../types/index.js';
5
+ /**
6
+ * Disambiguate between Tooltip and HoverCard.
7
+ * Returns the preferred primitive or null if cannot disambiguate.
8
+ */
9
+ export declare function disambiguateTooltipHoverCard(analysis: ComponentAnalysis): 'Tooltip' | 'HoverCard' | null;
10
+ //# sourceMappingURL=tooltip-hovercard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip-hovercard.d.ts","sourceRoot":"","sources":["../../../src/analyzer/rules/tooltip-hovercard.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,iBAAiB,GAC1B,SAAS,GAAG,WAAW,GAAG,IAAI,CAehC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Disambiguation rule for Tooltip vs HoverCard.
3
+ */
4
+ /**
5
+ * Disambiguate between Tooltip and HoverCard.
6
+ * Returns the preferred primitive or null if cannot disambiguate.
7
+ */
8
+ export function disambiguateTooltipHoverCard(analysis) {
9
+ const props = analysis.propsInterface;
10
+ // Tooltip: has delayDuration prop (common naming)
11
+ if (props.has('delayDuration')) {
12
+ return 'Tooltip';
13
+ }
14
+ // HoverCard: has openDelay prop (common naming)
15
+ if (props.has('openDelay')) {
16
+ return 'HoverCard';
17
+ }
18
+ // Cannot disambiguate
19
+ return null;
20
+ }
21
+ //# sourceMappingURL=tooltip-hovercard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip-hovercard.js","sourceRoot":"","sources":["../../../src/analyzer/rules/tooltip-hovercard.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,QAA2B;IAE3B,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC;IAEtC,kDAAkD;IAClD,IAAI,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,gDAAgD;IAChD,IAAI,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,sBAAsB;IACtB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Confidence scoring for component analysis.
3
+ * Scores components against Radix signatures using weighted dimensions.
4
+ */
5
+ import type { ComponentAnalysis, PrimitiveMatch, BehaviorSignature } from '../types/index.js';
6
+ import { type ScoringWeights } from './weights.js';
7
+ /**
8
+ * Score a component analysis against a Radix signature.
9
+ * Returns a PrimitiveMatch with confidence score and breakdown.
10
+ */
11
+ export declare function scoreAgainstSignatures(analysis: ComponentAnalysis, signatures: BehaviorSignature[], weights?: Partial<ScoringWeights>): PrimitiveMatch[];
12
+ //# sourceMappingURL=scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../src/analyzer/scorer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EAElB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,iBAAiB,EAC3B,UAAU,EAAE,iBAAiB,EAAE,EAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAChC,cAAc,EAAE,CAalB"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Confidence scoring for component analysis.
3
+ * Scores components against Radix signatures using weighted dimensions.
4
+ */
5
+ import { getScoringWeights } from './weights.js';
6
+ /**
7
+ * Score a component analysis against a Radix signature.
8
+ * Returns a PrimitiveMatch with confidence score and breakdown.
9
+ */
10
+ export function scoreAgainstSignatures(analysis, signatures, weights) {
11
+ const scoringWeights = getScoringWeights(weights);
12
+ const matches = [];
13
+ for (const signature of signatures) {
14
+ const match = scoreComponent(analysis, signature, scoringWeights);
15
+ matches.push(match);
16
+ }
17
+ // Sort by confidence (descending)
18
+ matches.sort((a, b) => b.confidence - a.confidence);
19
+ return matches;
20
+ }
21
+ /**
22
+ * Score a single component against a signature.
23
+ */
24
+ function scoreComponent(analysis, signature, weights) {
25
+ const breakdown = {
26
+ statePatternScore: scoreStatePattern(analysis.inferredStatePattern, signature.statePattern, weights.statePattern),
27
+ compositionScore: scoreComposition(analysis.inferredCompositionPattern, signature.compositionPattern, weights.composition),
28
+ propsSignatureScore: scorePropsSignature(analysis.propsInterface, signature, weights.propsSignature),
29
+ accessibilityScore: scoreAccessibility(analysis.ariaRoles, analysis.dataAttributes, signature, weights.accessibility),
30
+ renderingScore: scoreRendering(analysis.inferredRenderingPattern, signature.renderingPattern, weights.rendering),
31
+ };
32
+ // Calculate total confidence
33
+ let confidence = breakdown.statePatternScore +
34
+ breakdown.compositionScore +
35
+ breakdown.propsSignatureScore +
36
+ breakdown.accessibilityScore +
37
+ breakdown.renderingScore;
38
+ // Apply anti-pattern penalty
39
+ const antiPatternPenalty = calculateAntiPatternPenalty(analysis.propsInterface, signature.antiPatternProps);
40
+ confidence = Math.max(0, confidence - antiPatternPenalty);
41
+ // Collect signals
42
+ const signals = collectSignals(analysis, signature);
43
+ return {
44
+ primitive: signature.primitive,
45
+ package: signature.package,
46
+ confidence: Math.round(confidence),
47
+ breakdown,
48
+ signals,
49
+ };
50
+ }
51
+ /**
52
+ * Score state pattern match (0 to maxScore).
53
+ */
54
+ function scoreStatePattern(inferred, expected, maxScore) {
55
+ if (inferred === expected) {
56
+ return maxScore;
57
+ }
58
+ return 0;
59
+ }
60
+ /**
61
+ * Score composition pattern match (0 to maxScore).
62
+ */
63
+ function scoreComposition(inferred, expected, maxScore) {
64
+ if (inferred === expected) {
65
+ return maxScore;
66
+ }
67
+ return 0;
68
+ }
69
+ /**
70
+ * Score props signature match (0 to maxScore).
71
+ * Checks for distinguishing props and gives partial credit.
72
+ */
73
+ function scorePropsSignature(props, signature, maxScore) {
74
+ const distinguishingProps = signature.distinguishingProps;
75
+ if (distinguishingProps.length === 0) {
76
+ // No distinguishing props to check, return neutral score
77
+ return 0;
78
+ }
79
+ let matchedCount = 0;
80
+ for (const propName of distinguishingProps) {
81
+ if (props.has(propName)) {
82
+ matchedCount++;
83
+ }
84
+ }
85
+ // Proportional score based on how many distinguishing props match
86
+ return Math.round((matchedCount / distinguishingProps.length) * maxScore);
87
+ }
88
+ /**
89
+ * Score accessibility features (0 to maxScore).
90
+ * Checks for aria roles and data attributes that match expected patterns.
91
+ */
92
+ function scoreAccessibility(ariaRoles, dataAttributes, _signature, maxScore) {
93
+ // Basic scoring: if component has accessibility features, give partial credit
94
+ // More sophisticated scoring could check for specific roles/attributes
95
+ if (ariaRoles.length > 0 || dataAttributes.length > 0) {
96
+ // Give partial credit for having accessibility features
97
+ return Math.round(maxScore * 0.5);
98
+ }
99
+ return 0;
100
+ }
101
+ /**
102
+ * Score rendering pattern match (0 to maxScore).
103
+ */
104
+ function scoreRendering(inferred, expected, maxScore) {
105
+ if (inferred === expected) {
106
+ return maxScore;
107
+ }
108
+ return 0;
109
+ }
110
+ /**
111
+ * Calculate anti-pattern penalty.
112
+ * Returns penalty points to subtract from total score.
113
+ */
114
+ function calculateAntiPatternPenalty(props, antiPatternProps) {
115
+ let penalty = 0;
116
+ for (const antiProp of antiPatternProps) {
117
+ if (props.has(antiProp)) {
118
+ // Each anti-pattern prop reduces score by 10 points
119
+ penalty += 10;
120
+ }
121
+ }
122
+ return penalty;
123
+ }
124
+ /**
125
+ * Collect signals (matched, missing, anti-patterns) for debugging.
126
+ */
127
+ function collectSignals(analysis, signature) {
128
+ const matched = [];
129
+ const missing = [];
130
+ const antiPatterns = [];
131
+ // Check distinguishing props
132
+ for (const propName of signature.distinguishingProps) {
133
+ if (analysis.propsInterface.has(propName)) {
134
+ matched.push(`prop:${propName}`);
135
+ }
136
+ else {
137
+ missing.push(`prop:${propName}`);
138
+ }
139
+ }
140
+ // Check patterns
141
+ if (analysis.inferredStatePattern === signature.statePattern) {
142
+ matched.push(`state:${signature.statePattern}`);
143
+ }
144
+ else {
145
+ missing.push(`state:${signature.statePattern}`);
146
+ }
147
+ if (analysis.inferredCompositionPattern === signature.compositionPattern) {
148
+ matched.push(`composition:${signature.compositionPattern}`);
149
+ }
150
+ else {
151
+ missing.push(`composition:${signature.compositionPattern}`);
152
+ }
153
+ if (analysis.inferredRenderingPattern === signature.renderingPattern) {
154
+ matched.push(`rendering:${signature.renderingPattern}`);
155
+ }
156
+ else {
157
+ missing.push(`rendering:${signature.renderingPattern}`);
158
+ }
159
+ // Check anti-patterns
160
+ for (const antiProp of signature.antiPatternProps) {
161
+ if (analysis.propsInterface.has(antiProp)) {
162
+ antiPatterns.push(antiProp);
163
+ }
164
+ }
165
+ return {
166
+ matched,
167
+ missing,
168
+ antiPatterns,
169
+ };
170
+ }
171
+ //# sourceMappingURL=scorer.js.map