@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
@@ -19,7 +19,7 @@
19
19
  * ADDS a one-line nudge.
20
20
  */
21
21
 
22
- import {validateLoadedIntegration} from '../api/validate-integration.mjs';
22
+ import {validateLoadedIntegration} from '../api/integration/validate-integration.mjs';
23
23
 
24
24
  /**
25
25
  * For each configured (already-loaded) integration, compute its issues using
@@ -28,7 +28,7 @@ import {validateLoadedIntegration} from '../api/validate-integration.mjs';
28
28
  *
29
29
  * Warning: <pkg> has N integration issue(s). Run: astryx validate-integration <pkg>
30
30
  *
31
- * @param {Array<object>} loadedIntegrations the Project's loaded integrations
31
+ * @param {Array<import('./integrations.mjs').LoadedIntegration>} loadedIntegrations the Project's loaded integrations
32
32
  * @param {{json?: boolean}} [options]
33
33
  * @returns {Promise<void>}
34
34
  */
@@ -15,6 +15,23 @@ import * as path from 'node:path';
15
15
  import {AstryxIntegrationSchema} from './config-schema.mjs';
16
16
  import {loadModuleWithSchema, findPresentFiles} from './module-loader.mjs';
17
17
 
18
+ /**
19
+ * A fully-resolved, loaded integration. Identity (`name`, `version`) comes from
20
+ * the package's package.json; the `components`/`templates`/`codemods` roots are
21
+ * absolute paths resolved from the manifest. The `__`-prefixed fields are
22
+ * internal bookkeeping used by validate-integration and Project.
23
+ * @typedef {object} LoadedIntegration
24
+ * @property {string} name
25
+ * @property {string} [version]
26
+ * @property {string} [components]
27
+ * @property {string} [templates]
28
+ * @property {string} [codemods]
29
+ * @property {string} [issuesUrl]
30
+ * @property {string} __spec
31
+ * @property {string} __packageDir
32
+ * @property {string} __manifestFile
33
+ */
34
+
18
35
  /** Conventional manifest basenames, in load-precedence order. */
19
36
  export const MANIFEST_BASENAMES = [
20
37
  'astryx.integration.ts',
@@ -85,8 +102,10 @@ function resolveManifestPath(packageDir, spec) {
85
102
  *
86
103
  * @param {string[]} [specs] package names
87
104
  * @param {{cwd?: string}} [options]
105
+ * @returns {Promise<LoadedIntegration[]>}
88
106
  */
89
107
  export async function loadIntegrations(specs = [], {cwd = process.cwd()} = {}) {
108
+ /** @type {LoadedIntegration[]} */
90
109
  const integrations = [];
91
110
  const seen = new Set();
92
111
 
@@ -112,6 +131,7 @@ export async function loadIntegrations(specs = [], {cwd = process.cwd()} = {}) {
112
131
  {label: `Integration ${spec}`},
113
132
  );
114
133
 
134
+ /** @param {string | null | undefined} value */
115
135
  const resolveRoot = value =>
116
136
  value == null ? undefined : path.resolve(packageDir, value);
117
137
 
@@ -5,7 +5,7 @@ import * as fs from 'node:fs';
5
5
  import * as path from 'node:path';
6
6
  import {Project} from './project.mjs';
7
7
  import {loadIntegrations} from './integrations.mjs';
8
- import {discover} from '../api/discover.mjs';
8
+ import {discover} from '../api/discover/discover.mjs';
9
9
 
10
10
  let tmpDir;
11
11
  let originalCwd;
@@ -27,7 +27,7 @@ import {
27
27
  } from './json.mjs';
28
28
 
29
29
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
30
- const CLI = path.resolve(__dirname, '..', '..', 'bin', 'astryx.mjs');
30
+ const CLI = path.resolve(__dirname, '..', 'bin', 'astryx.mjs');
31
31
 
32
32
  function runCli(args) {
33
33
  return spawnSync(process.execPath, [CLI, ...args], {
@@ -65,6 +65,7 @@ function jsonActive() {
65
65
  export function buildHelpEnvelope(cmd) {
66
66
  // Reconstruct the fully-qualified command name (e.g. "astryx theme build").
67
67
  const nameParts = [];
68
+ /** @type {import('commander').Command | null} */
68
69
  let c = cmd;
69
70
  while (c) {
70
71
  nameParts.unshift(c.name());
@@ -81,7 +82,7 @@ export function buildHelpEnvelope(cmd) {
81
82
  });
82
83
 
83
84
  const subcommands = cmd.commands
84
- .filter((s) => !s._hidden)
85
+ .filter((s) => !(/** @type {any} */ (s))._hidden)
85
86
  .map((s) => ({name: s.name(), description: s.description() || ''}));
86
87
 
87
88
  return {
@@ -102,7 +103,7 @@ export function buildHelpEnvelope(cmd) {
102
103
  * for both success and error).
103
104
  *
104
105
  * @param {string} message
105
- * @param {Array<{name: string, reason: string}>} [suggestions]
106
+ * @param {import('../types/base').Suggestion[]} [suggestions]
106
107
  * @param {string} [code] - Stable machine-readable error code (error-codes.mjs).
107
108
  */
108
109
  function emitJsonError(message, suggestions, code) {
@@ -227,10 +228,14 @@ let Command_outputHelp_patched = false;
227
228
  * @param {import('commander').Command} cmd
228
229
  */
229
230
  function patchOutputHelp(cmd) {
230
- if (cmd.__xdsHelpPatched) return;
231
- cmd.__xdsHelpPatched = true;
231
+ // Commander instances are monkeypatched at runtime with an internal
232
+ // `__xdsHelpPatched` marker and a replacement `outputHelp`, neither of which
233
+ // is in commander's public types — treat the instance as untyped here.
234
+ const anyCmd = /** @type {any} */ (cmd);
235
+ if (anyCmd.__xdsHelpPatched) return;
236
+ anyCmd.__xdsHelpPatched = true;
232
237
  const original = cmd.outputHelp.bind(cmd);
233
- cmd.outputHelp = function patchedOutputHelp(contextOptions) {
238
+ anyCmd.outputHelp = function patchedOutputHelp(/** @type {any} */ contextOptions) {
234
239
  if (jsonActive()) {
235
240
  if (!process.__xdsJsonHandled) {
236
241
  process.__xdsJsonHandled = true;
@@ -254,7 +259,7 @@ function patchPrototype(CommandCtor) {
254
259
  if (proto.__xdsHelpPatched) return;
255
260
  proto.__xdsHelpPatched = true;
256
261
  const original = proto.outputHelp;
257
- proto.outputHelp = function patchedProtoOutputHelp(contextOptions) {
262
+ proto.outputHelp = function patchedProtoOutputHelp(/** @type {any} */ contextOptions) {
258
263
  if (jsonActive()) {
259
264
  if (!process.__xdsJsonHandled) {
260
265
  process.__xdsJsonHandled = true;
@@ -25,7 +25,7 @@ import * as path from 'node:path';
25
25
  import {fileURLToPath} from 'node:url';
26
26
 
27
27
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
28
- const CLI_BIN = path.resolve(__dirname, '../../bin/astryx.mjs');
28
+ const CLI_BIN = path.resolve(__dirname, '../bin/astryx.mjs');
29
29
 
30
30
  function runCli(args) {
31
31
  const res = spawnSync('node', [CLI_BIN, ...args], {
@@ -112,10 +112,10 @@ export function jsonOut(type, data, meta) {
112
112
  * consumers can branch on it unconditionally.
113
113
  *
114
114
  * @param {unknown} err
115
- * @param {Array<{name: string, reason: string}>} [suggestions]
115
+ * @param {import('../types/base').Suggestion[]} [suggestions]
116
116
  * @param {string} [code] - Explicit stable error code. Overrides any code
117
117
  * carried on a thrown Error.
118
- * @returns {{apiVersion: number, error: string, code: string, suggestions?: Array<{name: string, reason: string}>}}
118
+ * @returns {{apiVersion: number, error: string, code: string, suggestions?: import('../types/base').Suggestion[]}}
119
119
  */
120
120
  export function toErrorEnvelope(err, suggestions, code) {
121
121
  const message =
@@ -136,7 +136,7 @@ export function toErrorEnvelope(err, suggestions, code) {
136
136
  /**
137
137
  * Output a structured JSON error and exit.
138
138
  * @param {string} message
139
- * @param {Array<{name: string, reason: string}>} [suggestions]
139
+ * @param {import('../types/base').Suggestion[]} [suggestions]
140
140
  * @param {string} [code] - Stable machine-readable error code (error-codes.mjs).
141
141
  */
142
142
  export function jsonError(message, suggestions, code) {
@@ -13,8 +13,14 @@
13
13
  * @position lib — shared by string-utils.mjs and lib/xle/validate.mjs
14
14
  */
15
15
 
16
+ /**
17
+ * @param {string} a
18
+ * @param {string} b
19
+ * @returns {number}
20
+ */
16
21
  export function levenshteinDistance(a, b) {
17
22
  const m = a.length, n = b.length;
23
+ /** @type {number[][]} */
18
24
  const dp = Array.from({length: m + 1}, () => Array(n + 1).fill(0));
19
25
  for (let i = 0; i <= m; i++) dp[i][0] = i;
20
26
  for (let j = 0; j <= n; j++) dp[0][j] = j;
@@ -50,6 +50,7 @@ export const RESPONSE_TYPES = {
50
50
  docs: ['docs.list', 'docs.detail', 'docs.detail.section'],
51
51
  discover: ['discover.list', 'discover.detail', 'discover.detail.doc', 'discover.search'],
52
52
  search: ['search'],
53
+ build: ['build.help', 'build.kit'],
53
54
  swizzle: ['swizzle.list', 'swizzle.copy'],
54
55
  template: [
55
56
  'template.list',
@@ -79,6 +80,7 @@ const EXAMPLES = {
79
80
  docs: ['astryx docs', 'astryx docs spacing --json'],
80
81
  discover: ['astryx discover --json'],
81
82
  search: ['astryx search modal --json', 'astryx search button --type component --json'],
83
+ build: ['astryx build', 'astryx build "analytics dashboard" --json'],
82
84
  swizzle: ['astryx swizzle XDSButton'],
83
85
  template: ['astryx template --json', 'astryx template dashboard ./src/app'],
84
86
  hook: ['astryx hook', 'astryx hook useToggle --json'],
@@ -103,7 +105,7 @@ const EXAMPLES = {
103
105
  * option takes a value (boolean vs string), surfaces `choices` and `default`.
104
106
  *
105
107
  * @param {import('commander').Option} opt
106
- * @returns {{flag: string, description: string, type: string, choices?: string[], default?: unknown, negate?: boolean}}
108
+ * @returns {import('../types/manifest').ManifestOption}
107
109
  */
108
110
  function describeOption(opt) {
109
111
  const o = /** @type {any} */ (opt);
@@ -127,7 +129,7 @@ function describeOption(opt) {
127
129
  /**
128
130
  * Map a Commander positional argument to an arg descriptor.
129
131
  * @param {import('commander').Argument} arg
130
- * @returns {{name: string, required: boolean, variadic: boolean, description: string}}
132
+ * @returns {import('../types/manifest').ManifestArgument}
131
133
  */
132
134
  function describeArgument(arg) {
133
135
  const a = /** @type {any} */ (arg);
@@ -163,7 +165,7 @@ function fullName(cmd, root) {
163
165
  * @param {import('commander').Command} cmd
164
166
  * @param {import('commander').Command} root
165
167
  * @param {Set<string>} jsonSupported fully-qualified names that support --json
166
- * @returns {object | null} null for hidden/internal commands
168
+ * @returns {import('../types/manifest').ManifestCommand | null} null for hidden/internal commands
167
169
  */
168
170
  function describeCommand(cmd, root, jsonSupported) {
169
171
  const name = fullName(cmd, root);
@@ -210,7 +212,7 @@ function describeCommand(cmd, root, jsonSupported) {
210
212
  * command entry doesn't repeat them.
211
213
  *
212
214
  * @param {import('commander').Command} program
213
- * @returns {Array<object>}
215
+ * @returns {import('../types/manifest').ManifestOption[]}
214
216
  */
215
217
  function describeGlobalOptions(program) {
216
218
  const opts = (program.options || []).map(describeOption);
@@ -233,7 +235,7 @@ function describeGlobalOptions(program) {
233
235
  * @param {object} [opts]
234
236
  * @param {Set<string>} [opts.jsonSupported] the JSON_SUPPORTED allowlist
235
237
  * @param {string} [opts.version] CLI version (defaults to program.version())
236
- * @returns {object} the manifest `data` payload (sans envelope)
238
+ * @returns {import('../types/manifest').CLIManifest} the manifest `data` payload (sans envelope)
237
239
  */
238
240
  export function buildManifest(program, opts = {}) {
239
241
  const jsonSupported = opts.jsonSupported || new Set();
@@ -18,11 +18,11 @@ import {describe, it, expect} from 'vitest';
18
18
  import {spawnSync} from 'node:child_process';
19
19
  import * as path from 'node:path';
20
20
  import {fileURLToPath} from 'node:url';
21
- import {program, JSON_SUPPORTED} from '../index.mjs';
21
+ import {program, JSON_SUPPORTED} from '../cli/index.mjs';
22
22
  import {buildManifest, RESPONSE_TYPES} from './manifest.mjs';
23
23
 
24
24
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
- const CLI_BIN = path.resolve(__dirname, '../../bin/astryx.mjs');
25
+ const CLI_BIN = path.resolve(__dirname, '../bin/astryx.mjs');
26
26
 
27
27
  const manifest = buildManifest(program, {jsonSupported: JSON_SUPPORTED, version: '0.0.0-test'});
28
28
 
@@ -21,6 +21,7 @@ import * as fs from 'node:fs';
21
21
  import {createJiti} from 'jiti';
22
22
  import {formatZodError} from './config-schema.mjs';
23
23
 
24
+ /** @type {ReturnType<typeof createJiti> | undefined} */
24
25
  let jitiInstance;
25
26
  function getJiti() {
26
27
  if (!jitiInstance) {
@@ -6,9 +6,28 @@
6
6
  import * as fs from 'node:fs';
7
7
  import * as path from 'node:path';
8
8
 
9
+ /**
10
+ * A discovered documentation package (its package.json declares `astryx.docs`).
11
+ * @typedef {object} ScannedPackage
12
+ * @property {string} name
13
+ * @property {string} [version]
14
+ * @property {string} [description]
15
+ * @property {string} [displayName]
16
+ * @property {string} dir
17
+ * @property {Record<string, any>} astryx
18
+ * @property {string} category
19
+ * @property {string} docsDir
20
+ * @property {string[]} components
21
+ */
22
+
23
+ /**
24
+ * @param {string} scanDir
25
+ * @returns {ScannedPackage[]}
26
+ */
9
27
  export function scanDirectory(scanDir) {
10
28
  if (!fs.existsSync(scanDir)) return [];
11
29
  const entries = fs.readdirSync(scanDir, {withFileTypes: true});
30
+ /** @type {ScannedPackage[]} */
12
31
  const packages = [];
13
32
  for (const entry of entries) {
14
33
  if (!entry.isDirectory()) continue;
@@ -40,7 +59,13 @@ export function scanDirectory(scanDir) {
40
59
  return packages;
41
60
  }
42
61
 
62
+ /**
63
+ * @param {string[]} packageDirs
64
+ * @param {ScannedPackage[]} [explicitPackages]
65
+ * @returns {ScannedPackage[]}
66
+ */
43
67
  export function scanAllPackages(packageDirs, explicitPackages = []) {
68
+ /** @type {ScannedPackage[]} */
44
69
  const all = [];
45
70
  const seen = new Set();
46
71
 
@@ -62,10 +87,17 @@ export function scanAllPackages(packageDirs, explicitPackages = []) {
62
87
  return all;
63
88
  }
64
89
 
90
+ /**
91
+ * @param {string} docsDir
92
+ * @returns {string[]}
93
+ */
65
94
  function discoverDocComponents(docsDir) {
66
95
  if (!fs.existsSync(docsDir)) return [];
96
+ /** @type {string[]} */
67
97
  const components = [];
98
+ /** @param {string} dir */
68
99
  function walk(dir) {
100
+ /** @type {import('node:fs').Dirent[]} */
69
101
  let entries;
70
102
  try {
71
103
  entries = fs.readdirSync(dir, {withFileTypes: true});
@@ -84,6 +116,11 @@ function discoverDocComponents(docsDir) {
84
116
  return components.sort();
85
117
  }
86
118
 
119
+ /**
120
+ * @param {ScannedPackage[]} packages
121
+ * @param {string} name
122
+ * @returns {{pkg: ScannedPackage, docPath: string, componentName: string} | null}
123
+ */
87
124
  export function findComponentInPackages(packages, name) {
88
125
  const lower = name.toLowerCase();
89
126
  for (const pkg of packages) {
@@ -95,9 +132,19 @@ export function findComponentInPackages(packages, name) {
95
132
  return null;
96
133
  }
97
134
 
135
+ /**
136
+ * @param {string} docsDir
137
+ * @param {string} name
138
+ * @returns {string | null}
139
+ */
98
140
  function findDocFile(docsDir, name) {
99
141
  const target = name + '.doc.mjs';
142
+ /**
143
+ * @param {string} dir
144
+ * @returns {string | null}
145
+ */
100
146
  function walk(dir) {
147
+ /** @type {import('node:fs').Dirent[]} */
101
148
  let entries;
102
149
  try {
103
150
  entries = fs.readdirSync(dir, {withFileTypes: true});
@@ -44,19 +44,42 @@ import {findCoreDir} from '../utils/paths.mjs';
44
44
  import {
45
45
  discoverTemplates,
46
46
  discoverIntegrationTemplatesForOne,
47
- } from '../api/template.mjs';
47
+ } from '../api/template/template.mjs';
48
48
  import {getTransformsBetween} from '../codemods/registry.mjs';
49
49
  import {
50
50
  discoverIntegrationCodemods,
51
51
  selectIntegrationCodemods,
52
52
  } from '../codemods/integration-discovery.mjs';
53
- import {validateLoadedIntegration} from '../api/validate-integration.mjs';
53
+ import {validateLoadedIntegration} from '../api/integration/validate-integration.mjs';
54
54
  import {
55
55
  InMemoryConfigCache,
56
56
  cacheKey,
57
57
  configContentHash,
58
58
  } from './config-cache.mjs';
59
59
 
60
+ /**
61
+ * Extract a human-readable message from an unknown thrown value.
62
+ * Reproduces the historical `err?.message ?? String(err)` behavior in a
63
+ * strict-checkJs-safe way: prefer a non-nullish `.message` (covers Error
64
+ * instances and error-like objects thrown by integration code), else `String()`.
65
+ * @param {unknown} err
66
+ * @returns {string}
67
+ */
68
+ function errorMessage(err) {
69
+ const message =
70
+ err && typeof err === 'object' && 'message' in err
71
+ ? /** @type {{message: unknown}} */ (err).message
72
+ : undefined;
73
+ return message == null ? String(err) : String(message);
74
+ }
75
+
76
+ /**
77
+ * An integration issue tagged with the owner package. The base
78
+ * {@link import('../types/integration').AstryxIntegrationIssue} fields plus the
79
+ * `package` that produced it, which Project tracks for routing/dedup.
80
+ * @typedef {import('../types/integration').AstryxIntegrationIssue & {package: string}} ProjectIntegrationIssue
81
+ */
82
+
60
83
  /** Conventional config basenames, in load-precedence order. */
61
84
  export const CONFIG_BASENAMES = [
62
85
  'astryx.config.ts',
@@ -117,13 +140,13 @@ export class Project {
117
140
  #config;
118
141
  /** @type {string[]} */
119
142
  #integrations;
120
- /** @type {Array<object>} */
143
+ /** @type {import('./integrations.mjs').LoadedIntegration[]} */
121
144
  #loadedIntegrations;
122
145
  /** @type {import('./config-cache.mjs').ConfigCache} */
123
146
  #cache;
124
147
  /** @type {string} */
125
148
  #hash;
126
- /** @type {import('../types/integration').AstryxIntegrationIssue[]} */
149
+ /** @type {ProjectIntegrationIssue[]} */
127
150
  #issues = [];
128
151
  /**
129
152
  * Package names of integrations whose issues have already been collected
@@ -137,9 +160,9 @@ export class Project {
137
160
  * @param {object} init
138
161
  * @param {string} init.cwd
139
162
  * @param {string|null} init.configPath
140
- * @param {object} init.config validated AstryxConfig surface
163
+ * @param {import('../types/config').AstryxConfig} init.config validated AstryxConfig surface
141
164
  * @param {string[]} init.integrations
142
- * @param {Array<object>} init.loadedIntegrations
165
+ * @param {import('./integrations.mjs').LoadedIntegration[]} init.loadedIntegrations
143
166
  * @param {import('./config-cache.mjs').ConfigCache} init.cache
144
167
  * @param {string} init.hash config content hash
145
168
  */
@@ -175,8 +198,11 @@ export class Project {
175
198
  const configPath = findConfigPath(cwd);
176
199
  const hash = configContentHash(configPath);
177
200
 
201
+ /** @type {import('../types/config').AstryxConfig} */
178
202
  let config = {integrations: []};
203
+ /** @type {string[]} */
179
204
  let integrations = [];
205
+ /** @type {import('./integrations.mjs').LoadedIntegration[]} */
180
206
  let loadedIntegrations = [];
181
207
 
182
208
  if (configPath) {
@@ -204,7 +230,7 @@ export class Project {
204
230
  /**
205
231
  * The validated config surface (same data loadConfig returned, minus the
206
232
  * resolved `loadedIntegrations` which is exposed separately).
207
- * @returns {{integrations?: string[], issuesUrl?: string, hooks?: object, experimental?: object}}
233
+ * @returns {import('../types/config').AstryxConfig}
208
234
  */
209
235
  get config() {
210
236
  return this.#config;
@@ -215,7 +241,7 @@ export class Project {
215
241
  return this.#integrations;
216
242
  }
217
243
 
218
- /** Resolved loaded integrations (lib/integrations.mjs shape). @returns {Array<object>} */
244
+ /** Resolved loaded integrations (lib/integrations.mjs shape). @returns {import('./integrations.mjs').LoadedIntegration[]} */
219
245
  get loadedIntegrations() {
220
246
  return this.#loadedIntegrations;
221
247
  }
@@ -245,7 +271,7 @@ export class Project {
245
271
  */
246
272
  async #memo(kind, produce) {
247
273
  const key = cacheKey(this.#hash, this.#cwd, kind);
248
- const hit = this.#cache.get(key);
274
+ const hit = /** @type {{value: T} | undefined} */ (this.#cache.get(key));
249
275
  if (hit !== undefined) return hit.value;
250
276
  const value = await produce();
251
277
  this.#cache.set(key, {value});
@@ -272,7 +298,10 @@ export class Project {
272
298
  });
273
299
  }
274
300
 
275
- /** Package label for a loaded integration. */
301
+ /** Package label for a loaded integration.
302
+ * @param {import('./integrations.mjs').LoadedIntegration} integration
303
+ * @returns {string}
304
+ */
276
305
  #pkgLabel(integration) {
277
306
  return integration?.name ?? integration?.__spec ?? '(integration)';
278
307
  }
@@ -281,7 +310,7 @@ export class Project {
281
310
  * Validate one loaded integration and collect any issues. Marks the
282
311
  * integration visited so issues() won't redo the work. Best-effort: a
283
312
  * validator throwing is itself recorded as an issue, never propagated.
284
- * @param {object} integration
313
+ * @param {import('./integrations.mjs').LoadedIntegration} integration
285
314
  */
286
315
  async #collectIssues(integration) {
287
316
  const pkg = this.#pkgLabel(integration);
@@ -294,7 +323,7 @@ export class Project {
294
323
  this.#pushIssue(pkg, {
295
324
  code: 'integration_error',
296
325
  severity: 'error',
297
- message: err?.message ?? String(err),
326
+ message: errorMessage(err),
298
327
  });
299
328
  }
300
329
  }
@@ -311,7 +340,7 @@ export class Project {
311
340
  async components() {
312
341
  return this.#memo('components', async () => {
313
342
  const coreDir = findCoreDir(this.#cwd);
314
- /** @type {Array<object>} */
343
+ /** @type {Array<{name: string, package: string, group: string|null, docPath: string|null, sourcePath: string|null, issuesUrl: string|undefined}>} */
315
344
  const records = [];
316
345
 
317
346
  // Core records (no integrations) — never integration-broken.
@@ -343,7 +372,7 @@ export class Project {
343
372
  this.#pushIssue(pkg, {
344
373
  code: 'invalid_component',
345
374
  severity: 'error',
346
- message: err?.message ?? String(err),
375
+ message: errorMessage(err),
347
376
  });
348
377
  }
349
378
  }
@@ -362,7 +391,7 @@ export class Project {
362
391
  */
363
392
  async templates() {
364
393
  return this.#memo('templates', async () => {
365
- /** @type {Array<object>} */
394
+ /** @type {any[]} */
366
395
  const templates = [];
367
396
 
368
397
  // Core + external-package templates (discoverTemplates internally also
@@ -371,7 +400,7 @@ export class Project {
371
400
  // path so the skip+warn policy and issue collection apply, then dedupe).
372
401
  try {
373
402
  const core = await discoverTemplates(this.#cwd);
374
- for (const t of core) {
403
+ for (const t of /** @type {any[]} */ (core)) {
375
404
  // Skip integration-owned templates here; they are re-added (and
376
405
  // issue-collected) per integration below to honor skip+warn.
377
406
  if (t.package && t.package !== CORE_PACKAGE) continue;
@@ -405,7 +434,7 @@ export class Project {
405
434
  this.#pushIssue(pkg, {
406
435
  code: 'invalid_template',
407
436
  severity: 'error',
408
- message: err?.message ?? String(err),
437
+ message: errorMessage(err),
409
438
  });
410
439
  }
411
440
  }
@@ -431,6 +460,7 @@ export class Project {
431
460
 
432
461
  // Discover integration codemods per integration so a single broken
433
462
  // integration is skipped (issue collected) without losing the others.
463
+ /** @type {import('./integrations.mjs').LoadedIntegration[]} */
434
464
  const good = [];
435
465
  for (const integration of this.#loadedIntegrations) {
436
466
  await this.#collectIssues(integration);
@@ -449,7 +479,7 @@ export class Project {
449
479
  this.#pushIssue(pkg, {
450
480
  code: 'invalid_codemod',
451
481
  severity: 'error',
452
- message: err?.message ?? String(err),
482
+ message: errorMessage(err),
453
483
  });
454
484
  }
455
485
  }
@@ -13,7 +13,7 @@ let originalCwd;
13
13
 
14
14
  const codemodModulePath = path.resolve(
15
15
  process.cwd(),
16
- 'packages/cli/src/codemod.mjs',
16
+ 'packages/cli/authoring/codemod.mjs',
17
17
  );
18
18
  const codemodModuleUrl = pathToFileURL(codemodModulePath).href;
19
19
 
@@ -25,6 +25,9 @@ const _require = createRequire(import.meta.url);
25
25
  /**
26
26
  * Try to load a module, returning the default export or the module itself.
27
27
  * Returns null if the module cannot be found.
28
+ * @param {string} specifier
29
+ * @param {string} cwd
30
+ * @returns {unknown}
28
31
  */
29
32
  function tryLoadModule(specifier, cwd) {
30
33
  // For relative/absolute paths, resolve against cwd
@@ -49,6 +52,8 @@ function tryLoadModule(specifier, cwd) {
49
52
  * Extract theme data from a loaded module.
50
53
  * Handles both `module.default` and direct `module` patterns,
51
54
  * as well as named exports like `module.theme` or `module.{name}Theme`.
55
+ * @param {any} mod
56
+ * @returns {any}
52
57
  */
53
58
  function extractTheme(mod) {
54
59
  if (!mod || typeof mod !== 'object') return null;
@@ -13,6 +13,10 @@ export {levenshteinDistance} from './levenshtein.mjs';
13
13
  /**
14
14
  * Find the closest component names to a given (possibly misspelled) name.
15
15
  * Returns matches sorted by distance, filtered to maxDistance.
16
+ * @param {string} name
17
+ * @param {Record<string, string[]>} components
18
+ * @param {number} [maxDistance]
19
+ * @returns {{name: string, distance: number}[]}
16
20
  */
17
21
  export function findClosestComponents(name, components, maxDistance = 3) {
18
22
  const allNames = Object.values(components).flat();
@@ -45,6 +49,11 @@ export function findClosestComponents(name, components, maxDistance = 3) {
45
49
  * 20 name Levenshtein distance 3
46
50
  *
47
51
  * Each result: { name, score, reason }
52
+ *
53
+ * @param {string} needle
54
+ * @param {string} coreDir
55
+ * @param {Record<string, string[]>} components
56
+ * @returns {Promise<{name: string, score: number, reason: string}[]>}
48
57
  */
49
58
  export async function searchComponents(needle, coreDir, components) {
50
59
  const {pathToFileURL} = await import('node:url');
@@ -53,8 +62,14 @@ export async function searchComponents(needle, coreDir, components) {
53
62
 
54
63
  const term = needle.toLowerCase();
55
64
  const allNames = Object.values(components).flat();
65
+ /** @type {Map<string, {name: string, score: number, reason: string}>} */
56
66
  const scored = new Map();
57
67
 
68
+ /**
69
+ * @param {string} name
70
+ * @param {number} score
71
+ * @param {string} reason
72
+ */
58
73
  function addMatch(name, score, reason) {
59
74
  const existing = scored.get(name);
60
75
  if (!existing || score > existing.score) {