@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
@@ -9,8 +9,8 @@
9
9
 
10
10
  import * as fs from 'node:fs';
11
11
  import * as path from 'node:path';
12
- import {ERROR_CODES} from '../lib/error-codes.mjs';
13
- import {findCoreDir, discoverExternalPackages} from '../utils/paths.mjs';
12
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
13
+ import {findCoreDir, discoverExternalPackages} from '../../utils/paths.mjs';
14
14
  import {
15
15
  CORE_PACKAGE,
16
16
  discoverComponents,
@@ -22,24 +22,46 @@ import {
22
22
  findIntegrationComponentDoc,
23
23
  findIntegrationComponentSource,
24
24
  resolveImportPath,
25
- } from '../lib/component-discovery.mjs';
26
- import {Project} from '../lib/project.mjs';
27
- import {loadDocs} from '../lib/component-loader.mjs';
28
- import {searchComponents} from '../lib/string-utils.mjs';
29
- import {AstryxError} from './error.mjs';
30
- import {findShowcase, findRelatedBlocks} from './template.mjs';
25
+ } from '../../lib/component-discovery.mjs';
26
+ import {Project} from '../../lib/project.mjs';
27
+ import {loadDocs} from '../../lib/component-loader.mjs';
28
+ import {searchComponents} from '../../lib/string-utils.mjs';
29
+ import {AstryxError} from '../error.mjs';
30
+ import {findShowcase, findRelatedBlocks} from '../template/template.mjs';
31
+
32
+ /**
33
+ * A loaded component doc. `loadDocs` returns the authored `.doc.mjs` shape,
34
+ * which is either a single-component or multi-component doc; this loose view
35
+ * captures the fields the API reads across both forms.
36
+ * @typedef {object} LoadedComponentDoc
37
+ * @property {string} [name]
38
+ * @property {string} [description]
39
+ * @property {any[]} [props]
40
+ * @property {any[]} [components]
41
+ * @property {{description?: string}} [usage]
42
+ * @property {any} [theming]
43
+ */
44
+
45
+ /**
46
+ * Options object for `loadDocs`, matching its declared parameter shape (used
47
+ * as a cast target so `lang` (which the API may hold as `string|null`) type
48
+ * checks against `loadDocs`'s `lang?: string`).
49
+ * @typedef {{zh?: boolean, dense?: boolean, lang?: string}} LoadDocsOpts
50
+ */
31
51
 
32
52
  /**
33
53
  * Load the configured integrations for `cwd`, swallowing any config errors so
34
54
  * component discovery never hard-fails on a malformed/absent integration. An
35
55
  * empty list means "core only".
36
56
  * @param {string} cwd
37
- * @returns {Promise<Array<{name: string, components?: string, issuesUrl?: string}>>}
57
+ * @returns {Promise<import('../../lib/integrations.mjs').LoadedIntegration[]>}
38
58
  */
39
59
  async function loadIntegrationsSafely(cwd) {
40
60
  try {
41
61
  const project = await Project.load(cwd);
42
- return project.loadedIntegrations;
62
+ return /** @type {import('../../lib/integrations.mjs').LoadedIntegration[]} */ (
63
+ project.loadedIntegrations
64
+ );
43
65
  } catch {
44
66
  return [];
45
67
  }
@@ -47,7 +69,7 @@ async function loadIntegrationsSafely(cwd) {
47
69
 
48
70
  /**
49
71
  * Resolve a loaded integration by package name.
50
- * @param {Array<{name: string}>} loadedIntegrations
72
+ * @param {import('../../lib/integrations.mjs').LoadedIntegration[]} loadedIntegrations
51
73
  * @param {string} packageName
52
74
  */
53
75
  function findLoadedIntegration(loadedIntegrations, packageName) {
@@ -133,7 +155,7 @@ export async function component(name, options = {}) {
133
155
  const readme = findComponentReadme(coreDir, comp);
134
156
  if (readme && readme.endsWith('.doc.mjs')) {
135
157
  try {
136
- const docs = await loadDocs(readme, {zh, lang});
158
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(readme, /** @type {LoadDocsOpts} */ ({zh, lang})));
137
159
  entries.push({name: comp, description: docs.usage?.description || docs.description || '', import: resolveImportPath(coreDir, comp)});
138
160
  } catch {
139
161
  entries.push({name: comp, description: '', import: resolveImportPath(coreDir, comp)});
@@ -151,7 +173,7 @@ export async function component(name, options = {}) {
151
173
  const readme = findComponentReadme(coreDir, comp);
152
174
  if (readme && readme.endsWith('.doc.mjs')) {
153
175
  try {
154
- entries.push(await loadDocs(readme, {zh, lang, dense}));
176
+ entries.push(await loadDocs(readme, /** @type {LoadDocsOpts} */ ({zh, lang, dense})));
155
177
  } catch {
156
178
  entries.push({name: `XDS${comp}`, description: ''});
157
179
  }
@@ -173,7 +195,7 @@ export async function component(name, options = {}) {
173
195
 
174
196
  // All components — merge core + external packages with grouped subcategories
175
197
  if (detail === 'compact') {
176
- /** @type {Record<string, Array<import('../types/component').ComponentBriefEntry>>} */
198
+ /** @type {Record<string, Array<import('../../types/component').ComponentBriefEntry>>} */
177
199
  const result = {};
178
200
  for (const [cat, comps] of Object.entries(components)) {
179
201
  result[cat] = [];
@@ -181,7 +203,7 @@ export async function component(name, options = {}) {
181
203
  const readme = findComponentReadme(coreDir, comp);
182
204
  if (readme && readme.endsWith('.doc.mjs')) {
183
205
  try {
184
- const docs = await loadDocs(readme, {zh, lang});
206
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(readme, /** @type {LoadDocsOpts} */ ({zh, lang})));
185
207
  result[cat].push({name: comp, description: docs.usage?.description || docs.description || '', import: resolveImportPath(coreDir, comp)});
186
208
  } catch {
187
209
  result[cat].push({name: comp, description: '', import: resolveImportPath(coreDir, comp)});
@@ -203,7 +225,7 @@ export async function component(name, options = {}) {
203
225
  const readme = findComponentReadme(coreDir, comp);
204
226
  if (readme && readme.endsWith('.doc.mjs')) {
205
227
  try {
206
- result[cat].push(await loadDocs(readme, {zh, lang, dense}));
228
+ result[cat].push(await loadDocs(readme, /** @type {LoadDocsOpts} */ ({zh, lang, dense})));
207
229
  } catch {
208
230
  result[cat].push({name: `XDS${comp}`, description: ''});
209
231
  }
@@ -238,7 +260,7 @@ export async function component(name, options = {}) {
238
260
  const groupLabel = rec.group ?? integration.name;
239
261
  const key = `${groupLabel} (${integration.name})`;
240
262
  if (!byGroup.has(key)) byGroup.set(key, []);
241
- byGroup.get(key).push({name: rec.name, package: integration.name});
263
+ byGroup.get(key)?.push({name: rec.name, package: integration.name});
242
264
  }
243
265
  for (const [key, members] of byGroup) {
244
266
  members.sort((a, b) => a.name.localeCompare(b.name));
@@ -334,14 +356,14 @@ export async function component(name, options = {}) {
334
356
  * `package`, the resolved `import` specifier, and `sourceAvailable` (whether
335
357
  * a swizzleable source file exists for the owner). Existing doc fields
336
358
  * (name, usage, props, …) are preserved.
337
- * @param {object} docs
359
+ * @param {LoadedComponentDoc} docs
338
360
  * @param {{package: string, sourcePath: string|null}} owner
339
361
  * @param {string} componentName
340
362
  */
341
363
  function withOwnership(docs, owner, componentName) {
342
364
  const importSpec =
343
365
  owner.package === CORE_PACKAGE
344
- ? resolveImportPath(coreDir, componentName)
366
+ ? resolveImportPath(/** @type {string} */ (coreDir), componentName)
345
367
  : `${owner.package}/${componentName}`;
346
368
  return {
347
369
  ...docs,
@@ -368,7 +390,7 @@ export async function component(name, options = {}) {
368
390
  }
369
391
  return {type: 'component.detail.source', data: {component: dirName, source: fs.readFileSync(owner.sourcePath, 'utf-8')}};
370
392
  }
371
- const docs = await loadDocs(owner.docPath, {zh, dense, lang});
393
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(owner.docPath, /** @type {LoadDocsOpts} */ ({zh, dense, lang})));
372
394
  if (props) {
373
395
  const p = docs.props || (docs.components ? docs.components.flatMap(c => c.props || []) : []);
374
396
  return {type: 'component.detail.props', data: p};
@@ -389,7 +411,7 @@ export async function component(name, options = {}) {
389
411
  }
390
412
  return {type: 'component.detail.source', data: {component: dirName, source: fs.readFileSync(owner.sourcePath, 'utf-8')}};
391
413
  }
392
- const docs = await loadDocs(owner.docPath, {zh, dense, lang});
414
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(owner.docPath, /** @type {LoadDocsOpts} */ ({zh, dense, lang})));
393
415
  if (props) {
394
416
  const p = docs.props || (docs.components ? docs.components.flatMap(c => c.props || []) : []);
395
417
  return {type: 'component.detail.props', data: p};
@@ -420,7 +442,7 @@ export async function component(name, options = {}) {
420
442
 
421
443
  const extDocPath = findExternalComponentDoc(ext.docsDir, dirName);
422
444
  if (extDocPath && extDocPath.endsWith('.doc.mjs')) {
423
- const docs = await loadDocs(extDocPath, {zh, dense, lang});
445
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(extDocPath, /** @type {LoadDocsOpts} */ ({zh, dense, lang})));
424
446
 
425
447
  if (props) {
426
448
  const p = docs.props || (docs.components ? docs.components.flatMap(c => c.props || []) : []);
@@ -461,7 +483,7 @@ export async function component(name, options = {}) {
461
483
  if (showcase) {
462
484
  throw new AstryxError(`No showcase found for "${name}"`, undefined, ERROR_CODES.ERR_NO_SHOWCASE);
463
485
  }
464
- const docs = await loadDocs(owner.docPath, {zh, dense, lang});
486
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(owner.docPath, /** @type {LoadDocsOpts} */ ({zh, dense, lang})));
465
487
  if (props) {
466
488
  const p = docs.props || (docs.components ? docs.components.flatMap(c => c.props || []) : []);
467
489
  return {type: 'component.detail.props', data: p};
@@ -546,12 +568,12 @@ export async function component(name, options = {}) {
546
568
  throw new AstryxError(`No .doc.mjs found for "${resolvedName}". The component needs a typed doc file.`, undefined, ERROR_CODES.ERR_NO_DOC);
547
569
  }
548
570
 
549
- const docs = await loadDocs(readmePath, {zh, dense, lang});
571
+ const docs = /** @type {LoadedComponentDoc} */ (await loadDocs(readmePath, /** @type {LoadDocsOpts} */ ({zh, dense, lang})));
550
572
 
551
573
  // ── Blocks mode ──────────────────────────────────────────────
552
574
  if (blocks) {
553
575
  const allBlocks = await findRelatedBlocks(dirName);
554
- const toEntry = (b) => ({
576
+ const toEntry = (/** @type {any} */ b) => ({
555
577
  name: b.dirName,
556
578
  displayName: b.name,
557
579
  description: b.description,
@@ -561,7 +583,7 @@ export async function component(name, options = {}) {
561
583
 
562
584
  // Examples: blocks in the component's own directory, or
563
585
  // componentsUsed match for sub-components without a directory.
564
- const ownDir = allBlocks.filter(b => path.basename(b.category) === dirName);
586
+ const ownDir = allBlocks.filter((/** @type {any} */ b) => path.basename(b.category) === dirName);
565
587
  const examples = ownDir.length > 0
566
588
  ? ownDir
567
589
  : allBlocks.filter(b => b.componentsUsed?.some(c => c === dirName));
@@ -595,6 +617,7 @@ export async function component(name, options = {}) {
595
617
  : null;
596
618
 
597
619
  if (matchingComponent) {
620
+ /** @type {LoadedComponentDoc & {parentDoc?: string, import?: string}} */
598
621
  const scoped = {
599
622
  name: dirName,
600
623
  description: matchingComponent.description,
@@ -4,28 +4,37 @@
4
4
  * @file Programmatic API for the discover command.
5
5
  */
6
6
 
7
- import {Project} from '../lib/project.mjs';
7
+ import {Project} from '../../lib/project.mjs';
8
8
  import {
9
9
  scanAllPackages,
10
10
  findComponentInPackages,
11
- } from '../lib/package-scanner.mjs';
12
- import {loadDocs} from '../lib/component-loader.mjs';
13
- import {levenshteinDistance} from '../lib/string-utils.mjs';
14
- import {AstryxError} from './error.mjs';
15
- import {ERROR_CODES} from '../lib/error-codes.mjs';
11
+ } from '../../lib/package-scanner.mjs';
12
+ import {loadDocs} from '../../lib/component-loader.mjs';
13
+ import {levenshteinDistance} from '../../lib/string-utils.mjs';
14
+ import {AstryxError} from '../error.mjs';
15
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
16
16
 
17
+ /**
18
+ * @typedef {import('../../lib/package-scanner.mjs').ScannedPackage} ScannedPackage
19
+ */
20
+
21
+ /**
22
+ * @param {unknown} docs
23
+ * @returns {string | null}
24
+ */
17
25
  function validateDocs(docs) {
18
26
  if (!docs || typeof docs !== 'object')
19
27
  return 'docs export is missing or not an object';
20
- if (typeof docs.name !== 'string' || !docs.name)
28
+ const d = /** @type {Record<string, any>} */ (docs);
29
+ if (typeof d.name !== 'string' || !d.name)
21
30
  return 'docs.name is missing or not a string';
22
- if (!docs.usage || typeof docs.usage.description !== 'string')
31
+ if (!d.usage || typeof d.usage.description !== 'string')
23
32
  return 'docs.usage.description is missing or not a string';
24
- if (docs.props && !Array.isArray(docs.props))
33
+ if (d.props && !Array.isArray(d.props))
25
34
  return 'docs.props must be an array';
26
- if (docs.components && !Array.isArray(docs.components))
35
+ if (d.components && !Array.isArray(d.components))
27
36
  return 'docs.components must be an array';
28
- if (docs.usage?.bestPractices && !Array.isArray(docs.usage.bestPractices))
37
+ if (d.usage?.bestPractices && !Array.isArray(d.usage.bestPractices))
29
38
  return 'docs.usage.bestPractices must be an array';
30
39
  return null;
31
40
  }
@@ -36,11 +45,21 @@ function validateDocs(docs) {
36
45
  * @param {boolean} [options.components]
37
46
  * @param {string} [options.lang]
38
47
  * @param {boolean} [options.zh]
39
- * @returns {Promise<{type: string, data: unknown}>}
48
+ * @returns {Promise<
49
+ * import('../../types/discover').DiscoverListResponse |
50
+ * import('../../types/discover').DiscoverDetailResponse |
51
+ * import('../../types/discover').DiscoverDetailDocResponse |
52
+ * import('../../types/discover').DiscoverSearchResponse
53
+ * >}
40
54
  */
41
55
  export async function discover(query, options = {}) {
42
56
  const {lang = null, zh = false} = options;
43
57
  const project = await Project.load();
58
+ const loadedIntegrations =
59
+ /** @type {import('../../lib/integrations.mjs').LoadedIntegration[]} */ (
60
+ project.loadedIntegrations
61
+ );
62
+ /** @param {ScannedPackage} pkg */
44
63
  const toEntry = pkg => ({
45
64
  name: pkg.name,
46
65
  category: pkg.category,
@@ -52,7 +71,7 @@ export async function discover(query, options = {}) {
52
71
 
53
72
  // External packages come from configured integrations that declare a
54
73
  // components root. Each becomes a scannable package keyed by its docsDir.
55
- const explicitPackages = project.loadedIntegrations
74
+ const explicitPackages = loadedIntegrations
56
75
  .filter(integration => integration.components)
57
76
  .map(integration => ({
58
77
  name: integration.name,
@@ -64,7 +83,10 @@ export async function discover(query, options = {}) {
64
83
  return {type: 'discover.list', data: [], meta: {configured: false}};
65
84
  }
66
85
 
67
- const packages = scanAllPackages([], explicitPackages);
86
+ const packages = scanAllPackages(
87
+ [],
88
+ /** @type {ScannedPackage[]} */ (/** @type {unknown} */ (explicitPackages)),
89
+ );
68
90
 
69
91
  if (packages.length === 0) {
70
92
  return {type: 'discover.list', data: [], meta: {configured: true}};
@@ -105,7 +127,7 @@ export async function discover(query, options = {}) {
105
127
  return await loadAndValidate(exact, {lang, zh});
106
128
  }
107
129
 
108
- const substringMatches = [];
130
+ const substringMatches = /** @type {Array<{pkg: ScannedPackage, comp: string}>} */ ([]);
109
131
  for (const pkg of packages) {
110
132
  for (const comp of pkg.components) {
111
133
  if (comp.toLowerCase().includes(lower)) {
@@ -134,7 +156,7 @@ export async function discover(query, options = {}) {
134
156
  }
135
157
 
136
158
  // Fuzzy fallback
137
- const allComponents = [];
159
+ const allComponents = /** @type {Array<{pkg: ScannedPackage, comp: string}>} */ ([]);
138
160
  for (const pkg of packages) {
139
161
  for (const comp of pkg.components) {
140
162
  allComponents.push({pkg, comp});
@@ -167,6 +189,13 @@ export async function discover(query, options = {}) {
167
189
  );
168
190
  }
169
191
 
192
+ /**
193
+ * @param {ScannedPackage[]} packages
194
+ * @param {string} compName
195
+ * @param {string} pkgName
196
+ * @param {{lang?: string|null, zh?: boolean}} opts
197
+ * @returns {Promise<import('../../types/discover').DiscoverDetailDocResponse>}
198
+ */
170
199
  async function resolveComponentDocs(packages, compName, pkgName, {lang, zh}) {
171
200
  const pkg = packages.find(p => p.name === pkgName);
172
201
  if (!pkg)
@@ -202,13 +231,21 @@ async function resolveComponentDocs(packages, compName, pkgName, {lang, zh}) {
202
231
  return await loadAndValidate(result, {lang, zh});
203
232
  }
204
233
 
234
+ /**
235
+ * @param {{docPath: string, componentName: string, pkg: ScannedPackage}} result
236
+ * @param {{lang?: string|null, zh?: boolean}} opts
237
+ * @returns {Promise<import('../../types/discover').DiscoverDetailDocResponse>}
238
+ */
205
239
  async function loadAndValidate(result, {lang, zh}) {
206
240
  let docs;
207
241
  try {
208
- docs = await loadDocs(result.docPath, {zh, lang});
242
+ docs = await loadDocs(
243
+ result.docPath,
244
+ /** @type {{zh?: boolean, dense?: boolean, lang?: string}} */ ({zh, lang}),
245
+ );
209
246
  } catch (e) {
210
247
  throw new AstryxError(
211
- `Failed to load docs for ${result.componentName}: ${e.message}`,
248
+ `Failed to load docs for ${result.componentName}: ${/** @type {any} */ (e).message}`,
212
249
  undefined,
213
250
  ERROR_CODES.ERR_INVALID_DOC,
214
251
  );
@@ -7,13 +7,17 @@
7
7
  import * as fs from 'node:fs';
8
8
  import * as path from 'node:path';
9
9
  import {pathToFileURL} from 'node:url';
10
- import {CLI_ROOT} from '../utils/paths.mjs';
11
- import {AstryxError} from './error.mjs';
12
- import {ERROR_CODES} from '../lib/error-codes.mjs';
10
+ import {CLI_ROOT} from '../../utils/paths.mjs';
11
+ import {AstryxError} from '../error.mjs';
12
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
13
13
 
14
14
  const DOCS_DIR = path.join(CLI_ROOT, 'docs');
15
15
 
16
+ /**
17
+ * @returns {Record<string, string>}
18
+ */
16
19
  function discoverTopics() {
20
+ /** @type {Record<string, string>} */
17
21
  const topics = {};
18
22
  if (!fs.existsSync(DOCS_DIR)) return topics;
19
23
  for (const file of fs.readdirSync(DOCS_DIR)) {
@@ -23,6 +27,11 @@ function discoverTopics() {
23
27
  return topics;
24
28
  }
25
29
 
30
+ /**
31
+ * @param {string} docPath
32
+ * @param {{lang?: string|null}} [opts]
33
+ * @returns {Promise<import('../../types/docs').DocsDetailResponse['data']>}
34
+ */
26
35
  async function loadReferenceDocs(docPath, {lang} = {}) {
27
36
  const mod = await import(pathToFileURL(docPath).href);
28
37
  const docs = mod.docs;
@@ -45,6 +54,7 @@ async function loadReferenceDocs(docPath, {lang} = {}) {
45
54
  // printed the colour table under a "Spacing" heading (#2182). An overlay may
46
55
  // now cover any subset of sections, in any order; sections it does not name
47
56
  // keep their base content.
57
+ /** @type {Map<string, any>} */
48
58
  const bySection = new Map();
49
59
  for (const ts of translation.sections ?? []) {
50
60
  if (ts?.section != null) bySection.set(ts.section, ts);
@@ -53,32 +63,43 @@ async function loadReferenceDocs(docPath, {lang} = {}) {
53
63
  return {
54
64
  ...docs,
55
65
  description: translation.description || docs.description,
56
- sections: docs.sections.map(section => {
57
- const ts = bySection.get(section.title);
58
- if (!ts) return section;
59
- return {
60
- ...section,
61
- title: ts.title || section.title,
62
- content: section.content.map((block, bi) => {
63
- const tb = ts.content?.[bi];
64
- if (!tb) return block;
65
- if (tb.type === 'prose' && block.type === 'prose') return {...block, text: tb.text};
66
- if (tb.type === 'list' && block.type === 'list') return {...block, items: tb.items};
67
- return block;
68
- }),
69
- };
70
- }),
66
+ sections: docs.sections.map(
67
+ (/** @type {import('../../../core/src/docs-types').ReferenceSection} */ section) => {
68
+ const ts = bySection.get(section.title);
69
+ if (!ts) return section;
70
+ return {
71
+ ...section,
72
+ title: ts.title || section.title,
73
+ content: section.content.map(
74
+ (
75
+ /** @type {import('../../../core/src/docs-types').ContentBlock} */ block,
76
+ /** @type {number} */ bi,
77
+ ) => {
78
+ const tb = ts.content?.[bi];
79
+ if (!tb) return block;
80
+ if (tb.type === 'prose' && block.type === 'prose') return {...block, text: tb.text};
81
+ if (tb.type === 'list' && block.type === 'list') return {...block, items: tb.items};
82
+ return block;
83
+ },
84
+ ),
85
+ };
86
+ },
87
+ ),
71
88
  };
72
89
  }
73
90
 
74
91
  /**
75
92
  * Resolve token-ref blocks by inlining the referenced section's table.
76
93
  * This allows section docs to reference token tables without duplicating data.
94
+ * @param {import('../../types/docs').DocsDetailResponse['data']} docsData
95
+ * @param {Record<string, string>} topics
96
+ * @returns {Promise<import('../../types/docs').DocsDetailResponse['data']>}
77
97
  */
78
98
  async function resolveTokenRefs(docsData, topics) {
79
99
  const resolved = {...docsData, sections: [...docsData.sections]};
80
100
  for (let si = 0; si < resolved.sections.length; si++) {
81
101
  const section = resolved.sections[si];
102
+ /** @type {import('../../../core/src/docs-types').ContentBlock[]} */
82
103
  const newContent = [];
83
104
  for (const block of section.content) {
84
105
  if (block.type === 'token-ref') {
@@ -90,7 +111,8 @@ async function resolveTokenRefs(docsData, topics) {
90
111
  const refMod = await import(pathToFileURL(refPath).href);
91
112
  const refDocs = refMod.docs;
92
113
  const refSection = refDocs.sections.find(
93
- s => s.title.toLowerCase() === block.section.toLowerCase(),
114
+ (/** @type {import('../../../core/src/docs-types').ReferenceSection} */ s) =>
115
+ s.title.toLowerCase() === block.section.toLowerCase(),
94
116
  );
95
117
  if (!refSection) {
96
118
  newContent.push({type: 'prose', text: `[token-ref: section "${block.section}" not found in "${block.topic}"]`});
@@ -125,7 +147,11 @@ async function resolveTokenRefs(docsData, topics) {
125
147
  * @param {string} [options.lang]
126
148
  * @param {boolean} [options.zh]
127
149
  * @param {boolean} [options.dense]
128
- * @returns {Promise<{type: string, data: unknown}>}
150
+ * @returns {Promise<
151
+ * import('../../types/docs').DocsListResponse |
152
+ * import('../../types/docs').DocsDetailResponse |
153
+ * import('../../types/docs').DocsDetailSectionResponse
154
+ * >}
129
155
  */
130
156
  export async function docs(topic, section, options = {}) {
131
157
  const {lang = null, zh = false, dense = false} = options;
@@ -133,7 +159,7 @@ export async function docs(topic, section, options = {}) {
133
159
  const topics = discoverTopics();
134
160
 
135
161
  if (!topic) {
136
- /** @type {Array<import('../types/docs').DocsListEntry>} */
162
+ /** @type {Array<import('../../types/docs').DocsListEntry>} */
137
163
  const entries = [];
138
164
  for (const [name, docPath] of Object.entries(topics)) {
139
165
  try {
@@ -24,11 +24,11 @@ import * as fs from 'node:fs';
24
24
  import * as path from 'node:path';
25
25
  import {createRequire} from 'node:module';
26
26
 
27
- import {MIN_NODE_VERSION, isNodeVersionSupported} from '../lib/node-version.mjs';
28
- import {CLI_ROOT, findCoreDir} from '../utils/paths.mjs';
29
- import {detectPackageManager} from '../utils/package-manager.mjs';
30
- import {findConfigPath, Project} from '../lib/project.mjs';
31
- import {semverCompare} from '../utils/semver.mjs';
27
+ import {MIN_NODE_VERSION, isNodeVersionSupported} from '../../lib/node-version.mjs';
28
+ import {CLI_ROOT, findCoreDir} from '../../utils/paths.mjs';
29
+ import {detectPackageManager, getCliInvocation} from '../../utils/package-manager.mjs';
30
+ import {findConfigPath, Project} from '../../lib/project.mjs';
31
+ import {semverCompare} from '../../utils/semver.mjs';
32
32
 
33
33
  const _require = createRequire(import.meta.url);
34
34
 
@@ -49,7 +49,7 @@ const _require = createRequire(import.meta.url);
49
49
  * @typedef {object} DoctorContext
50
50
  * @property {string} cwd - Directory to diagnose.
51
51
  * @property {string} nodeVersion - Running Node version.
52
- * @property {string|null} coreDir - Resolved @astryxdesign/core directory, or null.
52
+ * @property {string|null} coreDir - Resolved core package directory, or null.
53
53
  * @property {string|null} configPath - Resolved astryx.config.mjs path, or null.
54
54
  * @property {string|null} configTheme - theme value read from config, or null.
55
55
  */
@@ -104,6 +104,7 @@ function findNodeModules(startDir) {
104
104
  */
105
105
  function findThemePackages(cwd) {
106
106
  const nm = findNodeModules(cwd);
107
+ /** @type {Array<{name: string, version: string|null}>} */
107
108
  const found = [];
108
109
  if (!nm) return found;
109
110
  const scopeDir = path.join(nm, '@astryxdesign');
@@ -317,7 +318,7 @@ export async function checkConfig(ctx) {
317
318
  id: 'config',
318
319
  label: 'astryx.config.mjs',
319
320
  status: 'fail',
320
- message: `astryx.config.mjs failed to load: ${err.message}`,
321
+ message: `astryx.config.mjs failed to load: ${/** @type {any} */ (err).message}`,
321
322
  fix: 'Fix the syntax/runtime error in astryx.config.mjs so it imports cleanly.',
322
323
  };
323
324
  }
@@ -343,7 +344,7 @@ export function checkAgentDocs(ctx) {
343
344
  label: 'AI agent docs',
344
345
  status: 'info',
345
346
  message: 'No agent docs (CLAUDE.md / AGENTS.md / .cursorrules) found.',
346
- fix: 'Generate agent docs with `astryx init --features agents`.',
347
+ fix: `Generate agent docs with \`${getCliInvocation(ctx.cwd)} init --features agents\`.`,
347
348
  };
348
349
  }
349
350
 
@@ -365,7 +366,7 @@ export function checkAgentDocs(ctx) {
365
366
  label: 'AI agent docs',
366
367
  status: 'warn',
367
368
  message: `Agent docs present (${present.join(', ')}) but no Astryx section markers found.`,
368
- fix: 'Add the Astryx section to your agent docs with `astryx init --features agents`.',
369
+ fix: `Add the Astryx section to your agent docs with \`${getCliInvocation(ctx.cwd)} init --features agents\`.`,
369
370
  };
370
371
  }
371
372
 
@@ -490,7 +491,8 @@ export async function runChecks(options = {}) {
490
491
  let configTheme = null;
491
492
  try {
492
493
  const project = await Project.load(cwd);
493
- configTheme = project.config?.theme ?? null;
494
+ configTheme =
495
+ /** @type {{theme?: string}} */ (project.config ?? {}).theme ?? null;
494
496
  } catch {
495
497
  // Best-effort: a missing/invalid config leaves configTheme null.
496
498
  }
@@ -504,6 +506,7 @@ export async function runChecks(options = {}) {
504
506
  configTheme,
505
507
  };
506
508
 
509
+ /** @type {DoctorCheck[]} */
507
510
  const checks = [];
508
511
  // checkConfig is async; run it in its declared slot (after themes).
509
512
  for (const fn of SYNC_CHECKS) {
@@ -14,7 +14,7 @@
14
14
  import {ERROR_CODES} from '../lib/error-codes.mjs';
15
15
 
16
16
  export class AstryxError extends Error {
17
- /** @type {Array<{name: string, reason: string}> | undefined} */
17
+ /** @type {import('../types/base').Suggestion[] | undefined} */
18
18
  suggestions;
19
19
 
20
20
  /**
@@ -26,7 +26,7 @@ export class AstryxError extends Error {
26
26
 
27
27
  /**
28
28
  * @param {string} message
29
- * @param {Array<{name: string, reason: string}>} [suggestions]
29
+ * @param {import('../types/base').Suggestion[]} [suggestions]
30
30
  * @param {string} [code] - Stable error code. Defaults to ERR_UNKNOWN.
31
31
  */
32
32
  constructor(message, suggestions, code) {
@@ -7,12 +7,12 @@
7
7
  * The CLI command handler is a thin wrapper around this function.
8
8
  */
9
9
 
10
- import {findCoreDir} from '../utils/paths.mjs';
11
- import {discoverHooks, findHookDoc, getAllHookNames} from '../lib/hook-discovery.mjs';
12
- import {loadDocs} from '../lib/component-loader.mjs';
13
- import {levenshteinDistance} from '../lib/string-utils.mjs';
14
- import {AstryxError} from './error.mjs';
15
- import {ERROR_CODES} from '../lib/error-codes.mjs';
10
+ import {findCoreDir} from '../../utils/paths.mjs';
11
+ import {discoverHooks, findHookDoc, getAllHookNames} from '../../lib/hook-discovery.mjs';
12
+ import {loadDocs} from '../../lib/component-loader.mjs';
13
+ import {levenshteinDistance} from '../../lib/string-utils.mjs';
14
+ import {AstryxError} from '../error.mjs';
15
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
16
16
 
17
17
  /**
18
18
  * @param {string} [name]
@@ -72,7 +72,7 @@ export async function hook(name, options = {}) {
72
72
  const docPath = findHookDoc(coreDir, hookName);
73
73
  if (docPath) {
74
74
  try {
75
- const docs = await loadDocs(docPath, {zh, lang});
75
+ const docs = await loadDocs(docPath, /** @type {{zh?: boolean, dense?: boolean, lang?: string}} */ ({zh, lang}));
76
76
  entries.push({
77
77
  name: hookName,
78
78
  description: docs.usage?.description || '',
@@ -94,7 +94,7 @@ export async function hook(name, options = {}) {
94
94
  const docPath = findHookDoc(coreDir, hookName);
95
95
  if (docPath) {
96
96
  try {
97
- entries.push(await loadDocs(docPath, {zh, lang}));
97
+ entries.push(await loadDocs(docPath, /** @type {{zh?: boolean, dense?: boolean, lang?: string}} */ ({zh, lang})));
98
98
  } catch {
99
99
  entries.push({name: hookName});
100
100
  }
@@ -119,7 +119,7 @@ export async function hook(name, options = {}) {
119
119
  const docPath = findHookDoc(coreDir, hookName);
120
120
  if (docPath) {
121
121
  try {
122
- const docs = await loadDocs(docPath, {zh, lang});
122
+ const docs = await loadDocs(docPath, /** @type {{zh?: boolean, dense?: boolean, lang?: string}} */ ({zh, lang}));
123
123
  result[cat].push({
124
124
  name: hookName,
125
125
  description: docs.usage?.description || '',
@@ -145,7 +145,7 @@ export async function hook(name, options = {}) {
145
145
  const docPath = findHookDoc(coreDir, hookName);
146
146
  if (docPath) {
147
147
  try {
148
- result[cat].push(await loadDocs(docPath, {zh, lang}));
148
+ result[cat].push(await loadDocs(docPath, /** @type {{zh?: boolean, dense?: boolean, lang?: string}} */ ({zh, lang})));
149
149
  } catch {
150
150
  result[cat].push({name: hookName});
151
151
  }
@@ -186,7 +186,7 @@ export async function hook(name, options = {}) {
186
186
  );
187
187
  }
188
188
 
189
- const docs = await loadDocs(docPath, {zh, lang});
189
+ const docs = await loadDocs(docPath, /** @type {{zh?: boolean, dense?: boolean, lang?: string}} */ ({zh, lang}));
190
190
 
191
191
  if (params) {
192
192
  return {type: 'hook.detail.params', data: docs.params || []};