@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
@@ -16,6 +16,8 @@ import {
16
16
  removeXdsBlock,
17
17
  discoverAgentDocs,
18
18
  resolveAgentPaths,
19
+ parseBlockVersion,
20
+ inspectAgentDocs,
19
21
  } from './agent-docs.mjs';
20
22
 
21
23
  let tmpDir;
@@ -88,17 +90,24 @@ describe('generateCompressedIndex', () => {
88
90
  expect(result).toMatch(/after any @astryxdesign\/core bump/);
89
91
  });
90
92
 
91
- it('states the runPrefix once in the CLI header', () => {
92
- const result = generateCompressedIndex('1.0.0', {runPrefix: 'yarn'});
93
+ it('states the invocation once in the CLI header (yarn)', () => {
94
+ const result = generateCompressedIndex('1.0.0', {invocation: 'yarn astryx'});
93
95
  expect(result).toContain('yarn astryx <cmd>');
94
96
  expect(result).not.toContain('npx astryx');
95
97
  });
96
98
 
97
- it('uses pnpm exec prefix', () => {
98
- const result = generateCompressedIndex('1.0.0', {runPrefix: 'pnpm exec'});
99
+ it('uses the pnpm exec invocation', () => {
100
+ const result = generateCompressedIndex('1.0.0', {invocation: 'pnpm exec astryx'});
99
101
  expect(result).toContain('pnpm exec astryx <cmd>');
100
102
  expect(result).not.toContain('npx astryx');
101
103
  });
104
+
105
+ it('uses the scoped package for one-off (uninstalled) runs so agents never hit the bare name', () => {
106
+ const result = generateCompressedIndex('1.0.0', {invocation: 'npx @astryxdesign/cli'});
107
+ expect(result).toContain('npx @astryxdesign/cli <cmd>');
108
+ // The header defines the mapping; the bare "run every command as `npx astryx`" footgun must be absent.
109
+ expect(result).not.toContain('npx astryx <cmd>');
110
+ });
102
111
  });
103
112
 
104
113
  describe('detectStylingSystem', () => {
@@ -389,18 +398,37 @@ describe('installAgentDocs', () => {
389
398
  );
390
399
  }
391
400
 
392
- it('creates .claude/CLAUDE.md when no agent docs exist', () => {
401
+ it('creates AGENTS.md when no agent docs exist (tool-agnostic default)', () => {
393
402
  setupCorePackage(tmpDir);
394
403
 
395
404
  const written = installAgentDocs(tmpDir);
396
405
 
397
- expect(written).toEqual(['.claude/CLAUDE.md']);
398
- expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(true);
399
- expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
400
- const content = fs.readFileSync(path.join(tmpDir, '.claude', 'CLAUDE.md'), 'utf-8');
406
+ expect(written).toEqual(['AGENTS.md']);
407
+ expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(true);
408
+ // Must NOT create the Claude-specific file by default.
409
+ expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(false);
410
+ const content = fs.readFileSync(path.join(tmpDir, 'AGENTS.md'), 'utf-8');
411
+ expect(content).toContain('# AGENTS.md');
401
412
  expect(content).toContain('<!-- ASTRYX:START -->');
402
413
  });
403
414
 
415
+ it('defaults to AGENTS.md but writes .claude/CLAUDE.md only when --agent claude is explicit', () => {
416
+ // Default (no agent): tool-agnostic AGENTS.md, never the Claude file.
417
+ setupCorePackage(tmpDir);
418
+ expect(installAgentDocs(tmpDir)).toEqual(['AGENTS.md']);
419
+ expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(false);
420
+
421
+ // Explicit Claude: the Claude-specific file, in a fresh project.
422
+ const claudeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-agent-docs-claude-'));
423
+ setupCorePackage(claudeDir);
424
+ try {
425
+ expect(installAgentDocs(claudeDir, {agent: 'claude'})).toEqual(['.claude/CLAUDE.md']);
426
+ expect(fs.existsSync(path.join(claudeDir, 'AGENTS.md'))).toBe(false);
427
+ } finally {
428
+ fs.rmSync(claudeDir, {recursive: true, force: true});
429
+ }
430
+ });
431
+
404
432
  it('injects into CLAUDE.md at root when it exists', () => {
405
433
  setupCorePackage(tmpDir);
406
434
  fs.writeFileSync(path.join(tmpDir, 'CLAUDE.md'), '# Claude\n\nProject rules.\n');
@@ -517,12 +545,13 @@ describe('installAgentDocs', () => {
517
545
  expect(content).toContain('Other rules.');
518
546
  });
519
547
 
520
- it('onlyReplace: does not create default .claude/CLAUDE.md when nothing exists', () => {
548
+ it('onlyReplace: does not create the default AGENTS.md when nothing exists', () => {
521
549
  setupCorePackage(tmpDir);
522
550
 
523
551
  const written = installAgentDocs(tmpDir, {onlyReplace: true});
524
552
 
525
553
  expect(written).toEqual([]);
554
+ expect(fs.existsSync(path.join(tmpDir, 'AGENTS.md'))).toBe(false);
526
555
  expect(fs.existsSync(path.join(tmpDir, '.claude', 'CLAUDE.md'))).toBe(false);
527
556
  });
528
557
  });
@@ -602,3 +631,87 @@ describe('resolveAgentPaths', () => {
602
631
  expect(result).toEqual({inject: [], create: ['.claude/CLAUDE.md']});
603
632
  });
604
633
  });
634
+
635
+ describe('parseBlockVersion', () => {
636
+ it('reads the version from the header of a generated block', () => {
637
+ expect(parseBlockVersion(generateCompressedIndex('1.2.3'))).toBe('1.2.3');
638
+ });
639
+
640
+ it('reads prerelease versions', () => {
641
+ expect(parseBlockVersion('Astryx v1.2.3-beta.4 · 10 components')).toBe(
642
+ '1.2.3-beta.4',
643
+ );
644
+ });
645
+
646
+ it('returns null when no versioned header is present', () => {
647
+ expect(parseBlockVersion('<!-- XDS:START -->\nold\n<!-- XDS:END -->')).toBeNull();
648
+ expect(parseBlockVersion('')).toBeNull();
649
+ expect(parseBlockVersion(undefined)).toBeNull();
650
+ });
651
+ });
652
+
653
+ describe('inspectAgentDocs', () => {
654
+ function writeBlock(rel, version) {
655
+ const filePath = path.join(tmpDir, rel);
656
+ fs.mkdirSync(path.dirname(filePath), {recursive: true});
657
+ fs.writeFileSync(filePath, `# Doc\n\n${generateCompressedIndex(version)}\n`);
658
+ }
659
+
660
+ it('reports missing when no agent docs exist at all', () => {
661
+ const res = inspectAgentDocs(tmpDir, '1.0.0');
662
+ expect(res.status).toBe('missing');
663
+ expect(res.files).toEqual([]);
664
+ expect(res.staleFiles).toEqual([]);
665
+ });
666
+
667
+ it('reports missing when agent files exist but carry no Astryx marker', () => {
668
+ fs.writeFileSync(path.join(tmpDir, 'AGENTS.md'), '# Agents\n\nHand-written notes.\n');
669
+ expect(inspectAgentDocs(tmpDir, '1.0.0').status).toBe('missing');
670
+ });
671
+
672
+ it('reports current when the only block matches the installed version', () => {
673
+ writeBlock('AGENTS.md', '1.0.0');
674
+ const res = inspectAgentDocs(tmpDir, '1.0.0');
675
+ expect(res.status).toBe('current');
676
+ expect(res.staleFiles).toEqual([]);
677
+ expect(res.blockVersions).toEqual([]);
678
+ });
679
+
680
+ it('reports stale (with the old version) when the block is behind', () => {
681
+ writeBlock('AGENTS.md', '1.0.0');
682
+ const res = inspectAgentDocs(tmpDir, '2.0.0');
683
+ expect(res.status).toBe('stale');
684
+ expect(res.staleFiles).toEqual(['AGENTS.md']);
685
+ expect(res.blockVersions).toEqual(['1.0.0']);
686
+ expect(res.installedVersion).toBe('2.0.0');
687
+ });
688
+
689
+ it('treats a legacy XDS block as stale even with no parseable version', () => {
690
+ fs.writeFileSync(
691
+ path.join(tmpDir, 'CLAUDE.md'),
692
+ '# Claude\n\n<!-- XDS:START -->\nlegacy index\n<!-- XDS:END -->\n',
693
+ );
694
+ const res = inspectAgentDocs(tmpDir, '1.0.0');
695
+ expect(res.status).toBe('stale');
696
+ expect(res.files[0].legacy).toBe(true);
697
+ expect(res.blockVersions).toEqual([]);
698
+ });
699
+
700
+ it('is stale if ANY marked file is behind (mixed current + stale)', () => {
701
+ writeBlock('AGENTS.md', '2.0.0');
702
+ writeBlock('CLAUDE.md', '1.0.0');
703
+ const res = inspectAgentDocs(tmpDir, '2.0.0');
704
+ expect(res.status).toBe('stale');
705
+ expect(res.staleFiles).toEqual(['CLAUDE.md']);
706
+ });
707
+
708
+ it('defaults the installed version to the core package when omitted', () => {
709
+ const coreDir = path.join(tmpDir, 'node_modules', '@astryxdesign', 'core');
710
+ fs.mkdirSync(coreDir, {recursive: true});
711
+ fs.writeFileSync(path.join(coreDir, 'package.json'), JSON.stringify({version: '3.0.0'}));
712
+ writeBlock('AGENTS.md', '3.0.0');
713
+ const res = inspectAgentDocs(tmpDir);
714
+ expect(res.installedVersion).toBe('3.0.0');
715
+ expect(res.status).toBe('current');
716
+ });
717
+ });
@@ -55,8 +55,8 @@ import {ERROR_CODES} from './error-codes.mjs';
55
55
 
56
56
  /**
57
57
  * Suggestion object — matches the shape used by API errors and the JSON
58
- * envelope's `suggestions` field.
59
- * @typedef {{name: string, reason?: string}} Suggestion
58
+ * envelope's `suggestions` field. Canonical definition lives in types/base.
59
+ * @typedef {import('../types/base').Suggestion} Suggestion
60
60
  */
61
61
 
62
62
  /**
@@ -77,12 +77,15 @@ const HIDDEN_RE = /(?:^|\n) {0,4}hidden:\s*true/;
77
77
  /**
78
78
  * Read the `group`, `hiddenComponents`, and `hidden` fields from a
79
79
  * component's .doc.mjs file (synchronous).
80
+ * @param {string} docPath
81
+ * @returns {{group: string | null, hiddenComponents: Set<string>, hidden: boolean}}
80
82
  */
81
83
  function readDocMeta(docPath) {
82
84
  try {
83
85
  const content = fs.readFileSync(docPath, 'utf-8');
84
86
  const groupMatch = GROUP_RE.exec(content);
85
87
  const hiddenCompsMatch = HIDDEN_COMPONENTS_RE.exec(content);
88
+ /** @type {Set<string>} */
86
89
  const hiddenSet = new Set();
87
90
  if (hiddenCompsMatch) {
88
91
  for (const m of hiddenCompsMatch[1].matchAll(/['"]([^'"]+)['"]/g)) {
@@ -109,13 +112,20 @@ function readDocMeta(docPath) {
109
112
  *
110
113
  * Keys are sorted alphabetically (groups and ungrouped components interleaved).
111
114
  * Components within each group are also sorted alphabetically.
115
+ * @param {string} coreDir
116
+ * @returns {Record<string, string[]>}
112
117
  */
113
118
  export function discoverComponents(coreDir) {
114
119
  const srcDir = path.join(coreDir, 'src');
115
120
  /** @type {Map<string, string|null>} componentName → group */
116
121
  const componentGroups = new Map();
117
122
 
123
+ /**
124
+ * @param {string} dirPath
125
+ * @returns {string[]}
126
+ */
118
127
  function collectXDSFiles(dirPath) {
128
+ /** @type {string[]} */
119
129
  const results = [];
120
130
  if (!fs.existsSync(dirPath)) return results;
121
131
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
@@ -185,7 +195,7 @@ export function discoverComponents(coreDir) {
185
195
  for (const [name, group] of componentGroups) {
186
196
  if (group) {
187
197
  if (!groups.has(group)) groups.set(group, []);
188
- groups.get(group).push(name);
198
+ groups.get(group)?.push(name);
189
199
  } else {
190
200
  ungrouped.push(name);
191
201
  }
@@ -220,6 +230,9 @@ export function discoverComponents(coreDir) {
220
230
  * Find the .doc.mjs file for a component.
221
231
  * For sub-components (e.g. StackItem), returns the parent's .doc.mjs
222
232
  * if the sub-component is documented there.
233
+ * @param {string} coreDir
234
+ * @param {string} name
235
+ * @returns {string | null}
223
236
  */
224
237
  export function findComponentReadme(coreDir, name) {
225
238
  const srcDir = path.join(coreDir, 'src');
@@ -278,6 +291,9 @@ export function findComponentReadme(coreDir, name) {
278
291
  * `useResizable.ts`), so `.ts` candidates are searched alongside `.tsx`. Without
279
292
  * this, deriving the import path for a `.ts`-authored function falls back to the
280
293
  * bare `@astryxdesign/core` root instead of its tree-shakeable subpath.
294
+ * @param {string} coreDir
295
+ * @param {string} name
296
+ * @returns {string | null}
281
297
  */
282
298
  export function findComponentSource(coreDir, name) {
283
299
  const srcDir = path.join(coreDir, 'src');
@@ -292,6 +308,10 @@ export function findComponentSource(coreDir, name) {
292
308
  `${name}.ts`,
293
309
  ];
294
310
 
311
+ /**
312
+ * @param {string} dirPath
313
+ * @returns {string | null}
314
+ */
295
315
  function searchDir(dirPath) {
296
316
  if (!fs.existsSync(dirPath)) return null;
297
317
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
@@ -337,6 +357,9 @@ export function findComponentSource(coreDir, name) {
337
357
  /**
338
358
  * Compute the Levenshtein (edit) distance between two strings.
339
359
  * Used for fuzzy-matching component names. Dependency-free.
360
+ * @param {string} coreDir
361
+ * @param {string} componentName
362
+ * @returns {string}
340
363
  */
341
364
  export function resolveImportPath(coreDir, componentName) {
342
365
  const srcDir = path.join(coreDir, 'src');
@@ -376,11 +399,15 @@ export function resolveImportPath(coreDir, componentName) {
376
399
  * Scans for *.doc.mjs files and returns their names as a flat array.
377
400
  *
378
401
  * @deprecated Use discoverExternalComponentsGrouped for group-aware discovery.
402
+ * @param {string} docsDir
403
+ * @returns {string[]}
379
404
  */
380
405
  export function discoverExternalComponents(docsDir) {
381
406
  if (!fs.existsSync(docsDir)) return [];
407
+ /** @type {string[]} */
382
408
  const components = [];
383
409
 
410
+ /** @param {string} dirPath */
384
411
  function scanDir(dirPath) {
385
412
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
386
413
  for (const entry of entries) {
@@ -405,6 +432,8 @@ export function discoverExternalComponents(docsDir) {
405
432
  * Returns a Record<string, string[]> matching the shape of discoverComponents():
406
433
  * - Grouped components: `{ 'App Chrome': ['AppShell', 'SideNav', 'TopNav'] }`
407
434
  * - Ungrouped components: `{ 'Diff': ['Diff'] }`
435
+ * @param {string} docsDir
436
+ * @returns {Record<string, string[]>}
408
437
  */
409
438
  export function discoverExternalComponentsGrouped(docsDir) {
410
439
  if (!fs.existsSync(docsDir)) return {};
@@ -412,6 +441,7 @@ export function discoverExternalComponentsGrouped(docsDir) {
412
441
  /** @type {Map<string, string|null>} componentName → group */
413
442
  const componentGroups = new Map();
414
443
 
444
+ /** @param {string} dirPath */
415
445
  function scanDir(dirPath) {
416
446
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
417
447
  for (const entry of entries) {
@@ -440,7 +470,7 @@ export function discoverExternalComponentsGrouped(docsDir) {
440
470
  for (const [name, group] of componentGroups) {
441
471
  if (group) {
442
472
  if (!groups.has(group)) groups.set(group, []);
443
- groups.get(group).push(name);
473
+ groups.get(group)?.push(name);
444
474
  } else {
445
475
  ungrouped.push(name);
446
476
  }
@@ -472,11 +502,18 @@ export function discoverExternalComponentsGrouped(docsDir) {
472
502
  /**
473
503
  * Find a component's doc file in an external package's docs directory.
474
504
  * Returns the path to {Name}.doc.mjs or null.
505
+ * @param {string} docsDir
506
+ * @param {string} name
507
+ * @returns {string | null}
475
508
  */
476
509
  export function findExternalComponentDoc(docsDir, name) {
477
510
  if (!fs.existsSync(docsDir)) return null;
478
511
  const target = `${name}.doc.mjs`;
479
512
 
513
+ /**
514
+ * @param {string} dirPath
515
+ * @returns {string | null}
516
+ */
480
517
  function scanDir(dirPath) {
481
518
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
482
519
  for (const entry of entries) {
@@ -538,6 +575,7 @@ export function discoverIntegrationComponents(integration) {
538
575
  /** @type {Map<string, {name: string, package: string, docPath: string, sourcePath: string|null, issuesUrl: string|undefined, group: string|null}>} */
539
576
  const byName = new Map();
540
577
 
578
+ /** @param {string} dirPath */
541
579
  function scanDir(dirPath) {
542
580
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
543
581
  for (const entry of entries) {
@@ -582,6 +620,10 @@ export function findIntegrationComponentDoc(integration, name) {
582
620
  const componentsDir = integration?.components;
583
621
  if (!componentsDir || !fs.existsSync(componentsDir)) return null;
584
622
 
623
+ /**
624
+ * @param {string} dirPath
625
+ * @returns {string | null}
626
+ */
585
627
  function scanDir(dirPath) {
586
628
  const entries = fs.readdirSync(dirPath, {withFileTypes: true});
587
629
  // Exact same-stem match (precedence order) first in this dir.