@astryxdesign/cli 0.1.8-canary.0c4d8d7 → 0.1.8-canary.0db5dfd

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 (303) hide show
  1. package/{src/api → api/blog}/blog.mjs +42 -6
  2. package/{src/api → api/blog}/blog.test.mjs +2 -2
  3. package/api/build/build.mjs +92 -0
  4. package/api/build/build.test.mjs +92 -0
  5. package/{src/api → api/component}/component.mjs +49 -26
  6. package/{src/api → api/discover}/discover.mjs +55 -18
  7. package/{src/api → api/docs}/docs.mjs +47 -21
  8. package/{src/api → api/doctor}/doctor.mjs +11 -8
  9. package/{src/api → api/hook}/hook.mjs +11 -11
  10. package/{src/api → api}/index.mjs +16 -9
  11. package/{src/api → api/integration}/validate-integration.mjs +48 -15
  12. package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
  13. package/{src/api → api/layout}/layout.mjs +66 -17
  14. package/{src/api → api/layout}/layout.test.mjs +1 -1
  15. package/{src/api → api/search}/search.mjs +71 -12
  16. package/api/swizzle/swizzle.mjs +283 -0
  17. package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
  18. package/{src/api → api/template}/template-integration.test.mjs +2 -2
  19. package/{src/api → api/template}/template-suffix.test.mjs +3 -3
  20. package/{src/api → api/template}/template.mjs +96 -19
  21. package/{src/api → api/theme}/theme-add.mjs +35 -7
  22. package/{src → authoring}/codemod.mjs +6 -6
  23. package/{src → authoring}/config.test.mjs +1 -1
  24. package/{src → authoring}/doc.mjs +1 -1
  25. package/{src → authoring}/doc.test.mjs +1 -1
  26. package/{src → authoring}/template.mjs +1 -1
  27. package/bin/astryx.mjs +12 -10
  28. package/{src → cli}/commands/blog.mjs +48 -7
  29. package/{src → cli}/commands/build-theme.mjs +125 -46
  30. package/{src → cli}/commands/build.mjs +33 -57
  31. package/{src → cli}/commands/component/index.mjs +49 -22
  32. package/{src → cli}/commands/component-ownership.test.mjs +3 -3
  33. package/{src → cli}/commands/component-package.test.mjs +1 -1
  34. package/{src → cli}/commands/component-resolution.test.mjs +2 -2
  35. package/{src → cli}/commands/discover.mjs +17 -8
  36. package/{src → cli}/commands/docs.mjs +39 -7
  37. package/{src → cli}/commands/docs.test.mjs +1 -1
  38. package/{src → cli}/commands/doctor.mjs +3 -3
  39. package/{src → cli}/commands/doctor.test.mjs +2 -2
  40. package/{src → cli}/commands/ensure-core-built.mjs +3 -2
  41. package/{src → cli}/commands/external-showcase.test.mjs +1 -1
  42. package/{src → cli}/commands/hook/index.mjs +37 -14
  43. package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
  44. package/{src → cli}/commands/init.mjs +20 -9
  45. package/{src → cli}/commands/layout.mjs +58 -18
  46. package/{src → cli}/commands/search.mjs +19 -12
  47. package/{src → cli}/commands/search.test.mjs +1 -1
  48. package/{src → cli}/commands/setup-nudge.test.mjs +1 -1
  49. package/cli/commands/swizzle.mjs +103 -0
  50. package/{src → cli}/commands/template.mjs +73 -22
  51. package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
  52. package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
  53. package/{src → cli}/commands/upgrade.mjs +160 -52
  54. package/{src → cli}/commands/upgrade.test.mjs +1 -1
  55. package/{src → cli}/commands/validate-integration.mjs +17 -37
  56. package/{src → cli}/index.mjs +17 -15
  57. package/{src/codemods → codemods}/ensure-jscodeshift.mjs +1 -1
  58. package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
  59. package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
  60. package/{src/codemods → codemods}/integration-runner.mjs +8 -3
  61. package/{src/codemods → codemods}/registry.mjs +3 -1
  62. package/{src/codemods → codemods}/run-codemod.mjs +17 -10
  63. package/{src/codemods → codemods}/runner.mjs +22 -12
  64. package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
  65. package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
  66. package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
  67. package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
  68. package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
  69. package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
  70. package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
  71. package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
  72. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
  73. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
  74. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
  75. package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
  76. package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
  77. package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
  78. package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
  79. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
  80. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
  81. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
  82. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
  83. package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
  84. package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
  85. package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
  86. package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
  87. package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
  88. package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
  89. package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
  90. package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
  91. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
  92. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
  93. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
  94. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
  95. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
  96. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
  97. package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
  98. package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
  99. package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
  100. package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +19 -14
  101. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
  102. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
  103. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +16 -11
  104. package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
  105. package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
  106. package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
  107. package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
  108. package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
  109. package/{src/codemods → codemods}/transforms/v0.1.8/rename-avatar-size-scale.mjs +15 -10
  110. package/docs/internationalization.doc.mjs +92 -46
  111. package/{src/commands → lib/agent-docs}/agent-docs.mjs +30 -11
  112. package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
  113. package/{src/lib → lib}/component-discovery.mjs +44 -2
  114. package/{src/lib → lib}/component-format.mjs +65 -24
  115. package/{src/lib → lib}/component-loader.mjs +27 -13
  116. package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
  117. package/{src/lib → lib}/error-codes.test.mjs +1 -1
  118. package/{src/lib → lib}/hook-discovery.mjs +14 -1
  119. package/{src/lib → lib}/hook-format.mjs +29 -5
  120. package/{src/lib → lib}/integration-warnings.mjs +2 -2
  121. package/{src/lib → lib}/integrations.mjs +20 -0
  122. package/{src/lib → lib}/integrations.test.mjs +1 -1
  123. package/{src/lib → lib}/json-contract.test.mjs +1 -1
  124. package/{src/lib → lib}/json-shim.mjs +10 -5
  125. package/{src/lib → lib}/json-shim.test.mjs +1 -1
  126. package/{src/lib → lib}/levenshtein.mjs +6 -0
  127. package/{src/lib → lib}/manifest.mjs +7 -5
  128. package/{src/lib → lib}/manifest.test.mjs +2 -2
  129. package/{src/lib → lib}/module-loader.mjs +1 -0
  130. package/{src/lib → lib}/package-scanner.mjs +47 -0
  131. package/{src/lib → lib}/project.mjs +48 -18
  132. package/{src/lib → lib}/project.test.mjs +1 -1
  133. package/{src/lib → lib}/resolve-theme.mjs +5 -0
  134. package/{src/lib → lib}/string-utils.mjs +15 -0
  135. package/{src/lib → lib}/term-log.mjs +12 -3
  136. package/{src/lib → lib}/xle/browser.mjs +18 -8
  137. package/{src/lib → lib}/xle/expand.mjs +155 -22
  138. package/{src/lib → lib}/xle/parse.mjs +119 -13
  139. package/{src/lib → lib}/xle/print.mjs +54 -14
  140. package/{src/lib → lib}/xle/registry-core.mjs +28 -3
  141. package/{src/lib → lib}/xle/registry.mjs +9 -4
  142. package/{src/lib → lib}/xle/splice.mjs +13 -2
  143. package/{src/lib → lib}/xle/validate.mjs +95 -14
  144. package/lib/xle/xle-ast.d.ts +214 -0
  145. package/package.json +33 -26
  146. package/scripts/postinstall.mjs +4 -4
  147. package/templates/blocks/components/Avatar/AvatarShowcase.tsx +1 -1
  148. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
  149. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
  150. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
  151. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
  152. package/{src/types → types}/api.contract.assert.ts +17 -8
  153. package/{src/types → types}/api.d.ts +106 -0
  154. package/{src/types → types}/base.d.ts +17 -2
  155. package/types/build.d.ts +53 -0
  156. package/types/codemod.d.ts +166 -0
  157. package/{src/types → types}/component.d.ts +1 -1
  158. package/{src/types → types}/discover.d.ts +1 -1
  159. package/{src/types → types}/docs.d.ts +1 -4
  160. package/{src/types → types}/hook.d.ts +1 -1
  161. package/types/jscodeshift.d.ts +19 -0
  162. package/types/layout.d.ts +74 -0
  163. package/types/theme.d.ts +53 -0
  164. package/{src/types → types}/upgrade.d.ts +8 -1
  165. package/{src/utils → utils}/paths.mjs +4 -1
  166. package/src/commands/swizzle.mjs +0 -417
  167. package/src/types/build.d.ts +0 -23
  168. package/src/types/codemod.d.ts +0 -81
  169. package/src/types/theme.d.ts +0 -23
  170. /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
  171. /package/{src/api → api}/error.mjs +0 -0
  172. /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
  173. /package/{src/api → api/template}/template.test.mjs +0 -0
  174. /package/{src → authoring}/codemod.test.mjs +0 -0
  175. /package/{src → authoring}/config.mjs +0 -0
  176. /package/{src → authoring}/integration.mjs +0 -0
  177. /package/{src → authoring}/template.test.mjs +0 -0
  178. /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
  179. /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
  180. /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
  181. /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
  182. /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
  183. /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
  184. /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
  185. /package/{src → cli}/commands/cli-postinstall.test.mjs +0 -0
  186. /package/{src → cli}/commands/component.test.mjs +0 -0
  187. /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
  188. /package/{src → cli}/commands/init.next-steps.test.mjs +0 -0
  189. /package/{src → cli}/commands/interactive-guard.test.mjs +0 -0
  190. /package/{src → cli}/commands/json-contract.test.mjs +0 -0
  191. /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
  192. /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
  193. /package/{src → cli}/commands/template.test.mjs +0 -0
  194. /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
  195. /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
  196. /package/{src → cli}/update-hint-commands.test.mjs +0 -0
  197. /package/{src/codemods → codemods}/__tests__/registry.test.mjs +0 -0
  198. /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
  199. /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
  200. /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
  201. /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
  202. /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
  203. /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
  204. /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
  205. /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
  206. /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
  207. /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
  208. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
  209. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
  210. /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
  211. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
  212. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
  213. /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
  214. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
  215. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
  216. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
  217. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
  218. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
  219. /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
  220. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
  221. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
  222. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
  223. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
  224. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
  225. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
  226. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
  227. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
  228. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
  229. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
  230. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
  231. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
  232. /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
  233. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
  234. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
  235. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
  236. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
  237. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
  238. /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
  239. /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
  240. /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
  241. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
  242. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
  243. /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
  244. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
  245. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
  246. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
  247. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +0 -0
  248. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
  249. /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
  250. /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
  251. /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
  252. /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
  253. /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
  254. /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
  255. /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
  256. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
  257. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
  258. /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
  259. /package/{src/codemods → codemods}/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +0 -0
  260. /package/{src/codemods → codemods}/transforms/v0.1.8/index.mjs +0 -0
  261. /package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +0 -0
  262. /package/{src/lib → lib}/cli-error.mjs +0 -0
  263. /package/{src/lib → lib}/cli-error.test.mjs +0 -0
  264. /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
  265. /package/{src/lib → lib}/component-format.test.mjs +0 -0
  266. /package/{src/lib → lib}/component-loader.test.mjs +0 -0
  267. /package/{src/lib → lib}/config-cache.mjs +0 -0
  268. /package/{src/lib → lib}/config-cache.test.mjs +0 -0
  269. /package/{src/lib → lib}/config-schema.mjs +0 -0
  270. /package/{src/lib → lib}/error-codes.mjs +0 -0
  271. /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
  272. /package/{src/lib → lib}/json.mjs +0 -0
  273. /package/{src/lib → lib}/module-loader.test.mjs +0 -0
  274. /package/{src/lib → lib}/node-version.mjs +0 -0
  275. /package/{src/lib → lib}/node-version.test.mjs +0 -0
  276. /package/{src/lib → lib}/parse.mjs +0 -0
  277. /package/{src/lib → lib}/site.mjs +0 -0
  278. /package/{src/lib → lib}/xle/browser.d.ts +0 -0
  279. /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
  280. /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
  281. /package/{src/schemas → schemas}/template-schema.mjs +0 -0
  282. /package/{src/types → types}/config.d.ts +0 -0
  283. /package/{src/types → types}/doc.d.ts +0 -0
  284. /package/{src/types → types}/doctor.d.ts +0 -0
  285. /package/{src/types → types}/error-codes.d.ts +0 -0
  286. /package/{src/types → types}/index.d.ts +0 -0
  287. /package/{src/types → types}/integration.d.ts +0 -0
  288. /package/{src/types → types}/manifest.d.ts +0 -0
  289. /package/{src/types → types}/search.d.ts +0 -0
  290. /package/{src/types → types}/swizzle.d.ts +0 -0
  291. /package/{src/types → types}/template-api.d.ts +0 -0
  292. /package/{src/types → types}/template.d.ts +0 -0
  293. /package/{src/types → types}/validate-integration.d.ts +0 -0
  294. /package/{src/utils → utils}/github.mjs +0 -0
  295. /package/{src/utils → utils}/package-manager.mjs +0 -0
  296. /package/{src/utils → utils}/package-manager.test.mjs +0 -0
  297. /package/{src/utils → utils}/path-safety.mjs +0 -0
  298. /package/{src/utils → utils}/path-safety.test.mjs +0 -0
  299. /package/{src/utils → utils}/paths.test.mjs +0 -0
  300. /package/{src/utils → utils}/semver.mjs +0 -0
  301. /package/{src/utils → utils}/semver.test.mjs +0 -0
  302. /package/{src/utils → utils}/update-check.mjs +0 -0
  303. /package/{src/utils → utils}/update-check.test.mjs +0 -0
@@ -80,7 +80,7 @@ const UNIQUE = new Set(['tiny', 'xsmall']);
80
80
  * Unwraps `'small' as const`. In non-precise contexts, ambiguous names are
81
81
  * skipped. Returns true when a rename occurred.
82
82
  */
83
- function renameValue(node, {precise = false} = {}) {
83
+ function renameValue(/** @type {any} */ node, {precise = false} = {}) {
84
84
  if (!node) return false;
85
85
  const target = node.type === 'TSAsExpression' ? node.expression : node;
86
86
  const isString =
@@ -95,7 +95,7 @@ function renameValue(node, {precise = false} = {}) {
95
95
  }
96
96
 
97
97
  /** Extract a plain string value from a literal-ish node, or null. */
98
- function literalString(node) {
98
+ function literalString(/** @type {any} */ node) {
99
99
  const target = node?.type === 'TSAsExpression' ? node.expression : node;
100
100
  if (
101
101
  target &&
@@ -107,6 +107,11 @@ function literalString(node) {
107
107
  return null;
108
108
  }
109
109
 
110
+ /**
111
+ * @param {import('../../../types/codemod').AstryxCodemodFile} file
112
+ * @param {import('../../../types/codemod').CodemodTransformApi} api
113
+ * @returns {string | null | undefined}
114
+ */
110
115
  export default function transformer(file, api) {
111
116
  const j = api.jscodeshift;
112
117
  const root = j(file.source);
@@ -114,7 +119,7 @@ export default function transformer(file, api) {
114
119
 
115
120
  // Track alias-aware local names for the target components.
116
121
  const targetLocals = new Set();
117
- root.find(j.ImportDeclaration).forEach((path) => {
122
+ root.find(j.ImportDeclaration).forEach((/** @type {any} */ path) => {
118
123
  if (!IMPORT_SOURCES.has(path.node.source.value)) return;
119
124
  for (const spec of path.node.specifiers ?? []) {
120
125
  if (
@@ -128,14 +133,14 @@ export default function transformer(file, api) {
128
133
 
129
134
  if (targetLocals.size === 0) return undefined;
130
135
 
131
- function renameArrayElements(node) {
136
+ function renameArrayElements(/** @type {any} */ node) {
132
137
  let arr = node;
133
138
  if (arr.type === 'TSAsExpression') arr = arr.expression;
134
139
  if (arr.type !== 'ArrayExpression') return;
135
140
  // If the array contains a name unique to Avatar's scale (tiny/xsmall), the
136
141
  // whole collection is unambiguously the Avatar size enum, so it is safe to
137
142
  // rename the ambiguous members too. Otherwise stay conservative.
138
- const precise = arr.elements.some((el) => UNIQUE.has(literalString(el)));
143
+ const precise = arr.elements.some((/** @type {any} */ el) => UNIQUE.has(literalString(el)));
139
144
  for (const el of arr.elements) {
140
145
  if (renameValue(el, {precise})) hasChanges = true;
141
146
  }
@@ -143,7 +148,7 @@ export default function transformer(file, api) {
143
148
 
144
149
  // 1. `size` JSX attributes on target components — PRECISE (component known),
145
150
  // so all five names, including the ambiguous ones, are renamed here.
146
- root.find(j.JSXOpeningElement).forEach((path) => {
151
+ root.find(j.JSXOpeningElement).forEach((/** @type {any} */ path) => {
147
152
  const name = path.node.name;
148
153
  const componentName = name.type === 'JSXIdentifier' ? name.name : null;
149
154
  if (!componentName || !targetLocals.has(componentName)) return;
@@ -182,7 +187,7 @@ export default function transformer(file, api) {
182
187
  // arrays — NON-PRECISE (the component isn't known here), so only the
183
188
  // unique names tiny/xsmall are renamed.
184
189
  const PropertyType = j.ObjectProperty ?? j.Property;
185
- root.find(PropertyType).forEach((path) => {
190
+ root.find(PropertyType).forEach((/** @type {any} */ path) => {
186
191
  const key = path.node.key;
187
192
  const keyName =
188
193
  key.type === 'Identifier'
@@ -204,7 +209,7 @@ export default function transformer(file, api) {
204
209
  // size: { control: 'select', options: ['tiny', ...] }
205
210
  if (value.type === 'ObjectExpression') {
206
211
  const optionsProp = value.properties.find(
207
- (p) => p.key && (p.key.name === 'options' || p.key.value === 'options'),
212
+ (/** @type {any} */ p) => p.key && (p.key.name === 'options' || p.key.value === 'options'),
208
213
  );
209
214
  if (optionsProp) renameArrayElements(optionsProp.value);
210
215
  }
@@ -216,7 +221,7 @@ export default function transformer(file, api) {
216
221
  // are renamed. This avoids corrupting unrelated unions that happen to use
217
222
  // common words like 'medium' (e.g. a priority or breakpoint type) in a
218
223
  // file that also imports Avatar.
219
- root.find(j.TSLiteralType).forEach((path) => {
224
+ root.find(j.TSLiteralType).forEach((/** @type {any} */ path) => {
220
225
  if (renameValue(path.node.literal)) hasChanges = true;
221
226
  });
222
227
 
@@ -225,7 +230,7 @@ export default function transformer(file, api) {
225
230
  // e.g. `(['tiny', 'xsmall', 'small', 'medium', 'large'] as const).map(...)`
226
231
  // used to render every size. The unique name proves the whole array is the
227
232
  // Avatar enum, so its ambiguous members can be renamed safely.
228
- root.find(j.ArrayExpression).forEach((path) => {
233
+ root.find(j.ArrayExpression).forEach((/** @type {any} */ path) => {
229
234
  renameArrayElements(path.node);
230
235
  });
231
236
 
@@ -7,7 +7,7 @@ export const docs = {
7
7
  title: 'Internationalization',
8
8
  category: 'guide',
9
9
  description:
10
- 'Localize astryx component strings, provide translation catalogs, override default text, coexist with your own i18n library, swap languages at runtime, and test translations with the pseudo locale.',
10
+ 'Set the active locale for astryx components, load locale catalogs, coexist with your own i18n library, swap languages at runtime, and test translations with the pseudo locale.',
11
11
 
12
12
  sections: [
13
13
  {
@@ -16,13 +16,13 @@ export const docs = {
16
16
  content: [
17
17
  {
18
18
  type: 'prose',
19
- text: 'Internationalization ships with `@astryxdesign/core`. There is nothing to install. Wrap your app in `<InternationalizationProvider>` and set a `locale`, and astryx components pick up localized strings automatically.',
19
+ text: 'Internationalization ships with `@astryxdesign/core`. There is nothing to install. Wrap your app in `<InternationalizationProvider>` and set the active `locale`; astryx components pick up localized strings from that provider.',
20
20
  },
21
21
  {
22
22
  type: 'code',
23
23
  lang: 'tsx',
24
24
  label: 'Wrap your app',
25
- code: `import {InternationalizationProvider} from '@astryxdesign/core';
25
+ code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
26
26
 
27
27
  function App() {
28
28
  return (
@@ -32,53 +32,56 @@ function App() {
32
32
  );
33
33
  }`,
34
34
  },
35
+ {
36
+ type: 'prose',
37
+ text: 'The provider always has the built-in English catalog. Pass additional catalogs through `messages` when you enable another locale.',
38
+ },
35
39
  {
36
40
  type: 'code',
37
41
  lang: 'tsx',
38
- label: 'Read strings inside a component',
39
- code: `import {useTranslator} from '@astryxdesign/core';
42
+ label: 'Load an astryx locale catalog',
43
+ code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
44
+ import fr from '@astryxdesign/core/locales/fr.json';
40
45
 
41
- function SaveButton() {
42
- const t = useTranslator();
43
- return <button>{t('@myapp.actions.save')}</button>;
44
- }`,
46
+ <InternationalizationProvider locale="fr" messages={{fr}}>
47
+ <App />
48
+ </InternationalizationProvider>;`,
45
49
  },
46
50
  {
47
51
  type: 'prose',
48
- text: 'The hook is available to consumer components too, but using it is entirely optional: many teams keep their app strings on their existing i18n library (react-intl, i18next, next-intl, LinguiJS) and only use `useTranslator` when reading astryx keys. If you do route your own strings through it, we recommend namespacing them (`@myapp.*` or your npm scope) to keep them separated from `@astryx.*`, but this is a convention, not a requirement; the resolver treats every key as an opaque string.',
52
+ text: 'Astryx ships English today, with first-party translations for other locales on the roadmap. Until a locale is available from `@astryxdesign/core/locales/*`, apps can pass a local catalog with the same shape. See `@astryxdesign/core/locales/en.json` for the current key inventory. Missing keys fall back through the locale chain to English (for example, `pt-BR` walks to `pt`, then to shipped `en`).',
49
53
  },
50
54
  {
51
55
  type: 'prose',
52
- text: "Astryx ships translations only for English today. First-party translations for other locales are on the roadmap; track https://github.com/facebook/astryx/issues/3641. In the meantime, if you want astryx UI translated into another locale, you can ship your own catalog through the `messages` prop (covered in the next section). If you're using `useTranslator` for your own strings, you'll want to ship your own catalog either way, since astryx only carries the fallback for `@astryx.*` keys, not the ones you author.",
56
+ text: 'Locale catalogs only affect astryx strings. Your app can continue using its own i18n system for product copy.',
53
57
  },
54
58
  ],
55
59
  },
56
60
  {
57
- title: 'Providing locale catalogs',
61
+ title: 'Runtime language swap',
58
62
  category: 'guide',
59
63
  content: [
60
64
  {
61
65
  type: 'prose',
62
- text: 'Astryx bundles only the English catalog today. To render in any other locale, provide a translation catalog through the `messages` prop and set `locale` accordingly. This matches how MUI, Ant Design, and AG Grid work: the consumer app supplies the catalogs it actually needs so unused translations stay out of the bundle.',
66
+ text: 'Re-render `<InternationalizationProvider>` with a new `locale` prop and every astryx string updates live. No reload, no separate API call.',
63
67
  },
64
68
  {
65
69
  type: 'code',
66
70
  lang: 'tsx',
67
- label: 'Add French',
68
- code: `import {InternationalizationProvider} from '@astryxdesign/core';
69
- import fr from './locales/astryx/fr.json';
71
+ label: 'Toggle between locales',
72
+ code: `const [locale, setLocale] = useState<'en' | 'fr'>('en');
70
73
 
71
- <InternationalizationProvider locale="fr" messages={{fr}}>
74
+ <InternationalizationProvider locale={locale} messages={{fr}}>
75
+ <Button
76
+ label={locale === 'en' ? 'Français' : 'English'}
77
+ onClick={() => setLocale(l => (l === 'en' ? 'fr' : 'en'))}
78
+ />
72
79
  <App />
73
80
  </InternationalizationProvider>;`,
74
81
  },
75
82
  {
76
83
  type: 'prose',
77
- text: "See `@astryxdesign/core/locales/en.json` for the full inventory of keys to translate. Copy it as the starting point: every key you translate replaces the English default; anything you omit falls back through the locale chain to English (e.g. `pt-BR` walks to `pt` then to shipped `en`), so a partial translation renders as a mix rather than empty text or raw key names.",
78
- },
79
- {
80
- type: 'prose',
81
- text: 'A community-maintained set of astryx translations is on the roadmap but not shipped yet. For now, consumer apps that ship in multiple languages own their astryx catalogs alongside their app catalogs. Contributions to a first-party set are welcome; track discussion at https://github.com/facebook/astryx/issues/3641.',
84
+ text: "Persisting the user's choice (localStorage, cookie, URL segment, account setting) is up to the consumer. Astryx reads whatever `locale` you pass in.",
82
85
  },
83
86
  ],
84
87
  },
@@ -119,7 +122,7 @@ import fr from './locales/astryx/fr.json';
119
122
  type: 'code',
120
123
  lang: 'tsx',
121
124
  label: 'Astryx + react-intl side by side',
122
- code: `import {InternationalizationProvider} from '@astryxdesign/core';
125
+ code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
123
126
  import {Selector} from '@astryxdesign/core/Selector';
124
127
  import {Button} from '@astryxdesign/core/Button';
125
128
  import {FormattedMessage, IntlProvider, useIntl} from 'react-intl';
@@ -169,35 +172,56 @@ export default function App() {
169
172
  },
170
173
  {
171
174
  type: 'prose',
172
- text: "Single-catalog usage (where an external i18n runtime like react-intl or i18next resolves both your app strings AND astryx's strings through one provider) is on the roadmap via a `Translator` adapter. Track https://github.com/facebook/astryx/issues/4029. For now, run the two providers side by side as shown above.",
175
+ text: "Single-catalog usage (where an external i18n runtime like react-intl or i18next resolves both your app strings AND astryx's strings through one provider) is on the roadmap via a `Translator` adapter. Track [facebook/astryx#4029](https://github.com/facebook/astryx/issues/4029). For now, run the two providers side by side as shown above.",
173
176
  },
174
177
  ],
175
178
  },
176
179
  {
177
- title: 'Runtime language swap',
180
+ title: 'Using astryx as your i18n library',
178
181
  category: 'guide',
179
182
  content: [
180
183
  {
181
184
  type: 'prose',
182
- text: 'Re-render `<InternationalizationProvider>` with a new `locale` prop and every astryx string updates live. No reload, no separate API call.',
185
+ text: "For production apps with substantial localization needs, we recommend a dedicated i18n library such as react-intl, i18next, next-intl, or LinguiJS. If your app is small or you do not want another runtime, you can resolve your own strings through astryx too. Keep app keys in a separate namespace from `@astryx.*`, and include your own `en` catalog because astryx's built-in English fallback only contains astryx component strings.",
183
186
  },
184
187
  {
185
188
  type: 'code',
186
189
  lang: 'tsx',
187
- label: 'Toggle between locales',
188
- code: `const [locale, setLocale] = useState<'en' | 'fr'>('en');
190
+ label: 'Translate app strings with astryx',
191
+ code: `import {Button} from '@astryxdesign/core/Button';
192
+ import {
193
+ InternationalizationProvider,
194
+ useTranslator,
195
+ type Catalog,
196
+ type MessagesByLocale,
197
+ } from '@astryxdesign/core/i18n';
189
198
 
190
- <InternationalizationProvider locale={locale} messages={{fr}}>
191
- <Button
192
- label={locale === 'en' ? 'Français' : 'English'}
193
- onClick={() => setLocale(l => (l === 'en' ? 'fr' : 'en'))}
194
- />
195
- <App />
196
- </InternationalizationProvider>;`,
199
+ const en: Catalog = {
200
+ '@myapp.actions.save': {defaultMessage: 'Save'},
201
+ };
202
+
203
+ const fr: Catalog = {
204
+ '@myapp.actions.save': {defaultMessage: 'Enregistrer'},
205
+ };
206
+
207
+ const messages: MessagesByLocale = {en, fr};
208
+
209
+ function SaveButton() {
210
+ const t = useTranslator();
211
+ return <Button label={t('@myapp.actions.save')} />;
212
+ }
213
+
214
+ export default function App() {
215
+ return (
216
+ <InternationalizationProvider locale="fr" messages={messages}>
217
+ <SaveButton />
218
+ </InternationalizationProvider>
219
+ );
220
+ }`,
197
221
  },
198
222
  {
199
223
  type: 'prose',
200
- text: "Persisting the user's choice (localStorage, cookie, URL segment, account setting) is up to the consumer. Astryx reads whatever `locale` you pass in.",
224
+ text: '`Catalog` types a single locale file; `MessagesByLocale` types the map passed to `messages`. A catalog entry uses the same `{defaultMessage, description?}` shape as `@astryxdesign/core/locales/en.json`.',
201
225
  },
202
226
  ],
203
227
  },
@@ -207,36 +231,58 @@ export default function App() {
207
231
  content: [
208
232
  {
209
233
  type: 'prose',
210
- text: 'Astryx generates a `pseudo` locale that wraps every string in `⟦…⟧` and replaces letters with accented look-alikes. Switching to it in development instantly reveals any astryx string that isn\'t going through the translator, plus any layout that breaks under longer text.',
234
+ text: 'Astryx generates a `pseudo` locale that wraps every string in `⟦…⟧` and replaces letters with accented look-alikes. Switch to it in development to catch hardcoded astryx strings and layout issues caused by longer text.',
211
235
  },
212
236
  {
213
237
  type: 'code',
214
238
  lang: 'tsx',
215
239
  label: 'Turn on pseudo-localization',
216
- code: `import pseudo from '@astryxdesign/core/locales/pseudo.json';
240
+ code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
241
+ import pseudo from '@astryxdesign/core/locales/pseudo.json';
217
242
 
218
243
  <InternationalizationProvider locale="pseudo" messages={{pseudo}}>
219
244
  <App />
220
245
  </InternationalizationProvider>;`,
221
246
  },
222
- {
223
- type: 'prose',
224
- text: 'Any bare English text you still see on screen is a hardcoded string that needs to be routed through `useTranslator`.',
225
- },
226
- {
227
- type: 'prose',
228
- text: "Pseudoloc also has a subtle caveat worth knowing: the pseudo catalog is complete (astryx generates it from every shipped key), so a component using an astryx-shipped key will always render its pseudo version. Your handwritten translation catalogs, on the other hand, only cover the keys you translated; anything missing falls back to English. That means \"looks perfect in pseudo\" is not the same guarantee as \"looks perfect in French.\" Check each real locale by hand for coverage gaps.",
229
- },
230
247
  ],
231
248
  },
232
249
  {
233
250
  title: 'For contributors',
234
251
  category: 'guide',
235
252
  content: [
253
+ {
254
+ type: 'heading',
255
+ level: 3,
256
+ text: 'Developers',
257
+ },
258
+ {
259
+ type: 'prose',
260
+ text: 'Astryx component authors read strings with `useTranslator()` rather than hardcoding user-facing text.',
261
+ },
262
+ {
263
+ type: 'code',
264
+ lang: 'tsx',
265
+ label: 'Read an astryx string',
266
+ code: `import {useTranslator} from '@astryxdesign/core/i18n';
267
+
268
+ function SaveButton() {
269
+ const t = useTranslator();
270
+ return <button>{t('@astryx.actions.save')}</button>;
271
+ }`,
272
+ },
236
273
  {
237
274
  type: 'prose',
238
275
  text: "Astryx's own strings live in `packages/core/locales/en.json`. New user-facing strings must go through `useTranslator`; this is enforced by the `@astryx/no-hardcoded-i18n-string` ESLint rule. See the AI contribution guide for the alias-and-resolve pattern used when adding new keys.",
239
276
  },
277
+ {
278
+ type: 'heading',
279
+ level: 3,
280
+ text: 'Translators',
281
+ },
282
+ {
283
+ type: 'prose',
284
+ text: 'Crowdin is the preferred way to contribute — [join a language](https://crowdin.com/project/astryx), translate strings in the web UI, and your work syncs back to the repo without opening a PR. Direct PRs against `packages/core/locales/*.json` also work if you prefer that flow.',
285
+ },
240
286
  ],
241
287
  },
242
288
  ],
@@ -20,13 +20,13 @@
20
20
 
21
21
  import * as fs from 'node:fs';
22
22
  import * as path from 'node:path';
23
- import {findCoreDir, CLI_ROOT} from '../utils/paths.mjs';
24
- import {assertWithin, PathSafetyError} from '../utils/path-safety.mjs';
25
- import {getCliInvocation} from '../utils/package-manager.mjs';
26
- import {discoverComponents} from '../lib/component-discovery.mjs';
27
- import {humanLog} from '../lib/json.mjs';
28
- import {cliError} from '../lib/cli-error.mjs';
29
- import {ERROR_CODES} from '../lib/error-codes.mjs';
23
+ import {findCoreDir, CLI_ROOT} from '../../utils/paths.mjs';
24
+ import {assertWithin, PathSafetyError} from '../../utils/path-safety.mjs';
25
+ import {getCliInvocation} from '../../utils/package-manager.mjs';
26
+ import {discoverComponents} from '../../lib/component-discovery.mjs';
27
+ import {humanLog} from '../../lib/json.mjs';
28
+ import {cliError} from '../../lib/cli-error.mjs';
29
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
30
30
 
31
31
  const AGENTS_MD = 'AGENTS.md';
32
32
  const CLAUDE_MD = 'CLAUDE.md';
@@ -143,9 +143,11 @@ export function parseBlockVersion(content) {
143
143
  */
144
144
  export function inspectAgentDocs(targetDir, installedVersion) {
145
145
  const version = installedVersion ?? getXdsVersion(findCoreDir(targetDir));
146
+ /** @type {Array<{path: string, blockVersion: string|null, legacy: boolean, stale: boolean}>} */
146
147
  const files = [];
147
148
 
148
149
  for (const rel of discoverAgentDocs(targetDir)) {
150
+ /** @type {string} */
149
151
  let content;
150
152
  try {
151
153
  content = fs.readFileSync(path.join(targetDir, rel), 'utf-8');
@@ -165,9 +167,10 @@ export function inspectAgentDocs(targetDir, installedVersion) {
165
167
  const staleEntries = files.filter(f => f.stale);
166
168
  const staleFiles = staleEntries.map(f => f.path);
167
169
  const blockVersions = [
168
- ...new Set(staleEntries.map(f => f.blockVersion).filter(Boolean)),
170
+ ...new Set(staleEntries.map(f => f.blockVersion).filter(/** @returns {v is string} */ (v) => v != null)),
169
171
  ];
170
172
 
173
+ /** @type {'missing' | 'stale' | 'current'} */
171
174
  let status;
172
175
  if (files.length === 0) status = 'missing';
173
176
  else if (staleFiles.length > 0) status = 'stale';
@@ -195,7 +198,7 @@ export function resolveAgentPaths(targetDir, agent) {
195
198
  return {inject: [], create: [AGENTS_MD, CLAUDE_DIR_MD]};
196
199
  }
197
200
 
198
- const searchPaths = AGENT_PRESETS[agent];
201
+ const searchPaths = /** @type {Record<string, string[]>} */ (AGENT_PRESETS)[agent];
199
202
  if (!searchPaths) {
200
203
  return {inject: [], create: [AGENTS_MD]};
201
204
  }
@@ -258,6 +261,10 @@ export function detectStylingSystem(targetDir) {
258
261
  * `stylingSystem` tailors the custom-styling guidance to what the project has
259
262
  * configured (see {@link detectStylingSystem}) so the agent never reaches for a
260
263
  * styling path that isn't compiled here.
264
+ *
265
+ * @param {string} version
266
+ * @param {{coreDir?: string|null, invocation?: string, stylingSystem?: 'stylex'|'tailwind'|'css', zh?: boolean, lang?: string}} [options]
267
+ * @returns {string}
261
268
  */
262
269
  export function generateCompressedIndex(version, {coreDir, invocation = getCliInvocation(), stylingSystem = 'css'} = {}) {
263
270
  const run = invocation;
@@ -337,7 +344,7 @@ export function generateCompressedIndex(version, {coreDir, invocation = getCliIn
337
344
  if (fs.existsSync(docsDir)) {
338
345
  const topics = fs.readdirSync(docsDir)
339
346
  .map(f => f.match(/^(\w+)\.doc\.mjs$/))
340
- .filter(Boolean)
347
+ .filter(/** @returns {m is RegExpMatchArray} */ (m) => m != null)
341
348
  .map(m => m[1])
342
349
  .sort();
343
350
  if (topics.length > 0) lines.push(` docs <topic> ${topics.join(', ')}`);
@@ -351,6 +358,8 @@ export function generateCompressedIndex(version, {coreDir, invocation = getCliIn
351
358
 
352
359
  /**
353
360
  * Get Astryx version from core package.
361
+ * @param {string|null} coreDir
362
+ * @returns {string}
354
363
  */
355
364
  export function getXdsVersion(coreDir) {
356
365
  if (coreDir) {
@@ -419,6 +428,9 @@ export function injectXdsBlock(filePath, compressedIndex, {createIfMissing = fal
419
428
  /**
420
429
  * Inject or update Astryx section in AGENTS.md.
421
430
  * Always creates the file if it doesn't exist.
431
+ *
432
+ * @param {string} targetDir
433
+ * @param {string} version
422
434
  */
423
435
  export function injectAgentsMd(targetDir, version) {
424
436
  const agentsPath = path.join(targetDir, AGENTS_MD);
@@ -436,6 +448,8 @@ export function injectAgentsMd(targetDir, version) {
436
448
  * Inject or update Astryx section in CLAUDE.md.
437
449
  * Only injects if CLAUDE.md already exists.
438
450
  *
451
+ * @param {string} targetDir
452
+ * @param {string} version
439
453
  * @returns {boolean} Whether the file was written
440
454
  */
441
455
  export function injectClaudeMd(targetDir, version) {
@@ -451,6 +465,8 @@ export function injectClaudeMd(targetDir, version) {
451
465
  * Remove Astryx section from a file.
452
466
  * If the file becomes empty (only boilerplate header remains), deletes it.
453
467
  *
468
+ * @param {string} filePath
469
+ * @param {{deleteIfEmpty?: boolean}} [options]
454
470
  * @returns {boolean} Whether the Astryx section was found and removed
455
471
  */
456
472
  export function removeXdsBlock(filePath, {deleteIfEmpty = false} = {}) {
@@ -487,6 +503,7 @@ export function removeXdsBlock(filePath, {deleteIfEmpty = false} = {}) {
487
503
 
488
504
  /**
489
505
  * Remove Astryx section from all known agent doc files.
506
+ * @param {string} targetDir
490
507
  */
491
508
  export function removeAgentDocs(targetDir) {
492
509
  const allPaths = discoverAgentDocs(targetDir);
@@ -528,6 +545,7 @@ export function installAgentDocs(targetDir, {zh = false, lang, agent, paths, onl
528
545
  const invocation = getCliInvocation(targetDir);
529
546
  const stylingSystem = detectStylingSystem(targetDir);
530
547
  const compressedIndex = generateCompressedIndex(version, {coreDir, zh, lang, invocation, stylingSystem});
548
+ /** @type {string[]} */
531
549
  const written = [];
532
550
 
533
551
  // Explicit paths override everything
@@ -603,6 +621,7 @@ export function installAgentDocs(targetDir, {zh = false, lang, agent, paths, onl
603
621
 
604
622
  const VALID_AGENTS = ['claude', 'cursor', 'codex', 'hermes', 'all'];
605
623
 
624
+ /** @param {import('commander').Command} program */
606
625
  export function registerAgentDocs(program) {
607
626
  program
608
627
  .command('agent-docs')
@@ -610,7 +629,7 @@ export function registerAgentDocs(program) {
610
629
  .option('--remove', 'Remove the design system section from all agent doc files')
611
630
  .option('--agent <tool>', 'Target tool: claude, cursor, codex, hermes, all')
612
631
  .option('--agent-docs-path <path...>', 'Explicit file path(s) to write to')
613
- .action(options => {
632
+ .action(/** @param {{remove?: boolean, agent?: string, agentDocsPath?: string|string[]}} options */ options => {
614
633
  const targetDir = process.cwd();
615
634
  const coreDir = findCoreDir(targetDir);
616
635
  const version = getXdsVersion(coreDir);
@@ -16,7 +16,7 @@ import * as fs from 'node:fs';
16
16
  import * as path from 'node:path';
17
17
  import * as os from 'node:os';
18
18
  import {installAgentDocs} from './agent-docs.mjs';
19
- import {PathSafetyError} from '../utils/path-safety.mjs';
19
+ import {PathSafetyError} from '../../utils/path-safety.mjs';
20
20
 
21
21
  let tmpDir;
22
22
  beforeEach(() => {