@astryxdesign/cli 0.1.8-canary.3cbbe66 → 0.1.8-canary.433a57e

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 (297) hide show
  1. package/bin/astryx.mjs +10 -12
  2. package/docs/internationalization.doc.mjs +47 -89
  3. package/package.json +26 -33
  4. package/scripts/postinstall.mjs +4 -4
  5. package/{api/blog → src/api}/blog.mjs +6 -42
  6. package/{api/blog → src/api}/blog.test.mjs +2 -2
  7. package/{api/component → src/api}/component.mjs +26 -49
  8. package/{api/discover → src/api}/discover.mjs +18 -55
  9. package/{api/docs → src/api}/docs.mjs +21 -47
  10. package/{api/doctor → src/api}/doctor.mjs +8 -11
  11. package/{api/hook → src/api}/hook.mjs +11 -11
  12. package/{api → src/api}/index.mjs +9 -9
  13. package/{api/layout → src/api}/layout.mjs +17 -66
  14. package/{api/layout → src/api}/layout.test.mjs +1 -1
  15. package/{api/search → src/api}/search.mjs +12 -71
  16. package/{api/template → src/api}/template-integration.test.mjs +2 -2
  17. package/{api/template → src/api}/template-suffix.test.mjs +3 -3
  18. package/{api/template → src/api}/template.mjs +19 -96
  19. package/{api/theme → src/api}/theme-add.mjs +7 -35
  20. package/{api/integration → src/api}/validate-integration.mjs +15 -20
  21. package/{api/integration → src/api}/validate-integration.test.mjs +1 -1
  22. package/{authoring → src}/codemod.mjs +6 -6
  23. package/{codemods → src/codemods}/ensure-jscodeshift.mjs +1 -1
  24. package/{codemods → src/codemods}/integration-discovery.mjs +3 -6
  25. package/{codemods → src/codemods}/integration-discovery.test.mjs +1 -1
  26. package/{codemods → src/codemods}/integration-runner.mjs +3 -8
  27. package/{codemods → src/codemods}/registry.mjs +1 -3
  28. package/{codemods → src/codemods}/run-codemod.mjs +10 -17
  29. package/{codemods → src/codemods}/runner.mjs +12 -22
  30. package/{codemods → src/codemods}/transforms/v0.0.10/remove-size-props.mjs +4 -9
  31. package/{codemods → src/codemods}/transforms/v0.0.12/add-is-icon-only.mjs +22 -27
  32. package/{codemods → src/codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +5 -12
  33. package/{codemods → src/codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +8 -15
  34. package/{codemods → src/codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +4 -10
  35. package/{codemods → src/codemods}/transforms/v0.0.14/rename-action-props.mjs +5 -11
  36. package/{codemods → src/codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +6 -11
  37. package/{codemods → src/codemods}/transforms/v0.0.14/rename-status-variants.mjs +10 -15
  38. package/{codemods → src/codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +8 -13
  39. package/{codemods → src/codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +13 -18
  40. package/{codemods → src/codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +4 -8
  41. package/{codemods → src/codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +6 -11
  42. package/{codemods → src/codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +1 -6
  43. package/{codemods → src/codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +1 -6
  44. package/{codemods → src/codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +3 -8
  45. package/{codemods → src/codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +10 -17
  46. package/{codemods → src/codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +1 -7
  47. package/{codemods → src/codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +4 -9
  48. package/{codemods → src/codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +7 -12
  49. package/{codemods → src/codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +2 -7
  50. package/{codemods → src/codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +2 -8
  51. package/{codemods → src/codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +2 -7
  52. package/{codemods → src/codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +2 -7
  53. package/{codemods → src/codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +4 -11
  54. package/{codemods → src/codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +4 -10
  55. package/{codemods → src/codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +2 -7
  56. package/{codemods → src/codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +5 -10
  57. package/{codemods → src/codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +2 -7
  58. package/{codemods → src/codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +3 -9
  59. package/{codemods → src/codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +5 -11
  60. package/{codemods → src/codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +6 -13
  61. package/{codemods → src/codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +1 -7
  62. package/{codemods → src/codemods}/transforms/v0.0.6/migrate-token-names.mjs +5 -11
  63. package/{codemods → src/codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +3 -8
  64. package/{codemods → src/codemods}/transforms/v0.0.8/migrate-token-renames.mjs +8 -15
  65. package/{codemods → src/codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +2 -7
  66. package/{codemods → src/codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +14 -19
  67. package/{codemods → src/codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +17 -21
  68. package/{codemods → src/codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +2 -7
  69. package/{codemods → src/codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +11 -16
  70. package/{codemods → src/codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +9 -15
  71. package/{codemods → src/codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +12 -17
  72. package/{codemods → src/codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +9 -15
  73. package/{codemods → src/codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +10 -17
  74. package/{codemods → src/codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +13 -18
  75. package/{codemods → src/codemods}/transforms/v0.1.8/rename-avatar-size-scale.mjs +10 -15
  76. package/{cli → src}/commands/agent-docs.mjs +11 -30
  77. package/{cli → src}/commands/agent-docs.path-safety.test.mjs +1 -1
  78. package/{cli → src}/commands/blog.mjs +7 -48
  79. package/{cli → src}/commands/build-theme.mjs +46 -125
  80. package/{cli → src}/commands/build.mjs +9 -19
  81. package/{cli → src}/commands/component/index.mjs +22 -49
  82. package/{cli → src}/commands/component-ownership.test.mjs +3 -3
  83. package/{cli → src}/commands/component-package.test.mjs +1 -1
  84. package/{cli → src}/commands/component-resolution.test.mjs +2 -2
  85. package/{cli → src}/commands/discover.mjs +8 -17
  86. package/{cli → src}/commands/docs.mjs +7 -39
  87. package/{cli → src}/commands/docs.test.mjs +1 -1
  88. package/{cli → src}/commands/doctor.mjs +3 -3
  89. package/{cli → src}/commands/doctor.test.mjs +2 -2
  90. package/{cli → src}/commands/ensure-core-built.mjs +2 -3
  91. package/{cli → src}/commands/external-showcase.test.mjs +1 -1
  92. package/{cli → src}/commands/hook/index.mjs +14 -37
  93. package/{cli → src}/commands/import-hint-correctness.test.mjs +1 -1
  94. package/{cli → src}/commands/init.mjs +8 -19
  95. package/{cli → src}/commands/layout.mjs +18 -58
  96. package/{cli → src}/commands/search.mjs +12 -19
  97. package/{cli → src}/commands/search.test.mjs +1 -1
  98. package/{cli → src}/commands/swizzle.mjs +13 -20
  99. package/{cli → src}/commands/template.mjs +22 -73
  100. package/{cli → src}/commands/template.path-safety.test.mjs +2 -2
  101. package/{cli → src}/commands/upgrade.integration-policy.test.mjs +1 -1
  102. package/{cli → src}/commands/upgrade.mjs +51 -159
  103. package/{cli → src}/commands/validate-integration.mjs +3 -3
  104. package/{authoring → src}/config.test.mjs +1 -1
  105. package/{authoring → src}/doc.mjs +1 -1
  106. package/{authoring → src}/doc.test.mjs +1 -1
  107. package/{cli → src}/index.mjs +14 -15
  108. package/{lib → src/lib}/component-discovery.mjs +2 -44
  109. package/{lib → src/lib}/component-format.mjs +24 -65
  110. package/{lib → src/lib}/component-loader.mjs +13 -27
  111. package/{lib → src/lib}/componentDocOverlay.test.mjs +1 -0
  112. package/{lib → src/lib}/error-codes.test.mjs +1 -1
  113. package/{lib → src/lib}/hook-discovery.mjs +1 -14
  114. package/{lib → src/lib}/hook-format.mjs +5 -29
  115. package/{lib → src/lib}/integration-warnings.mjs +2 -2
  116. package/{lib → src/lib}/integrations.mjs +0 -20
  117. package/{lib → src/lib}/integrations.test.mjs +1 -1
  118. package/{lib → src/lib}/json-contract.test.mjs +1 -1
  119. package/{lib → src/lib}/json-shim.mjs +5 -10
  120. package/{lib → src/lib}/json-shim.test.mjs +1 -1
  121. package/{lib → src/lib}/levenshtein.mjs +0 -6
  122. package/{lib → src/lib}/manifest.mjs +5 -5
  123. package/{lib → src/lib}/manifest.test.mjs +2 -2
  124. package/{lib → src/lib}/module-loader.mjs +0 -1
  125. package/{lib → src/lib}/package-scanner.mjs +0 -47
  126. package/{lib → src/lib}/project.mjs +18 -48
  127. package/{lib → src/lib}/project.test.mjs +1 -1
  128. package/{lib → src/lib}/resolve-theme.mjs +0 -5
  129. package/{lib → src/lib}/string-utils.mjs +0 -15
  130. package/{lib → src/lib}/term-log.mjs +3 -12
  131. package/{lib → src/lib}/xle/browser.mjs +8 -18
  132. package/{lib → src/lib}/xle/expand.mjs +22 -155
  133. package/{lib → src/lib}/xle/parse.mjs +13 -119
  134. package/{lib → src/lib}/xle/print.mjs +14 -54
  135. package/{lib → src/lib}/xle/registry-core.mjs +3 -28
  136. package/{lib → src/lib}/xle/registry.mjs +4 -9
  137. package/{lib → src/lib}/xle/splice.mjs +2 -13
  138. package/{lib → src/lib}/xle/validate.mjs +14 -95
  139. package/{authoring → src}/template.mjs +1 -1
  140. package/{types → src/types}/api.contract.assert.ts +8 -17
  141. package/{types → src/types}/base.d.ts +1 -15
  142. package/src/types/codemod.d.ts +81 -0
  143. package/{types → src/types}/component.d.ts +1 -1
  144. package/{types → src/types}/discover.d.ts +1 -1
  145. package/{types → src/types}/docs.d.ts +4 -1
  146. package/{types → src/types}/hook.d.ts +1 -1
  147. package/src/types/theme.d.ts +23 -0
  148. package/{types → src/types}/upgrade.d.ts +1 -8
  149. package/{utils → src/utils}/paths.mjs +1 -4
  150. package/lib/xle/xle-ast.d.ts +0 -214
  151. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +0 -19
  152. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +0 -46
  153. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +0 -14
  154. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +0 -33
  155. package/types/codemod.d.ts +0 -166
  156. package/types/jscodeshift.d.ts +0 -19
  157. package/types/layout.d.ts +0 -74
  158. package/types/theme.d.ts +0 -53
  159. /package/{api/docs → src/api}/docOverlays.test.mjs +0 -0
  160. /package/{api → src/api}/error.mjs +0 -0
  161. /package/{api/integration → src/api}/integration-block-exports.test.mjs +0 -0
  162. /package/{api/template → src/api}/template.test.mjs +0 -0
  163. /package/{cli → src}/cli-exit-codes.test.mjs +0 -0
  164. /package/{authoring → src}/codemod.test.mjs +0 -0
  165. /package/{codemods → src/codemods}/__tests__/registry.test.mjs +0 -0
  166. /package/{codemods → src/codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
  167. /package/{codemods → src/codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
  168. /package/{codemods → src/codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
  169. /package/{codemods → src/codemods}/__tests__/runner.test.mjs +0 -0
  170. /package/{codemods → src/codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
  171. /package/{codemods → src/codemods}/__tests__/validation.test.mjs +0 -0
  172. /package/{codemods → src/codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
  173. /package/{codemods → src/codemods}/transforms/v0.0.10/index.mjs +0 -0
  174. /package/{codemods → src/codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
  175. /package/{codemods → src/codemods}/transforms/v0.0.12/index.mjs +0 -0
  176. /package/{codemods → src/codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
  177. /package/{codemods → src/codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
  178. /package/{codemods → src/codemods}/transforms/v0.0.13/index.mjs +0 -0
  179. /package/{codemods → src/codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
  180. /package/{codemods → src/codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
  181. /package/{codemods → src/codemods}/transforms/v0.0.14/index.mjs +0 -0
  182. /package/{codemods → src/codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
  183. /package/{codemods → src/codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
  184. /package/{codemods → src/codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
  185. /package/{codemods → src/codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
  186. /package/{codemods → src/codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
  187. /package/{codemods → src/codemods}/transforms/v0.0.15/index.mjs +0 -0
  188. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
  189. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
  190. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
  191. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
  192. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
  193. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
  194. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
  195. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
  196. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
  197. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
  198. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
  199. /package/{codemods → src/codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
  200. /package/{codemods → src/codemods}/transforms/v0.0.2/index.mjs +0 -0
  201. /package/{codemods → src/codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
  202. /package/{codemods → src/codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
  203. /package/{codemods → src/codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
  204. /package/{codemods → src/codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
  205. /package/{codemods → src/codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
  206. /package/{codemods → src/codemods}/transforms/v0.0.6/index.mjs +0 -0
  207. /package/{codemods → src/codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
  208. /package/{codemods → src/codemods}/transforms/v0.0.7/index.mjs +0 -0
  209. /package/{codemods → src/codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
  210. /package/{codemods → src/codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
  211. /package/{codemods → src/codemods}/transforms/v0.0.8/index.mjs +0 -0
  212. /package/{codemods → src/codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +0 -0
  213. /package/{codemods → src/codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
  214. /package/{codemods → src/codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
  215. /package/{codemods → src/codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +0 -0
  216. /package/{codemods → src/codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
  217. /package/{codemods → src/codemods}/transforms/v0.1.0/index.mjs +0 -0
  218. /package/{codemods → src/codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
  219. /package/{codemods → src/codemods}/transforms/v0.1.2/index.mjs +0 -0
  220. /package/{codemods → src/codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
  221. /package/{codemods → src/codemods}/transforms/v0.1.3/index.mjs +0 -0
  222. /package/{codemods → src/codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
  223. /package/{codemods → src/codemods}/transforms/v0.1.5/index.mjs +0 -0
  224. /package/{codemods → src/codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
  225. /package/{codemods → src/codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
  226. /package/{codemods → src/codemods}/transforms/v0.1.7/index.mjs +0 -0
  227. /package/{codemods → src/codemods}/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +0 -0
  228. /package/{codemods → src/codemods}/transforms/v0.1.8/index.mjs +0 -0
  229. /package/{cli → src}/commands/agent-docs.test.mjs +0 -0
  230. /package/{cli → src}/commands/build-theme.color-scheme.test.mjs +0 -0
  231. /package/{cli → src}/commands/build-theme.import-path.test.mjs +0 -0
  232. /package/{cli → src}/commands/build-theme.path-safety.test.mjs +0 -0
  233. /package/{cli → src}/commands/build-theme.prose.test.mjs +0 -0
  234. /package/{cli → src}/commands/build-theme.variants.test.mjs +0 -0
  235. /package/{cli → src}/commands/build-theme.watch.test.mjs +0 -0
  236. /package/{cli → src}/commands/cli-postinstall.test.mjs +0 -0
  237. /package/{cli → src}/commands/component.test.mjs +0 -0
  238. /package/{cli → src}/commands/detail-levels.test.mjs +0 -0
  239. /package/{cli → src}/commands/init.next-steps.test.mjs +0 -0
  240. /package/{cli → src}/commands/interactive-guard.test.mjs +0 -0
  241. /package/{cli → src}/commands/json-contract.test.mjs +0 -0
  242. /package/{cli → src}/commands/setup-nudge.test.mjs +0 -0
  243. /package/{cli → src}/commands/swizzle.path-safety.test.mjs +0 -0
  244. /package/{cli → src}/commands/swizzle.routing.test.mjs +0 -0
  245. /package/{cli → src}/commands/swizzle.test.mjs +0 -0
  246. /package/{cli → src}/commands/template.test.mjs +0 -0
  247. /package/{cli → src}/commands/upgrade.config-ordering.test.mjs +0 -0
  248. /package/{cli → src}/commands/upgrade.test.mjs +0 -0
  249. /package/{cli → src}/commands/validate-integration.test.mjs +0 -0
  250. /package/{authoring → src}/config.mjs +0 -0
  251. /package/{authoring → src}/integration.mjs +0 -0
  252. /package/{lib → src/lib}/cli-error.mjs +0 -0
  253. /package/{lib → src/lib}/cli-error.test.mjs +0 -0
  254. /package/{lib → src/lib}/component-discovery.importpath.test.mjs +0 -0
  255. /package/{lib → src/lib}/component-format.test.mjs +0 -0
  256. /package/{lib → src/lib}/component-loader.test.mjs +0 -0
  257. /package/{lib → src/lib}/config-cache.mjs +0 -0
  258. /package/{lib → src/lib}/config-cache.test.mjs +0 -0
  259. /package/{lib → src/lib}/config-schema.mjs +0 -0
  260. /package/{lib → src/lib}/error-codes.mjs +0 -0
  261. /package/{lib → src/lib}/integration-warnings.test.mjs +0 -0
  262. /package/{lib → src/lib}/json.mjs +0 -0
  263. /package/{lib → src/lib}/module-loader.test.mjs +0 -0
  264. /package/{lib → src/lib}/node-version.mjs +0 -0
  265. /package/{lib → src/lib}/node-version.test.mjs +0 -0
  266. /package/{lib → src/lib}/parse.mjs +0 -0
  267. /package/{lib → src/lib}/site.mjs +0 -0
  268. /package/{lib → src/lib}/xle/browser.d.ts +0 -0
  269. /package/{lib → src/lib}/xle/xle.test.mjs +0 -0
  270. /package/{schemas → src/schemas}/doc-schema.mjs +0 -0
  271. /package/{schemas → src/schemas}/template-schema.mjs +0 -0
  272. /package/{authoring → src}/template.test.mjs +0 -0
  273. /package/{types → src/types}/api.d.ts +0 -0
  274. /package/{types → src/types}/build.d.ts +0 -0
  275. /package/{types → src/types}/config.d.ts +0 -0
  276. /package/{types → src/types}/doc.d.ts +0 -0
  277. /package/{types → src/types}/doctor.d.ts +0 -0
  278. /package/{types → src/types}/error-codes.d.ts +0 -0
  279. /package/{types → src/types}/index.d.ts +0 -0
  280. /package/{types → src/types}/integration.d.ts +0 -0
  281. /package/{types → src/types}/manifest.d.ts +0 -0
  282. /package/{types → src/types}/search.d.ts +0 -0
  283. /package/{types → src/types}/swizzle.d.ts +0 -0
  284. /package/{types → src/types}/template-api.d.ts +0 -0
  285. /package/{types → src/types}/template.d.ts +0 -0
  286. /package/{types → src/types}/validate-integration.d.ts +0 -0
  287. /package/{cli → src}/update-hint-commands.test.mjs +0 -0
  288. /package/{utils → src/utils}/github.mjs +0 -0
  289. /package/{utils → src/utils}/package-manager.mjs +0 -0
  290. /package/{utils → src/utils}/package-manager.test.mjs +0 -0
  291. /package/{utils → src/utils}/path-safety.mjs +0 -0
  292. /package/{utils → src/utils}/path-safety.test.mjs +0 -0
  293. /package/{utils → src/utils}/paths.test.mjs +0 -0
  294. /package/{utils → src/utils}/semver.mjs +0 -0
  295. /package/{utils → src/utils}/semver.test.mjs +0 -0
  296. /package/{utils → src/utils}/update-check.mjs +0 -0
  297. /package/{utils → src/utils}/update-check.test.mjs +0 -0
package/bin/astryx.mjs CHANGED
@@ -13,22 +13,21 @@
13
13
  // `node-version.mjs` is intentionally dependency-free so it loads on the
14
14
  // unsupported runtimes this guard protects against.
15
15
  //
16
- // Sibling package modules (e.g. `cli/`, `lib/`) are resolved by this bin's REAL
17
- // path. When the CLI is installed as a package, `npx astryx` runs this file
18
- // through the `node_modules/.bin/astryx` symlink, and some Node versions resolve
19
- // relative specifiers from the symlink's directory rather than the real package
20
- // — breaking bare `../…` imports with a cryptic ERR_MODULE_NOT_FOUND.
21
- // realpath-ing `import.meta.url` makes these imports resolve correctly however
22
- // the bin is invoked (symlink, copy, or Windows shim). Uses only built-ins, so
23
- // the version gate below still runs first.
16
+ // Sibling `src/` modules are resolved by this bin's REAL path. When the CLI is
17
+ // installed as a package, `npx astryx` runs this file through the
18
+ // `node_modules/.bin/astryx` symlink, and some Node versions resolve relative
19
+ // specifiers from the symlink's directory (→ `node_modules/src/...`) rather
20
+ // than the real package — breaking bare `../src/...` imports with a cryptic
21
+ // ERR_MODULE_NOT_FOUND. realpath-ing `import.meta.url` makes these imports
22
+ // resolve correctly however the bin is invoked (symlink, copy, or Windows
23
+ // shim). Uses only built-ins, so the version gate below still runs first.
24
24
  import {fileURLToPath, pathToFileURL} from 'node:url';
25
25
  import {realpathSync} from 'node:fs';
26
26
  import {dirname, join} from 'node:path';
27
27
 
28
28
  const binDir = dirname(realpathSync(fileURLToPath(import.meta.url)));
29
- /** @param {string} rel */
30
29
  const importSrc = rel =>
31
- import(pathToFileURL(join(binDir, '..', rel)).href);
30
+ import(pathToFileURL(join(binDir, '..', 'src', rel)).href);
32
31
 
33
32
  const {isNodeVersionSupported, unsupportedNodeMessage} =
34
33
  await importSrc('lib/node-version.mjs');
@@ -55,7 +54,7 @@ if (!isNodeVersionSupported(process.versions.node)) {
55
54
 
56
55
  // Imports that transitively load `styleText` must happen AFTER the gate above,
57
56
  // so they are dynamically imported here rather than at the top of the module.
58
- const {program} = await importSrc('cli/index.mjs');
57
+ const {program} = await importSrc('index.mjs');
59
58
  const {isJsonMode, toErrorEnvelope} = await importSrc('lib/json.mjs');
60
59
  const {handleCommanderError} = await importSrc('lib/json-shim.mjs');
61
60
 
@@ -73,7 +72,6 @@ function inJsonMode() {
73
72
  return isJsonMode() || process.argv.slice(2).includes('--json');
74
73
  }
75
74
 
76
- /** @param {unknown} err */
77
75
  function handleFatal(err) {
78
76
  // CommanderError (parse errors, --help, unknown command) routes
79
77
  // through the JSON shim so that a --json consumer always gets a
@@ -7,7 +7,7 @@ export const docs = {
7
7
  title: 'Internationalization',
8
8
  category: 'guide',
9
9
  description:
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.',
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.',
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 the active `locale`; astryx components pick up localized strings from that provider.',
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.',
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/i18n';
25
+ code: `import {InternationalizationProvider} from '@astryxdesign/core';
26
26
 
27
27
  function App() {
28
28
  return (
@@ -32,56 +32,53 @@ 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
- },
39
35
  {
40
36
  type: 'code',
41
37
  lang: 'tsx',
42
- label: 'Load an astryx locale catalog',
43
- code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
44
- import fr from '@astryxdesign/core/locales/fr.json';
38
+ label: 'Read strings inside a component',
39
+ code: `import {useTranslator} from '@astryxdesign/core';
45
40
 
46
- <InternationalizationProvider locale="fr" messages={{fr}}>
47
- <App />
48
- </InternationalizationProvider>;`,
41
+ function SaveButton() {
42
+ const t = useTranslator();
43
+ return <button>{t('@myapp.actions.save')}</button>;
44
+ }`,
49
45
  },
50
46
  {
51
47
  type: 'prose',
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`).',
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.',
53
49
  },
54
50
  {
55
51
  type: 'prose',
56
- text: 'Locale catalogs only affect astryx strings. Your app can continue using its own i18n system for product copy.',
52
+ text: "Astryx ships translations only for English today. First-party translations for other locales are on the roadmap. 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.",
57
53
  },
58
54
  ],
59
55
  },
60
56
  {
61
- title: 'Runtime language swap',
57
+ title: 'Providing locale catalogs',
62
58
  category: 'guide',
63
59
  content: [
64
60
  {
65
61
  type: 'prose',
66
- text: 'Re-render `<InternationalizationProvider>` with a new `locale` prop and every astryx string updates live. No reload, no separate API call.',
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.',
67
63
  },
68
64
  {
69
65
  type: 'code',
70
66
  lang: 'tsx',
71
- label: 'Toggle between locales',
72
- code: `const [locale, setLocale] = useState<'en' | 'fr'>('en');
67
+ label: 'Add French',
68
+ code: `import {InternationalizationProvider} from '@astryxdesign/core';
69
+ import fr from './locales/astryx/fr.json';
73
70
 
74
- <InternationalizationProvider locale={locale} messages={{fr}}>
75
- <Button
76
- label={locale === 'en' ? 'Français' : 'English'}
77
- onClick={() => setLocale(l => (l === 'en' ? 'fr' : 'en'))}
78
- />
71
+ <InternationalizationProvider locale="fr" messages={{fr}}>
79
72
  <App />
80
73
  </InternationalizationProvider>;`,
81
74
  },
82
75
  {
83
76
  type: 'prose',
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.",
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. Translations are coordinated through Crowdin — contribute at https://crowdin.com/project/astryx.',
85
82
  },
86
83
  ],
87
84
  },
@@ -122,7 +119,7 @@ import fr from '@astryxdesign/core/locales/fr.json';
122
119
  type: 'code',
123
120
  lang: 'tsx',
124
121
  label: 'Astryx + react-intl side by side',
125
- code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
122
+ code: `import {InternationalizationProvider} from '@astryxdesign/core';
126
123
  import {Selector} from '@astryxdesign/core/Selector';
127
124
  import {Button} from '@astryxdesign/core/Button';
128
125
  import {FormattedMessage, IntlProvider, useIntl} from 'react-intl';
@@ -172,56 +169,35 @@ export default function App() {
172
169
  },
173
170
  {
174
171
  type: 'prose',
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.",
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.",
176
173
  },
177
174
  ],
178
175
  },
179
176
  {
180
- title: 'Using astryx as your i18n library',
177
+ title: 'Runtime language swap',
181
178
  category: 'guide',
182
179
  content: [
183
180
  {
184
181
  type: 'prose',
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.",
182
+ text: 'Re-render `<InternationalizationProvider>` with a new `locale` prop and every astryx string updates live. No reload, no separate API call.',
186
183
  },
187
184
  {
188
185
  type: 'code',
189
186
  lang: 'tsx',
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';
198
-
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
- }
187
+ label: 'Toggle between locales',
188
+ code: `const [locale, setLocale] = useState<'en' | 'fr'>('en');
213
189
 
214
- export default function App() {
215
- return (
216
- <InternationalizationProvider locale="fr" messages={messages}>
217
- <SaveButton />
218
- </InternationalizationProvider>
219
- );
220
- }`,
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>;`,
221
197
  },
222
198
  {
223
199
  type: 'prose',
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`.',
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.",
225
201
  },
226
202
  ],
227
203
  },
@@ -231,57 +207,39 @@ export default function App() {
231
207
  content: [
232
208
  {
233
209
  type: 'prose',
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.',
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.',
235
211
  },
236
212
  {
237
213
  type: 'code',
238
214
  lang: 'tsx',
239
215
  label: 'Turn on pseudo-localization',
240
- code: `import {InternationalizationProvider} from '@astryxdesign/core/i18n';
241
- import pseudo from '@astryxdesign/core/locales/pseudo.json';
216
+ code: `import pseudo from '@astryxdesign/core/locales/pseudo.json';
242
217
 
243
218
  <InternationalizationProvider locale="pseudo" messages={{pseudo}}>
244
219
  <App />
245
220
  </InternationalizationProvider>;`,
246
221
  },
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
+ },
247
230
  ],
248
231
  },
249
232
  {
250
233
  title: 'For contributors',
251
234
  category: 'guide',
252
235
  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
- },
273
236
  {
274
237
  type: 'prose',
275
238
  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.",
276
239
  },
277
- {
278
- type: 'heading',
279
- level: 3,
280
- text: 'Translators',
281
- },
282
240
  {
283
241
  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.',
242
+ text: 'Translators: Crowdin is the preferred way to contribute — join a language at 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
243
  },
286
244
  ],
287
245
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/cli",
3
- "version": "0.1.8-canary.3cbbe66",
3
+ "version": "0.1.8-canary.433a57e",
4
4
  "displayName": "CLI",
5
5
  "description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
6
6
  "author": "Meta Open Source",
@@ -32,48 +32,41 @@
32
32
  "exports": {
33
33
  ".": "./bin/astryx.mjs",
34
34
  "./json": {
35
- "types": "./types/index.d.ts",
36
- "import": "./lib/parse.mjs"
35
+ "types": "./src/types/index.d.ts",
36
+ "import": "./src/lib/parse.mjs"
37
37
  },
38
38
  "./api": {
39
- "types": "./types/api.d.ts",
40
- "import": "./api/index.mjs"
39
+ "types": "./src/types/api.d.ts",
40
+ "import": "./src/api/index.mjs"
41
41
  },
42
42
  "./config": {
43
- "types": "./types/config.d.ts",
44
- "import": "./authoring/config.mjs"
43
+ "types": "./src/types/config.d.ts",
44
+ "import": "./src/config.mjs"
45
45
  },
46
46
  "./integration": {
47
- "types": "./types/integration.d.ts",
48
- "import": "./authoring/integration.mjs"
47
+ "types": "./src/types/integration.d.ts",
48
+ "import": "./src/integration.mjs"
49
49
  },
50
50
  "./doc": {
51
- "types": "./types/doc.d.ts",
52
- "import": "./authoring/doc.mjs"
51
+ "types": "./src/types/doc.d.ts",
52
+ "import": "./src/doc.mjs"
53
53
  },
54
54
  "./template": {
55
- "types": "./types/template-api.d.ts",
56
- "import": "./authoring/template.mjs"
55
+ "types": "./src/types/template-api.d.ts",
56
+ "import": "./src/template.mjs"
57
57
  },
58
58
  "./codemod": {
59
- "types": "./types/codemod.d.ts",
60
- "import": "./authoring/codemod.mjs"
59
+ "types": "./src/types/codemod.d.ts",
60
+ "import": "./src/codemod.mjs"
61
61
  },
62
62
  "./xle": {
63
- "types": "./lib/xle/browser.d.ts",
64
- "import": "./lib/xle/browser.mjs"
63
+ "types": "./src/lib/xle/browser.d.ts",
64
+ "import": "./src/lib/xle/browser.mjs"
65
65
  }
66
66
  },
67
67
  "files": [
68
68
  "bin",
69
- "api",
70
- "cli",
71
- "codemods",
72
- "authoring",
73
- "lib",
74
- "utils",
75
- "types",
76
- "schemas",
69
+ "src",
77
70
  "scripts/postinstall.mjs",
78
71
  "templates",
79
72
  "docs",
@@ -86,10 +79,10 @@
86
79
  "zod": "^4.4.3"
87
80
  },
88
81
  "peerDependencies": {
89
- "@astryxdesign/charts": "0.1.8-canary.3cbbe66",
90
- "@astryxdesign/core": "0.1.8-canary.3cbbe66",
91
- "@astryxdesign/lab": "0.1.8-canary.3cbbe66",
92
- "@astryxdesign/theme-neutral": "0.1.8-canary.3cbbe66",
82
+ "@astryxdesign/charts": "0.1.8-canary.433a57e",
83
+ "@astryxdesign/core": "0.1.8-canary.433a57e",
84
+ "@astryxdesign/lab": "0.1.8-canary.433a57e",
85
+ "@astryxdesign/theme-neutral": "0.1.8-canary.433a57e",
93
86
  "gpt-tokenizer": "^3.4.0"
94
87
  },
95
88
  "peerDependenciesMeta": {
@@ -107,10 +100,10 @@
107
100
  }
108
101
  },
109
102
  "devDependencies": {
110
- "@astryxdesign/charts": "0.1.8-canary.3cbbe66",
111
- "@astryxdesign/core": "0.1.8-canary.3cbbe66",
112
- "@astryxdesign/lab": "0.1.8-canary.3cbbe66",
113
- "@astryxdesign/theme-neutral": "0.1.8-canary.3cbbe66",
103
+ "@astryxdesign/charts": "0.1.8-canary.433a57e",
104
+ "@astryxdesign/core": "0.1.8-canary.433a57e",
105
+ "@astryxdesign/lab": "0.1.8-canary.433a57e",
106
+ "@astryxdesign/theme-neutral": "0.1.8-canary.433a57e",
114
107
  "gpt-tokenizer": "^3.4.0"
115
108
  },
116
109
  "scripts": {
@@ -24,11 +24,11 @@ const HERE = fileURLToPath(import.meta.url);
24
24
  * Pure decision: should the postinstall print the setup nudge? Split out so the
25
25
  * matrix is unit-testable without an actual npm install.
26
26
  *
27
- * @param {object} [opts]
28
- * @param {string} [opts.scriptPath] - Absolute path of this script (location tells
27
+ * @param {object} opts
28
+ * @param {string} opts.scriptPath - Absolute path of this script (location tells
29
29
  * us dependency vs monorepo vs npx-cache).
30
30
  * @param {string} [opts.npmCommand] - process.env.npm_command ('install', 'exec', …).
31
- * @param {boolean} [opts.isSetUp] - Whether the project already ran init.
31
+ * @param {boolean} opts.isSetUp - Whether the project already ran init.
32
32
  * @returns {boolean}
33
33
  */
34
34
  export function shouldNudge({scriptPath, npmCommand, isSetUp} = {}) {
@@ -41,7 +41,7 @@ export function shouldNudge({scriptPath, npmCommand, isSetUp} = {}) {
41
41
  /** @param {string} root @returns {Promise<boolean>} */
42
42
  async function projectIsSetUp(root) {
43
43
  try {
44
- const {isAstryxInitialized} = await import('../cli/commands/agent-docs.mjs');
44
+ const {isAstryxInitialized} = await import('../src/commands/agent-docs.mjs');
45
45
  return isAstryxInitialized(root);
46
46
  } catch {
47
47
  return false; // best-effort — if the check can't load, fall through and nudge
@@ -10,9 +10,9 @@
10
10
  * blog's structure can change freely without touching the CLI.
11
11
  */
12
12
 
13
- import {AstryxError} from '../error.mjs';
14
- import {ERROR_CODES} from '../../lib/error-codes.mjs';
15
- import {SITE_URL, SITE_ORIGIN} from '../../lib/site.mjs';
13
+ import {AstryxError} from './error.mjs';
14
+ import {ERROR_CODES} from '../lib/error-codes.mjs';
15
+ import {SITE_URL, SITE_ORIGIN} from '../lib/site.mjs';
16
16
 
17
17
  /** Abort a feed/post fetch that hangs, and cap how much we'll read. */
18
18
  const FETCH_TIMEOUT_MS = 15000;
@@ -20,10 +20,6 @@ const MAX_BYTES = 5 * 1024 * 1024; // 5 MB — a blog feed is never larger.
20
20
 
21
21
  const FEED_URL = new URL('/rss.xml', SITE_URL).toString();
22
22
 
23
- /**
24
- * @param {string} url
25
- * @returns {Promise<string>}
26
- */
27
23
  async function fetchText(url) {
28
24
  const controller = new AbortController();
29
25
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
@@ -35,12 +31,7 @@ async function fetchText(url) {
35
31
  });
36
32
  } catch (e) {
37
33
  clearTimeout(timer);
38
- const reason =
39
- e instanceof Error
40
- ? e.name === 'AbortError'
41
- ? 'timed out'
42
- : e.message
43
- : String(e);
34
+ const reason = e.name === 'AbortError' ? 'timed out' : e.message;
44
35
  throw new AstryxError(
45
36
  `Could not reach ${url}: ${reason}`,
46
37
  [],
@@ -70,7 +61,6 @@ async function fetchText(url) {
70
61
  * Defense in depth: a post's plaintext URL comes from feed content. Require it
71
62
  * to live on the canonical origin so even a tampered feed can't redirect the
72
63
  * CLI to another host.
73
- * @param {string} target
74
64
  */
75
65
  function assertCanonicalOrigin(target) {
76
66
  let targetOrigin;
@@ -92,10 +82,6 @@ function assertCanonicalOrigin(target) {
92
82
  }
93
83
  }
94
84
 
95
- /**
96
- * @param {string} value
97
- * @returns {string}
98
- */
99
85
  function unescapeXml(value) {
100
86
  return value
101
87
  .replace(/&lt;/g, '<')
@@ -105,23 +91,12 @@ function unescapeXml(value) {
105
91
  .replace(/&amp;/g, '&');
106
92
  }
107
93
 
108
- /**
109
- * @param {string} item
110
- * @param {string} name
111
- * @returns {string}
112
- */
113
94
  function tag(item, name) {
114
95
  const m = item.match(new RegExp(`<${name}[^>]*>([\\s\\S]*?)</${name}>`));
115
96
  return m ? unescapeXml(m[1].trim()) : '';
116
97
  }
117
98
 
118
- /**
119
- * @param {string} item
120
- * @param {string} name
121
- * @returns {string[]}
122
- */
123
99
  function tagAll(item, name) {
124
- /** @type {string[]} */
125
100
  const out = [];
126
101
  const re = new RegExp(`<${name}[^>]*>([\\s\\S]*?)</${name}>`, 'g');
127
102
  let m;
@@ -129,11 +104,7 @@ function tagAll(item, name) {
129
104
  return out;
130
105
  }
131
106
 
132
- /**
133
- * Extract the plaintext alternate href from an <item>.
134
- * @param {string} item
135
- * @returns {string | null}
136
- */
107
+ /** Extract the plaintext alternate href from an <item>. */
137
108
  function textHref(item) {
138
109
  // Match the atom:link alternate regardless of attribute order/quoting; then
139
110
  // confirm it's the text/plain alternate before trusting the href.
@@ -150,11 +121,7 @@ function textHref(item) {
150
121
  return null;
151
122
  }
152
123
 
153
- /**
154
- * Derive a slug from a post link (last path segment).
155
- * @param {string} link
156
- * @returns {string}
157
- */
124
+ /** Derive a slug from a post link (last path segment). */
158
125
  function slugFromLink(link) {
159
126
  try {
160
127
  const path = new URL(link).pathname.replace(/\/$/, '');
@@ -164,9 +131,6 @@ function slugFromLink(link) {
164
131
  }
165
132
  }
166
133
 
167
- /**
168
- * @param {string} xml
169
- */
170
134
  function parseFeed(xml) {
171
135
  const items = [];
172
136
  const re = /<item>([\s\S]*?)<\/item>/g;
@@ -9,8 +9,8 @@
9
9
 
10
10
  import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
11
11
  import {blog} from './blog.mjs';
12
- import {AstryxError} from '../error.mjs';
13
- import {SITE_URL} from '../../lib/site.mjs';
12
+ import {AstryxError} from './error.mjs';
13
+ import {SITE_URL} from '../lib/site.mjs';
14
14
 
15
15
  const FEED = `<?xml version="1.0" encoding="UTF-8"?>
16
16
  <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">