@astryxdesign/cli 0.1.7 → 0.1.8-canary.07362a9

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 (389) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +115 -19
  3. package/{src/api → api/blog}/blog.mjs +42 -6
  4. package/{src/api → api/blog}/blog.test.mjs +2 -2
  5. package/api/build/build.mjs +92 -0
  6. package/api/build/build.test.mjs +92 -0
  7. package/{src/api → api/component}/component.mjs +49 -26
  8. package/{src/api → api/discover}/discover.mjs +55 -18
  9. package/{src/api → api/docs}/docs.mjs +47 -21
  10. package/{src/api → api/doctor}/doctor.mjs +13 -10
  11. package/{src/api → api}/error.mjs +2 -2
  12. package/{src/api → api/hook}/hook.mjs +11 -11
  13. package/{src/api → api}/index.mjs +16 -9
  14. package/{src/api → api/integration}/validate-integration.mjs +48 -15
  15. package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
  16. package/{src/api → api/layout}/layout.mjs +66 -17
  17. package/{src/api → api/layout}/layout.test.mjs +1 -1
  18. package/{src/api → api/search}/search.mjs +71 -12
  19. package/api/swizzle/swizzle.mjs +283 -0
  20. package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
  21. package/{src/api → api/template}/template-integration.test.mjs +2 -2
  22. package/{src/api → api/template}/template-suffix.test.mjs +3 -3
  23. package/{src/api → api/template}/template.mjs +96 -19
  24. package/{src/api → api/theme}/theme-add.mjs +35 -7
  25. package/{src → authoring}/codemod.mjs +6 -6
  26. package/{src → authoring}/config.test.mjs +1 -1
  27. package/{src → authoring}/doc.mjs +1 -1
  28. package/{src → authoring}/doc.test.mjs +1 -1
  29. package/{src → authoring}/template.mjs +1 -1
  30. package/bin/astryx.mjs +12 -10
  31. package/{src → cli}/commands/blog.mjs +48 -7
  32. package/{src → cli}/commands/build-theme.mjs +133 -115
  33. package/cli/commands/build.mjs +172 -0
  34. package/cli/commands/cli-postinstall.test.mjs +42 -0
  35. package/{src → cli}/commands/component/index.mjs +52 -25
  36. package/{src → cli}/commands/component-ownership.test.mjs +3 -3
  37. package/{src → cli}/commands/component-package.test.mjs +1 -1
  38. package/{src → cli}/commands/component-resolution.test.mjs +2 -2
  39. package/{src → cli}/commands/discover.mjs +23 -12
  40. package/{src → cli}/commands/docs.mjs +42 -10
  41. package/{src → cli}/commands/docs.test.mjs +1 -1
  42. package/{src → cli}/commands/doctor.mjs +3 -3
  43. package/{src → cli}/commands/doctor.test.mjs +2 -2
  44. package/{src → cli}/commands/ensure-core-built.mjs +3 -2
  45. package/{src → cli}/commands/external-showcase.test.mjs +1 -1
  46. package/{src → cli}/commands/hook/index.mjs +40 -17
  47. package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
  48. package/cli/commands/init.mjs +195 -0
  49. package/{src → cli}/commands/init.next-steps.test.mjs +1 -1
  50. package/cli/commands/interactive-guard.test.mjs +66 -0
  51. package/{src → cli}/commands/json-contract.test.mjs +2 -2
  52. package/{src → cli}/commands/layout.mjs +59 -19
  53. package/{src → cli}/commands/search.mjs +22 -15
  54. package/{src → cli}/commands/search.test.mjs +1 -1
  55. package/cli/commands/setup-nudge.test.mjs +108 -0
  56. package/cli/commands/swizzle.mjs +103 -0
  57. package/{src → cli}/commands/template.mjs +84 -53
  58. package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
  59. package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
  60. package/{src → cli}/commands/upgrade.mjs +291 -77
  61. package/cli/commands/upgrade.test.mjs +314 -0
  62. package/{src → cli}/commands/validate-integration.mjs +17 -37
  63. package/{src → cli}/index.mjs +55 -19
  64. package/{src/codemods → codemods}/__tests__/registry.test.mjs +1 -0
  65. package/{src/codemods → codemods}/ensure-jscodeshift.mjs +12 -28
  66. package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
  67. package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
  68. package/{src/codemods → codemods}/integration-runner.mjs +8 -3
  69. package/{src/codemods → codemods}/registry.mjs +4 -1
  70. package/{src/codemods → codemods}/run-codemod.mjs +18 -11
  71. package/{src/codemods → codemods}/runner.mjs +24 -14
  72. package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
  73. package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
  74. package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
  75. package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
  76. package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
  77. package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
  78. package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
  79. package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
  80. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
  81. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
  82. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
  83. package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
  84. package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
  85. package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
  86. package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
  87. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
  88. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
  89. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
  90. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
  91. package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
  92. package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
  93. package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
  94. package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
  95. package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
  96. package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
  97. package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
  98. package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
  99. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
  100. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
  101. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
  102. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
  103. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
  104. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
  105. package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
  106. package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
  107. package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
  108. package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +42 -7
  109. package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +43 -0
  110. package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +117 -13
  111. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
  112. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
  113. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +86 -15
  114. package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
  115. package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
  116. package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
  117. package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
  118. package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
  119. package/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +161 -0
  120. package/codemods/transforms/v0.1.8/index.mjs +19 -0
  121. package/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +239 -0
  122. package/docs/cli-integrations.doc.mjs +150 -0
  123. package/docs/elevation.doc.mjs +79 -1
  124. package/docs/getting-started.doc.mjs +9 -9
  125. package/docs/internationalization.doc.mjs +92 -46
  126. package/docs/migration.doc.mjs +18 -18
  127. package/docs/principles.doc.dense.mjs +1 -1
  128. package/docs/principles.doc.mjs +6 -6
  129. package/docs/principles.doc.zh.mjs +1 -1
  130. package/docs/styling-libraries.doc.mjs +3 -3
  131. package/docs/styling.doc.mjs +4 -4
  132. package/docs/theme.doc.dense.mjs +2 -2
  133. package/docs/theme.doc.mjs +7 -7
  134. package/docs/theme.doc.zh.mjs +1 -1
  135. package/docs/tokens.doc.mjs +1 -1
  136. package/docs/working-with-ai.doc.mjs +19 -19
  137. package/{src/commands → lib/agent-docs}/agent-docs.mjs +164 -29
  138. package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
  139. package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +123 -10
  140. package/{src/lib → lib}/cli-error.mjs +2 -2
  141. package/{src/lib → lib}/component-discovery.mjs +44 -2
  142. package/{src/lib → lib}/component-format.mjs +67 -25
  143. package/{src/lib → lib}/component-loader.mjs +27 -13
  144. package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
  145. package/{src/lib → lib}/error-codes.test.mjs +1 -1
  146. package/{src/lib → lib}/hook-discovery.mjs +14 -1
  147. package/{src/lib → lib}/hook-format.mjs +29 -5
  148. package/{src/lib → lib}/integration-warnings.mjs +2 -2
  149. package/{src/lib → lib}/integrations.mjs +20 -0
  150. package/{src/lib → lib}/integrations.test.mjs +1 -1
  151. package/{src/lib → lib}/json-contract.test.mjs +1 -1
  152. package/{src/lib → lib}/json-shim.mjs +11 -6
  153. package/{src/lib → lib}/json-shim.test.mjs +1 -1
  154. package/{src/lib → lib}/json.mjs +3 -3
  155. package/{src/lib → lib}/levenshtein.mjs +6 -0
  156. package/{src/lib → lib}/manifest.mjs +7 -5
  157. package/{src/lib → lib}/manifest.test.mjs +2 -2
  158. package/{src/lib → lib}/module-loader.mjs +1 -0
  159. package/{src/lib → lib}/package-scanner.mjs +47 -0
  160. package/{src/lib → lib}/project.mjs +48 -18
  161. package/{src/lib → lib}/project.test.mjs +1 -1
  162. package/{src/lib → lib}/resolve-theme.mjs +5 -0
  163. package/{src/lib → lib}/string-utils.mjs +15 -0
  164. package/lib/term-log.mjs +57 -0
  165. package/{src/lib → lib}/xle/browser.mjs +18 -8
  166. package/{src/lib → lib}/xle/expand.mjs +155 -22
  167. package/{src/lib → lib}/xle/parse.mjs +119 -13
  168. package/{src/lib → lib}/xle/print.mjs +54 -14
  169. package/{src/lib → lib}/xle/registry-core.mjs +28 -3
  170. package/{src/lib → lib}/xle/registry.mjs +9 -4
  171. package/{src/lib → lib}/xle/splice.mjs +13 -2
  172. package/{src/lib → lib}/xle/validate.mjs +95 -14
  173. package/lib/xle/xle-ast.d.ts +214 -0
  174. package/package.json +37 -28
  175. package/scripts/postinstall.mjs +74 -0
  176. package/templates/blocks/components/Avatar/AvatarFallbackChain.tsx +4 -4
  177. package/templates/blocks/components/Avatar/AvatarGroup.tsx +2 -2
  178. package/templates/blocks/components/Avatar/AvatarInitialsFallback.tsx +1 -1
  179. package/templates/blocks/components/Avatar/AvatarShowcase.tsx +5 -5
  180. package/templates/blocks/components/Avatar/AvatarUserCard.tsx +1 -1
  181. package/templates/blocks/components/Avatar/AvatarWithImage.tsx +4 -4
  182. package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +3 -3
  183. package/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.tsx +2 -2
  184. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowCustomText.tsx +1 -1
  185. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowDefault.tsx +1 -1
  186. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowShowcase.tsx +2 -2
  187. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotShowcase.tsx +3 -3
  188. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +3 -3
  189. package/templates/blocks/components/Banner/BannerFloating.doc.mjs +14 -0
  190. package/templates/blocks/components/Banner/BannerFloating.tsx +16 -0
  191. package/templates/blocks/components/Button/ButtonFloating.doc.mjs +14 -0
  192. package/templates/blocks/components/Button/ButtonFloating.tsx +37 -0
  193. package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.doc.mjs +14 -0
  194. package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.tsx +23 -0
  195. package/templates/blocks/components/Card/CardElevations.doc.mjs +14 -0
  196. package/templates/blocks/components/Card/CardElevations.tsx +32 -0
  197. package/templates/blocks/components/Card/ClickableCardElevated.doc.mjs +14 -0
  198. package/templates/blocks/components/Card/ClickableCardElevated.tsx +21 -0
  199. package/templates/blocks/components/Card/SelectableCardElevated.doc.mjs +14 -0
  200. package/templates/blocks/components/Card/SelectableCardElevated.tsx +37 -0
  201. package/templates/blocks/components/Carousel/CarouselSnap.tsx +1 -1
  202. package/templates/blocks/components/ChatComposer/ChatComposerFlat.doc.mjs +14 -0
  203. package/templates/blocks/components/ChatComposer/ChatComposerFlat.tsx +75 -0
  204. package/templates/blocks/components/ChatMessage/ChatMessageAvatarName.tsx +2 -2
  205. package/templates/blocks/components/ChatMessage/ChatMessageMultiBubble.tsx +1 -1
  206. package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleGrouping.tsx +1 -1
  207. package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleMetadata.tsx +1 -1
  208. package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +5 -9
  209. package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -1
  210. package/templates/blocks/components/CodeBlock/CodeBlockTerminal.tsx +1 -1
  211. package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -1
  212. package/templates/blocks/components/IconButton/IconButtonFloating.doc.mjs +14 -0
  213. package/templates/blocks/components/IconButton/IconButtonFloating.tsx +37 -0
  214. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
  215. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
  216. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
  217. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
  218. package/templates/blocks/components/Item/ItemWithMedia.tsx +2 -2
  219. package/templates/blocks/components/ListItem/ListItemWithMedia.tsx +2 -2
  220. package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.doc.mjs +14 -0
  221. package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.tsx +39 -0
  222. package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.doc.mjs +14 -0
  223. package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.tsx +44 -0
  224. package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -6
  225. package/templates/blocks/components/Stack/StackFillItem.tsx +2 -6
  226. package/templates/blocks/components/TabList/TabListTabsWithActions.doc.mjs +1 -1
  227. package/templates/blocks/components/TabList/TabListTabsWithActions.tsx +2 -7
  228. package/templates/blocks/components/Table/TableRowStatusTable.doc.mjs +14 -0
  229. package/templates/blocks/components/Table/TableRowStatusTable.tsx +59 -0
  230. package/templates/blocks/components/Thumbnail/ThumbnailDisabled.tsx +6 -1
  231. package/templates/blocks/components/Thumbnail/ThumbnailGallery.tsx +1 -0
  232. package/templates/blocks/components/Thumbnail/ThumbnailRemovable.tsx +1 -0
  233. package/templates/blocks/components/TypeaheadItem/TypeaheadItemShowcase.tsx +1 -1
  234. package/templates/pages/ai-chat/page.tsx +4 -4
  235. package/templates/pages/dashboard-portfolio/page.tsx +3 -11
  236. package/templates/pages/detail-page/page.tsx +5 -12
  237. package/templates/pages/documentation-design/page.tsx +1 -1
  238. package/templates/pages/messaging-shell/page.tsx +6 -8
  239. package/templates/pages/table-grouped/page.tsx +9 -14
  240. package/templates/pages/table-page/page.tsx +7 -9
  241. package/templates/pages/table-page-heatmap-status/page.tsx +5 -13
  242. package/{src/types → types}/api.contract.assert.ts +17 -8
  243. package/{src/types → types}/api.d.ts +110 -9
  244. package/{src/types → types}/base.d.ts +40 -4
  245. package/types/build.d.ts +53 -0
  246. package/types/codemod.d.ts +166 -0
  247. package/{src/types → types}/component.d.ts +1 -1
  248. package/{src/types → types}/discover.d.ts +1 -1
  249. package/{src/types → types}/docs.d.ts +1 -4
  250. package/{src/types → types}/hook.d.ts +1 -1
  251. package/{src/types → types}/index.d.ts +1 -0
  252. package/types/jscodeshift.d.ts +19 -0
  253. package/types/layout.d.ts +74 -0
  254. package/{src/types → types}/swizzle.d.ts +4 -0
  255. package/{src/types → types}/template-api.d.ts +4 -1
  256. package/types/theme.d.ts +53 -0
  257. package/types/upgrade.d.ts +108 -0
  258. package/utils/package-manager.mjs +178 -0
  259. package/utils/package-manager.test.mjs +220 -0
  260. package/{src/utils → utils}/path-safety.mjs +0 -18
  261. package/{src/utils → utils}/paths.mjs +4 -1
  262. package/{src/utils → utils}/update-check.mjs +5 -4
  263. package/{src/utils → utils}/update-check.test.mjs +3 -3
  264. package/docs/integration-authoring.md +0 -105
  265. package/src/commands/build.mjs +0 -196
  266. package/src/commands/init.mjs +0 -288
  267. package/src/commands/interactive-guard.test.mjs +0 -69
  268. package/src/commands/swizzle.mjs +0 -440
  269. package/src/commands/upgrade.test.mjs +0 -160
  270. package/src/types/codemod.d.ts +0 -81
  271. package/src/types/theme.d.ts +0 -23
  272. package/src/types/upgrade.d.ts +0 -64
  273. package/src/utils/interactive.mjs +0 -76
  274. package/src/utils/interactive.test.mjs +0 -70
  275. package/src/utils/package-manager.mjs +0 -74
  276. package/src/utils/package-manager.test.mjs +0 -113
  277. /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
  278. /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
  279. /package/{src/api → api/template}/template.test.mjs +0 -0
  280. /package/{src → authoring}/codemod.test.mjs +0 -0
  281. /package/{src → authoring}/config.mjs +0 -0
  282. /package/{src → authoring}/integration.mjs +0 -0
  283. /package/{src → authoring}/template.test.mjs +0 -0
  284. /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
  285. /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
  286. /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
  287. /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
  288. /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
  289. /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
  290. /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
  291. /package/{src → cli}/commands/component.test.mjs +0 -0
  292. /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
  293. /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
  294. /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
  295. /package/{src → cli}/commands/template.test.mjs +0 -0
  296. /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
  297. /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
  298. /package/{src → cli}/update-hint-commands.test.mjs +0 -0
  299. /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
  300. /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
  301. /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
  302. /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
  303. /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
  304. /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
  305. /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
  306. /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
  307. /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
  308. /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
  309. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
  310. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
  311. /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
  312. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
  313. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
  314. /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
  315. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
  316. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
  317. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
  318. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
  319. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
  320. /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
  321. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
  322. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
  323. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
  324. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
  325. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
  326. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
  327. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
  328. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
  329. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
  330. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
  331. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
  332. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
  333. /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
  334. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
  335. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
  336. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
  337. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
  338. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
  339. /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
  340. /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
  341. /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
  342. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
  343. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
  344. /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
  345. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
  346. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
  347. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
  348. /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
  349. /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
  350. /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
  351. /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
  352. /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
  353. /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
  354. /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
  355. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
  356. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
  357. /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
  358. /package/{src/lib → lib}/cli-error.test.mjs +0 -0
  359. /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
  360. /package/{src/lib → lib}/component-format.test.mjs +0 -0
  361. /package/{src/lib → lib}/component-loader.test.mjs +0 -0
  362. /package/{src/lib → lib}/config-cache.mjs +0 -0
  363. /package/{src/lib → lib}/config-cache.test.mjs +0 -0
  364. /package/{src/lib → lib}/config-schema.mjs +0 -0
  365. /package/{src/lib → lib}/error-codes.mjs +0 -0
  366. /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
  367. /package/{src/lib → lib}/module-loader.test.mjs +0 -0
  368. /package/{src/lib → lib}/node-version.mjs +0 -0
  369. /package/{src/lib → lib}/node-version.test.mjs +0 -0
  370. /package/{src/lib → lib}/parse.mjs +0 -0
  371. /package/{src/lib → lib}/site.mjs +0 -0
  372. /package/{src/lib → lib}/xle/browser.d.ts +0 -0
  373. /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
  374. /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
  375. /package/{src/schemas → schemas}/template-schema.mjs +0 -0
  376. /package/{src/types → types}/config.d.ts +0 -0
  377. /package/{src/types → types}/doc.d.ts +0 -0
  378. /package/{src/types → types}/doctor.d.ts +0 -0
  379. /package/{src/types → types}/error-codes.d.ts +0 -0
  380. /package/{src/types → types}/integration.d.ts +0 -0
  381. /package/{src/types → types}/manifest.d.ts +0 -0
  382. /package/{src/types → types}/search.d.ts +0 -0
  383. /package/{src/types → types}/template.d.ts +0 -0
  384. /package/{src/types → types}/validate-integration.d.ts +0 -0
  385. /package/{src/utils → utils}/github.mjs +0 -0
  386. /package/{src/utils → utils}/path-safety.test.mjs +0 -0
  387. /package/{src/utils → utils}/paths.test.mjs +0 -0
  388. /package/{src/utils → utils}/semver.mjs +0 -0
  389. /package/{src/utils → utils}/semver.test.mjs +0 -0
@@ -17,6 +17,11 @@
17
17
  */
18
18
 
19
19
  export class XLEParseError extends Error {
20
+ /**
21
+ * @param {string} message
22
+ * @param {number} line
23
+ * @param {number} col
24
+ */
20
25
  constructor(message, line, col) {
21
26
  super(message);
22
27
  this.name = 'XLEParseError';
@@ -25,7 +30,10 @@ export class XLEParseError extends Error {
25
30
  }
26
31
  }
27
32
 
28
- /** Keys that expand to full prop names before validation. */
33
+ /**
34
+ * Keys that expand to full prop names before validation.
35
+ * @type {Record<string, string>}
36
+ */
29
37
  export const KEY_ALIASES = {
30
38
  p: 'padding', pad: 'padding', g: 'gap', c: 'columns', cols: 'columns',
31
39
  w: 'width', h: 'height', cp: 'contentPadding', mw: 'maxWidth',
@@ -38,6 +46,12 @@ export const KEY_ALIASES = {
38
46
  /** Fused shorthand letters (`p6`, `g4`, `cp2`…) — letter must be a KEY_ALIAS. */
39
47
  const FUSED = new Set(['p', 'g', 'c', 'w', 'h', 'cp', 'mw', 'mh', 'rg', 'cg']);
40
48
 
49
+ /**
50
+ * @param {string|null} name
51
+ * @param {number} line
52
+ * @param {number} col
53
+ * @returns {import('./xle-ast').XLENode}
54
+ */
41
55
  export function makeNode(name, line, col) {
42
56
  return {
43
57
  kind: 'node',
@@ -57,20 +71,30 @@ export function makeNode(name, line, col) {
57
71
  };
58
72
  }
59
73
 
74
+ /**
75
+ * @param {number} line
76
+ * @param {number} col
77
+ * @returns {import('./xle-ast').XLEGroup}
78
+ */
60
79
  function makeGroup(line, col) {
61
80
  return {kind: 'group', repeat: null, children: [], line, col};
62
81
  }
63
82
 
64
83
  // ─── shared low-level helpers ──────────────────────────────────────────────
65
84
 
66
- const isIdentStart = (ch) => /[A-Za-z]/.test(ch);
67
- const isIdent = (ch) => /[A-Za-z0-9_-]/.test(ch);
85
+ const isIdentStart = (/** @type {string} */ ch) => /[A-Za-z]/.test(ch);
86
+ const isIdent = (/** @type {string} */ ch) => /[A-Za-z0-9_-]/.test(ch);
68
87
 
69
88
  /**
70
89
  * Split a string into tokens at depth-0 whitespace, where (), [], {} and
71
90
  * quotes raise depth. Used for attr blocks and outline lines.
91
+ * @param {string} str
92
+ * @param {number} line
93
+ * @param {number} startCol
94
+ * @returns {Array<{text: string, col: number}>}
72
95
  */
73
96
  function tokenize(str, line, startCol) {
97
+ /** @type {Array<{text: string, col: number}>} */
74
98
  const tokens = [];
75
99
  let i = 0;
76
100
  while (i < str.length) {
@@ -78,6 +102,7 @@ function tokenize(str, line, startCol) {
78
102
  if (i >= str.length) break;
79
103
  const start = i;
80
104
  let depth = 0;
105
+ /** @type {string|null} */
81
106
  let quote = null;
82
107
  while (i < str.length) {
83
108
  const ch = str[i];
@@ -101,7 +126,11 @@ function tokenize(str, line, startCol) {
101
126
  return tokens;
102
127
  }
103
128
 
104
- /** Parse a scalar/object/list attr value string into a JS value. */
129
+ /**
130
+ * Parse a scalar/object/list attr value string into a JS value.
131
+ * @param {string} raw
132
+ * @returns {import('./xle-ast').XLEValue}
133
+ */
105
134
  export function parseValue(raw) {
106
135
  const s = raw.trim();
107
136
  if (/^(['"]).*\1$/.test(s)) return s.slice(1, -1);
@@ -110,6 +139,7 @@ export function parseValue(raw) {
110
139
  if (s === 'false') return false;
111
140
  if (s.startsWith('#')) return {idref: s.slice(1)};
112
141
  if (s.startsWith('{') && s.endsWith('}')) {
142
+ /** @type {Record<string, import('./xle-ast').XLEValue>} */
113
143
  const obj = {};
114
144
  for (const part of splitTop(s.slice(1, -1), ',')) {
115
145
  const idx = part.indexOf(':');
@@ -125,10 +155,16 @@ export function parseValue(raw) {
125
155
  return s; // bare ident — enum string
126
156
  }
127
157
 
128
- /** Split on a separator at bracket/quote depth 0. */
158
+ /**
159
+ * Split on a separator at bracket/quote depth 0.
160
+ * @param {string} str
161
+ * @param {string} sep
162
+ * @returns {string[]}
163
+ */
129
164
  function splitTop(str, sep) {
130
165
  const parts = [];
131
166
  let depth = 0;
167
+ /** @type {string|null} */
132
168
  let quote = null;
133
169
  let cur = '';
134
170
  for (const ch of str) {
@@ -151,7 +187,13 @@ function splitTop(str, sep) {
151
187
  return parts.map(p => p.trim()).filter(Boolean);
152
188
  }
153
189
 
154
- /** Parse `{name +flag +flag2 :arg}` hint body (without braces). */
190
+ /**
191
+ * Parse `{name +flag +flag2 :arg}` hint body (without braces).
192
+ * @param {string} body
193
+ * @param {number} line
194
+ * @param {number} col
195
+ * @returns {import('./xle-ast').Hint}
196
+ */
155
197
  function parseHintBody(body, line, col) {
156
198
  const m = body.trim().match(/^([a-z0-9][a-z0-9-]*)((?:\s*\+[a-z0-9-]+)*)(?:\s*:(.*))?$/);
157
199
  if (!m) {
@@ -169,8 +211,10 @@ function parseHintBody(body, line, col) {
169
211
  }
170
212
 
171
213
  /**
172
- * Interpret one attribute token. Returns an attr record or mutates node
173
- * for special tokens (slots are returned as {kind:'slot'} records too).
214
+ * Interpret one attribute token. Returns an attr record or a slot record.
215
+ * @param {{text: string, col: number}} token
216
+ * @param {number} line
217
+ * @returns {import('./xle-ast').Attr | import('./xle-ast').Slot}
174
218
  */
175
219
  function parseAttrToken(token, line) {
176
220
  const {text, col} = token;
@@ -182,6 +226,7 @@ function parseAttrToken(token, line) {
182
226
  }
183
227
  const name = text.slice(1, eq);
184
228
  const rest = text.slice(eq + 1);
229
+ /** @type {import('./xle-ast').SlotValue} */
185
230
  let value;
186
231
  if (rest.startsWith('(') && rest.endsWith(')')) {
187
232
  value = {subexpr: parseCompactSiblings(new CompactStream(rest.slice(1, -1), line, col + eq + 2))};
@@ -203,6 +248,7 @@ function parseAttrToken(token, line) {
203
248
 
204
249
  // key=value (split at first depth-0 '=')
205
250
  let depth = 0;
251
+ /** @type {string|null} */
206
252
  let quote = null;
207
253
  for (let i = 0; i < text.length; i++) {
208
254
  const ch = text[i];
@@ -240,6 +286,11 @@ function parseAttrToken(token, line) {
240
286
  // ─── compact (XLE) surface ─────────────────────────────────────────────────
241
287
 
242
288
  class CompactStream {
289
+ /**
290
+ * @param {string} src
291
+ * @param {number} [line]
292
+ * @param {number} [col]
293
+ */
243
294
  constructor(src, line = 1, col = 1) {
244
295
  this.src = src;
245
296
  this.i = 0;
@@ -253,21 +304,29 @@ class CompactStream {
253
304
  const col = (lines.length === 1 ? this.baseCol : 1) + lines[lines.length - 1].length;
254
305
  return {line, col};
255
306
  }
307
+ /** @param {number} [offset] */
256
308
  peek(offset = 0) { return this.src[this.i + offset]; }
257
309
  next() { return this.src[this.i++]; }
258
310
  eof() { return this.i >= this.src.length; }
259
311
  skipWs() { while (!this.eof() && /\s/.test(this.peek())) this.i++; }
312
+ /** @param {string} message */
260
313
  error(message) {
261
314
  const {line, col} = this.pos();
262
315
  throw new XLEParseError(message, line, col);
263
316
  }
264
- /** Consume through the matching close bracket; returns inner text. */
317
+ /**
318
+ * Consume through the matching close bracket; returns inner text.
319
+ * @param {string} open
320
+ * @param {string} close
321
+ * @returns {string}
322
+ */
265
323
  readBalanced(open, close) {
266
324
  const startPos = this.pos();
267
325
  if (this.peek() !== open) this.error(`Expected '${open}'`);
268
326
  this.next();
269
327
  const start = this.i;
270
328
  let depth = 1;
329
+ /** @type {string|null} */
271
330
  let quote = null;
272
331
  while (!this.eof()) {
273
332
  const ch = this.next();
@@ -292,6 +351,10 @@ class CompactStream {
292
351
  }
293
352
  }
294
353
 
354
+ /**
355
+ * @param {CompactStream} s
356
+ * @returns {import('./xle-ast').XLENode}
357
+ */
295
358
  function parseCompactNode(s) {
296
359
  const {line, col} = s.pos();
297
360
  let name = '';
@@ -359,6 +422,10 @@ function parseCompactNode(s) {
359
422
  return node;
360
423
  }
361
424
 
425
+ /**
426
+ * @param {CompactStream} s
427
+ * @returns {import('./xle-ast').XLEItem}
428
+ */
362
429
  function parseCompactTerm(s) {
363
430
  s.skipWs();
364
431
  if (s.peek() === '(') {
@@ -387,11 +454,20 @@ function parseCompactTerm(s) {
387
454
  return parseCompactNode(s);
388
455
  }
389
456
 
457
+ /**
458
+ * @param {import('./xle-ast').XLEItem} node
459
+ * @returns {import('./xle-ast').XLENode}
460
+ */
390
461
  function structuredCloneNode(node) {
391
462
  return JSON.parse(JSON.stringify(node));
392
463
  }
393
464
 
465
+ /**
466
+ * @param {CompactStream} s
467
+ * @returns {import('./xle-ast').XLEItem[]}
468
+ */
394
469
  function parseCompactSiblings(s) {
470
+ /** @type {import('./xle-ast').XLEItem[]} */
395
471
  const terms = [];
396
472
  for (;;) {
397
473
  s.skipWs();
@@ -410,12 +486,17 @@ function parseCompactSiblings(s) {
410
486
  return terms;
411
487
  }
412
488
 
489
+ /**
490
+ * @param {string} source
491
+ * @returns {import('./xle-ast').XLEDoc}
492
+ */
413
493
  export function parseCompact(source) {
414
494
  const parts = source.split(/;;/);
415
495
  const main = new CompactStream(parts[0]);
416
496
  const roots = parseCompactSiblings(main);
417
497
  main.skipWs();
418
498
  if (!main.eof()) main.error(`Unexpected '${main.peek()}'`);
499
+ /** @type {import('./xle-ast').XLEItem[]} */
419
500
  const overlays = [];
420
501
  for (const part of parts.slice(1)) {
421
502
  const s = new CompactStream(part);
@@ -428,20 +509,35 @@ export function parseCompact(source) {
428
509
 
429
510
  // ─── outline (XLO) surface ─────────────────────────────────────────────────
430
511
 
431
- /** Parse one outline line's node chain: `Layout > LayoutContent pad=0 !scroll`. */
512
+ /**
513
+ * Parse one outline line's node chain: `Layout > LayoutContent pad=0 !scroll`.
514
+ * @param {string} text
515
+ * @param {number} line
516
+ * @returns {{head: import('./xle-ast').XLENode, tail: import('./xle-ast').XLENode}}
517
+ */
432
518
  function parseOutlineChain(text, line) {
433
519
  const segments = splitTop(text, '>');
520
+ /** @type {import('./xle-ast').XLENode | null} */
434
521
  let head = null;
522
+ /** @type {import('./xle-ast').XLENode | null} */
435
523
  let tail = null;
436
524
  for (const segment of segments) {
437
525
  const node = parseOutlineNodeSegment(segment, line);
438
526
  if (!head) head = node;
439
- else tail.children.push(node);
527
+ else /** @type {import('./xle-ast').XLENode} */ (tail).children.push(node);
440
528
  tail = node;
441
529
  }
442
- return {head, tail};
530
+ return /** @type {{head: import('./xle-ast').XLENode, tail: import('./xle-ast').XLENode}} */ ({
531
+ head,
532
+ tail,
533
+ });
443
534
  }
444
535
 
536
+ /**
537
+ * @param {string} segment
538
+ * @param {number} line
539
+ * @returns {import('./xle-ast').XLENode}
540
+ */
445
541
  function parseOutlineNodeSegment(segment, line) {
446
542
  const tokens = tokenize(segment, line, 0);
447
543
  if (tokens.length === 0) throw new XLEParseError('Empty node', line, 1);
@@ -487,10 +583,17 @@ function parseOutlineNodeSegment(segment, line) {
487
583
  return node;
488
584
  }
489
585
 
586
+ /**
587
+ * @param {string} source
588
+ * @returns {import('./xle-ast').XLEDoc}
589
+ */
490
590
  export function parseOutline(source) {
591
+ /** @type {import('./xle-ast').XLEItem[]} */
491
592
  const roots = [];
593
+ /** @type {import('./xle-ast').XLEItem[]} */
492
594
  const overlays = [];
493
595
  // Stack frames: {indent, container: array, node|null}
596
+ /** @type {Array<{indent: number, container: import('./xle-ast').XLEItem[], node: import('./xle-ast').XLENode | null}>} */
494
597
  const stack = [{indent: -1, container: roots, node: null}];
495
598
  let inOverlays = false;
496
599
 
@@ -499,7 +602,7 @@ export function parseOutline(source) {
499
602
  const raw = lines[li];
500
603
  const lineNo = li + 1;
501
604
  if (raw.trim() === '' || raw.trim().startsWith('#') || raw.trim().startsWith('//')) continue;
502
- const indent = raw.match(/^[ \t]*/)[0].replace(/\t/g, ' ').length;
605
+ const indent = /** @type {RegExpMatchArray} */ (raw.match(/^[ \t]*/))[0].replace(/\t/g, ' ').length;
503
606
  const text = raw.trim();
504
607
 
505
608
  if (text === 'overlays:') {
@@ -530,6 +633,7 @@ export function parseOutline(source) {
530
633
  `Slot '${slotMatch[1]}:' has no parent component`, lineNo, indent + 1,
531
634
  );
532
635
  }
636
+ /** @type {import('./xle-ast').Slot & {value: {subexpr: import('./xle-ast').XLEItem[]}}} */
533
637
  const slot = {kind: 'slot', key: slotMatch[1], value: {subexpr: []}, line: lineNo, col: indent + 1};
534
638
  parent.node.slots.push(slot);
535
639
  const inline = slotMatch[2].trim();
@@ -557,6 +661,8 @@ export function parseOutline(source) {
557
661
  * Detect which surface the source uses. Multi-line input is outline
558
662
  * unless every line break sits inside an operator chain (trailing
559
663
  * `>`/`+`/`;;` or unclosed brackets), which is multi-line compact.
664
+ * @param {string} source
665
+ * @returns {'compact'|'outline'}
560
666
  */
561
667
  export function detectForm(source) {
562
668
  const lines = source.split('\n').map(l => l.trim()).filter(l => l !== '' && !l.startsWith('#') && !l.startsWith('//'));
@@ -13,10 +13,14 @@
13
13
  * @position lib/xle — inverse of parse.mjs
14
14
  */
15
15
 
16
+ /**
17
+ * @param {import('./xle-ast').XLEValue} value
18
+ * @returns {string}
19
+ */
16
20
  function valueText(value) {
17
21
  if (typeof value === 'string') return /[\s,'"]/.test(value) ? `'${value}'` : value;
18
22
  if (typeof value === 'number' || typeof value === 'boolean') return String(value);
19
- if (value && value.idref) return `#${value.idref}`;
23
+ if (value && /** @type {any} */ (value).idref) return `#${/** @type {any} */ (value).idref}`;
20
24
  if (Array.isArray(value)) return `[${value.map(valueText).join(',')}]`;
21
25
  if (typeof value === 'object' && value !== null) {
22
26
  return `{${Object.entries(value)
@@ -26,6 +30,10 @@ function valueText(value) {
26
30
  return String(value);
27
31
  }
28
32
 
33
+ /**
34
+ * @param {import('./xle-ast').Hint} hint
35
+ * @returns {string}
36
+ */
29
37
  function hintText(hint) {
30
38
  let out = hint.name;
31
39
  for (const flag of hint.flags || []) out += ` +${flag}`;
@@ -33,6 +41,7 @@ function hintText(hint) {
33
41
  return `{${out}}`;
34
42
  }
35
43
 
44
+ /** @param {import('./xle-ast').XLENode} node */
36
45
  function attrTokens(node) {
37
46
  const tokens = [];
38
47
  for (const attr of node.attrs) {
@@ -43,17 +52,22 @@ function attrTokens(node) {
43
52
  return tokens;
44
53
  }
45
54
 
55
+ /** @param {import('./xle-ast').XLENode} node */
46
56
  function slotTokensCompact(node) {
47
57
  return node.slots.map(slot => {
48
58
  if (slot.value == null) return `@${slot.key}`;
49
59
  if (typeof slot.value === 'string') return `@${slot.key}='${slot.value}'`;
50
- if (slot.value.hint) return `@${slot.key}=${hintText(slot.value.hint)}`;
51
- if (slot.value.idref) return `@${slot.key}=#${slot.value.idref}`;
52
- if (slot.value.subexpr) return `@${slot.key}=(${siblingsCompact(slot.value.subexpr)})`;
60
+ if ('hint' in slot.value) return `@${slot.key}=${hintText(slot.value.hint)}`;
61
+ if (/** @type {any} */ (slot.value).idref) return `@${slot.key}=#${/** @type {any} */ (slot.value).idref}`;
62
+ if ('subexpr' in slot.value) return `@${slot.key}=(${siblingsCompact(slot.value.subexpr)})`;
53
63
  return `@${slot.key}`;
54
64
  });
55
65
  }
56
66
 
67
+ /**
68
+ * @param {import('./xle-ast').XLENode} node
69
+ * @returns {string}
70
+ */
57
71
  function nodeCompact(node) {
58
72
  let out = node.name || '';
59
73
  if (node.id) out += `#${node.id}`;
@@ -72,6 +86,10 @@ function nodeCompact(node) {
72
86
  return out;
73
87
  }
74
88
 
89
+ /**
90
+ * @param {import('./xle-ast').XLEItem} item
91
+ * @returns {string}
92
+ */
75
93
  function termCompact(item) {
76
94
  if (item.kind === 'group') {
77
95
  let out = `(${siblingsCompact(item.children)})`;
@@ -82,6 +100,10 @@ function termCompact(item) {
82
100
  return nodeCompact(item);
83
101
  }
84
102
 
103
+ /**
104
+ * @param {import('./xle-ast').XLEItem[]} items
105
+ * @returns {string}
106
+ */
85
107
  function siblingsCompact(items) {
86
108
  return items
87
109
  .map((item, i) => {
@@ -96,6 +118,7 @@ function siblingsCompact(items) {
96
118
  .join(' + ');
97
119
  }
98
120
 
121
+ /** @param {import('./xle-ast').XLEDoc} doc */
99
122
  export function toCompact(doc) {
100
123
  let out = siblingsCompact(doc.roots);
101
124
  for (const overlay of doc.overlays) {
@@ -106,6 +129,11 @@ export function toCompact(doc) {
106
129
 
107
130
  // ── outline ────────────────────────────────────────────────────────────────
108
131
 
132
+ /**
133
+ * @param {import('./xle-ast').XLENode} node
134
+ * @param {number} depth
135
+ * @returns {string[]}
136
+ */
109
137
  function nodeOutlineLines(node, depth) {
110
138
  const pad = ' '.repeat(depth);
111
139
  let line = node.name || '';
@@ -121,21 +149,23 @@ function nodeOutlineLines(node, depth) {
121
149
 
122
150
  const lines = [pad + line.trimStart()];
123
151
  for (const slot of node.slots) {
124
- if (slot.value && slot.value.subexpr) {
125
- if (slot.value.subexpr.length === 1 && isSimpleNode(slot.value.subexpr[0])) {
126
- const sub = nodeOutlineLines(slot.value.subexpr[0], 0)[0];
152
+ const sv = slot.value;
153
+ if (sv && typeof sv === 'object' && 'subexpr' in sv) {
154
+ const first = sv.subexpr[0];
155
+ if (sv.subexpr.length === 1 && first && isSimpleNode(first)) {
156
+ const sub = nodeOutlineLines(first, 0)[0];
127
157
  lines.push(`${pad} ${slot.key}: ${sub}`);
128
158
  // simple = no children, so the single line is complete
129
159
  } else {
130
160
  lines.push(`${pad} ${slot.key}:`);
131
- for (const sub of slot.value.subexpr) lines.push(...itemOutlineLines(sub, depth + 2));
161
+ for (const sub of sv.subexpr) lines.push(...itemOutlineLines(sub, depth + 2));
132
162
  }
133
- } else if (typeof slot.value === 'string') {
134
- lines.push(`${pad} ${slot.key}: "${slot.value}"`);
135
- } else if (slot.value && slot.value.hint) {
136
- lines.push(`${pad} ${slot.key}: ${hintText(slot.value.hint)}`);
137
- } else if (slot.value && slot.value.idref) {
138
- lines.push(`${pad} ${slot.key}: #${slot.value.idref}`);
163
+ } else if (typeof sv === 'string') {
164
+ lines.push(`${pad} ${slot.key}: "${sv}"`);
165
+ } else if (sv && typeof sv === 'object' && 'hint' in sv) {
166
+ lines.push(`${pad} ${slot.key}: ${hintText(sv.hint)}`);
167
+ } else if (sv && /** @type {any} */ (sv).idref) {
168
+ lines.push(`${pad} ${slot.key}: #${/** @type {any} */ (sv).idref}`);
139
169
  } else {
140
170
  lines.push(`${pad} ${slot.key}:`);
141
171
  }
@@ -144,10 +174,19 @@ function nodeOutlineLines(node, depth) {
144
174
  return lines;
145
175
  }
146
176
 
177
+ /**
178
+ * @param {import('./xle-ast').XLEItem} item
179
+ * @returns {item is import('./xle-ast').XLENode}
180
+ */
147
181
  function isSimpleNode(item) {
148
182
  return item.kind === 'node' && item.children.length === 0 && item.slots.length === 0;
149
183
  }
150
184
 
185
+ /**
186
+ * @param {import('./xle-ast').XLEItem} item
187
+ * @param {number} depth
188
+ * @returns {string[]}
189
+ */
151
190
  function itemOutlineLines(item, depth) {
152
191
  if (item.kind === 'group') {
153
192
  // A repeat-less group exists only to disambiguate compact-form
@@ -163,6 +202,7 @@ function itemOutlineLines(item, depth) {
163
202
  return nodeOutlineLines(item, depth);
164
203
  }
165
204
 
205
+ /** @param {import('./xle-ast').XLEDoc} doc */
166
206
  export function toOutline(doc) {
167
207
  const lines = [];
168
208
  for (const item of doc.roots) lines.push(...itemOutlineLines(item, 0));
@@ -74,6 +74,8 @@ export const SPACING_STEPS = [0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10];
74
74
  * Parse enum values from a doc.mjs prop type string.
75
75
  * "'a' | 'b' | 'c'" → ['a','b','c']; "1|2|3" → [1,2,3];
76
76
  * "SpacingStep" → SPACING_STEPS. Mixed/non-enum types → null.
77
+ * @param {string | undefined | null} type
78
+ * @returns {Array<string | number> | null}
77
79
  */
78
80
  export function parseEnumValues(type) {
79
81
  if (!type || typeof type !== 'string') return null;
@@ -83,6 +85,7 @@ export function parseEnumValues(type) {
83
85
  }
84
86
  const parts = t.split('|').map(p => p.trim());
85
87
  if (parts.length < 2) return null;
88
+ /** @type {Array<string | number>} */
86
89
  const values = [];
87
90
  for (const part of parts) {
88
91
  const str = part.match(/^'([^']*)'$/) || part.match(/^"([^"]*)"$/);
@@ -93,14 +96,21 @@ export function parseEnumValues(type) {
93
96
  return values;
94
97
  }
95
98
 
99
+ /** @param {string} name */
96
100
  export function normalizeName(name) {
97
101
  return name.replace(/^XDS/, '');
98
102
  }
99
103
 
100
104
  /**
101
105
  * Index one doc entry's props into the registry component shape.
106
+ * @param {string} name
107
+ * @param {import('./xle-ast').DocProp[]} props
108
+ * @param {string} dirName
109
+ * @param {string} importPath
110
+ * @returns {import('./xle-ast').RegistryComponent}
102
111
  */
103
112
  export function toComponentEntry(name, props, dirName, importPath) {
113
+ /** @type {Map<string, import('./xle-ast').RegistryProp>} */
104
114
  const propMap = new Map();
105
115
  for (const p of props || []) {
106
116
  propMap.set(p.name, {
@@ -119,10 +129,14 @@ export function toComponentEntry(name, props, dirName, importPath) {
119
129
  /**
120
130
  * Resolve a node name (alias, bare name, or XDS-prefixed name) to a
121
131
  * registry component entry, or null.
132
+ * @param {import('./xle-ast').Registry} registry
133
+ * @param {string | null} name
134
+ * @returns {import('./xle-ast').RegistryComponent | null}
122
135
  */
123
136
  export function resolveComponent(registry, name) {
137
+ if (name == null) return null;
124
138
  const viaAlias = registry.aliases.get(name);
125
- if (viaAlias) return registry.components.get(viaAlias);
139
+ if (viaAlias) return registry.components.get(viaAlias) ?? null;
126
140
  const bare = normalizeName(name);
127
141
  return registry.components.get(bare) || null;
128
142
  }
@@ -130,6 +144,8 @@ export function resolveComponent(registry, name) {
130
144
  /**
131
145
  * Serialize a built registry (with Map fields) to a plain JSON-safe object
132
146
  * so a Node build step can ship it to the browser.
147
+ * @param {import('./xle-ast').Registry} registry
148
+ * @returns {import('./browser').SerializedRegistry}
133
149
  */
134
150
  export function serializeRegistry(registry) {
135
151
  return {
@@ -139,7 +155,7 @@ export function serializeRegistry(registry) {
139
155
  dirName: c.dirName,
140
156
  importPath: c.importPath,
141
157
  undocumented: c.undocumented || false,
142
- props: [...c.props.values()],
158
+ props: /** @type {Array<Record<string, unknown>>} */ (/** @type {unknown} */ ([...c.props.values()])),
143
159
  })),
144
160
  aliases: [...registry.aliases.entries()],
145
161
  componentNames: registry.componentNames,
@@ -149,17 +165,26 @@ export function serializeRegistry(registry) {
149
165
  /**
150
166
  * Hydrate a serialized registry back into the Map-bearing shape that
151
167
  * validate()/expand() expect. Inverse of serializeRegistry.
168
+ * @param {import('./browser').SerializedRegistry} json
169
+ * @returns {import('./xle-ast').Registry}
152
170
  */
153
171
  export function hydrateRegistry(json) {
172
+ /** @type {Map<string, import('./xle-ast').RegistryComponent>} */
154
173
  const components = new Map();
155
174
  for (const c of json.components) {
175
+ /** @type {Map<string, import('./xle-ast').RegistryProp>} */
176
+ const props = new Map();
177
+ for (const p of c.props) {
178
+ const prop = /** @type {import('./xle-ast').RegistryProp} */ (/** @type {unknown} */ (p));
179
+ props.set(String(p.name), prop);
180
+ }
156
181
  components.set(c.name, {
157
182
  name: c.name,
158
183
  exportName: c.exportName,
159
184
  dirName: c.dirName,
160
185
  importPath: c.importPath,
161
186
  undocumented: c.undocumented || false,
162
- props: new Map(c.props.map(p => [p.name, p])),
187
+ props,
163
188
  });
164
189
  }
165
190
  return {
@@ -40,6 +40,11 @@ export {
40
40
  hydrateRegistry,
41
41
  } from './registry-core.mjs';
42
42
 
43
+ /**
44
+ * @param {Record<string, string[]>} grouped
45
+ * @param {string} member
46
+ * @returns {string|null}
47
+ */
43
48
  function findDirFor(grouped, member) {
44
49
  for (const [dir, members] of Object.entries(grouped)) {
45
50
  if (members.includes(member)) return dir;
@@ -90,7 +95,7 @@ function readDirExportedComponents(coreDir, dirName) {
90
95
  return [...names];
91
96
  }
92
97
 
93
- let cachedRegistry = null;
98
+ let cachedRegistry = /** @type {import('./xle-ast').Registry | null} */ (null);
94
99
 
95
100
  /**
96
101
  * Build (and cache) the registry: every documented component keyed by its
@@ -123,7 +128,7 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
123
128
  }
124
129
  const importPath = resolveImportPath(coreDir, dirName);
125
130
 
126
- const register = (rawName, props) => {
131
+ const register = (/** @type {string} */ rawName, /** @type {import('./xle-ast').DocProp[]} */ props) => {
127
132
  const name = normalizeName(rawName);
128
133
  const entry = toComponentEntry(name, props, dirName, importPath);
129
134
  const existing = components.get(name);
@@ -147,7 +152,7 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
147
152
  // props go missing and valid attrs (e.g. Heading[level=2]) get rejected.
148
153
  // Read every .doc.mjs in each contributing dir and upgrade props, keyed to
149
154
  // each component's own export subpath. Props-only: never adds empty entries.
150
- const upgradeFromDoc = (rawName, props, fallbackDir) => {
155
+ const upgradeFromDoc = (/** @type {string} */ rawName, /** @type {import('./xle-ast').DocProp[]} */ props, /** @type {string} */ fallbackDir) => {
151
156
  if (!props || props.length === 0) return;
152
157
  const name = normalizeName(rawName);
153
158
  // Prefer the component's own export subpath (Heading → @astryxdesign/core/Heading);
@@ -193,7 +198,7 @@ export async function buildRegistry({cwd = process.cwd()} = {}) {
193
198
  // (TableHeader/Body/Footer became bare files with no own .doc.mjs after
194
199
  // the un-prefix migration), so we recover them from the real export
195
200
  // surface here.
196
- const registerUndocumented = (name, dirName) => {
201
+ const registerUndocumented = (/** @type {string} */ name, /** @type {string} */ dirName) => {
197
202
  if (components.has(name)) return;
198
203
  const entry = toComponentEntry(name, [], dirName, resolveImportPath(coreDir, name));
199
204
  entry.undocumented = true;