@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
@@ -17,25 +17,27 @@ import * as path from 'node:path';
17
17
  import {pathToFileURL, fileURLToPath} from 'node:url';
18
18
  import {spawn} from 'node:child_process';
19
19
  import {createJiti} from 'jiti';
20
- import {getCliInvocation} from '../utils/package-manager.mjs';
20
+ import {getCliInvocation} from '../../utils/package-manager.mjs';
21
21
  import {
22
22
  sanitizeName,
23
23
  PathSafetyError,
24
- } from '../utils/path-safety.mjs';
25
- import {jsonOut, humanLog} from '../lib/json.mjs';
26
- import {cliError} from '../lib/cli-error.mjs';
27
- import {ERROR_CODES} from '../lib/error-codes.mjs';
28
- import {themeAdd} from '../api/theme-add.mjs';
24
+ } from '../../utils/path-safety.mjs';
25
+ import {jsonOut, humanLog} from '../../lib/json.mjs';
26
+ import {cliError} from '../../lib/cli-error.mjs';
27
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
28
+ import {themeAdd} from '../../api/theme/theme-add.mjs';
29
29
 
30
30
  // Import shared theme processing from core. `astryx theme build` MUST produce the
31
31
  // exact same CSS as the `<Theme>` runtime, so it has exactly one generation
32
32
  // path: core's generator. There is no in-CLI fallback implementation — if this
33
33
  // import fails, the build fails (see the ERR_CORE_NOT_FOUND guard in the theme
34
34
  // action). A built, resolvable `@astryxdesign/core` is a hard requirement.
35
- let _defineTheme = null;
36
- let _generateThemeRulesSplit = null;
37
- let _generateOnMediaCSS = null;
38
- let _coreImportError = null;
35
+ // A built, resolvable `@astryxdesign/core` is a hard requirement. These are
36
+ // populated from a dynamic import (a runtime boundary), so `any` is intentional.
37
+ /** @type {any} */ let _defineTheme = null;
38
+ /** @type {any} */ let _generateThemeRulesSplit = null;
39
+ /** @type {any} */ let _generateOnMediaCSS = null;
40
+ /** @type {any} */ let _coreImportError = null;
39
41
  try {
40
42
  const coreTheme = await import('@astryxdesign/core/theme');
41
43
  _defineTheme = coreTheme.defineTheme;
@@ -75,9 +77,11 @@ function generatedHeader(sourceFile, lang = 'js', command) {
75
77
  /**
76
78
  * Convert a theme name to a valid JS identifier.
77
79
  * e.g. 'default-minimal' → 'defaultMinimal', 'ocean' → 'ocean'
80
+ * @param {string} name
81
+ * @returns {string}
78
82
  */
79
83
  function toIdentifier(name) {
80
- return name.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
84
+ return name.replace(/-([a-z])/g, (/** @type {string} */ _, /** @type {string} */ c) => c.toUpperCase());
81
85
  }
82
86
 
83
87
  /**
@@ -85,6 +89,9 @@ function toIdentifier(name) {
85
89
  * from the cwd-relative dir (most consumers import from a file under src/) but
86
90
  * keeps the rest of the path (e.g. `themes/gothic`). Callers note the path is
87
91
  * relative to the consumer's file.
92
+ * @param {string} relDir
93
+ * @param {string} base
94
+ * @returns {string}
88
95
  */
89
96
  function importSpecifier(relDir, base) {
90
97
  const normalized = relDir === '.' ? '' : relDir;
@@ -95,11 +102,13 @@ function importSpecifier(relDir, base) {
95
102
  /**
96
103
  * Convert a kebab-case component name to PascalCase.
97
104
  * e.g. 'button' → 'Button', 'progress-bar' → 'ProgressBar', 'avatar-status-dot' → 'AvatarStatusDot'
105
+ * @param {string} name
106
+ * @returns {string}
98
107
  */
99
108
  function toPascalCase(name) {
100
109
  return name
101
110
  .split('-')
102
- .map(part => part.charAt(0).toUpperCase() + part.slice(1))
111
+ .map((/** @type {string} */ part) => part.charAt(0).toUpperCase() + part.slice(1))
103
112
  .join('');
104
113
  }
105
114
 
@@ -107,6 +116,8 @@ function toPascalCase(name) {
107
116
  * Load known built-in values for a component's visual props from its .doc.mjs file.
108
117
  * Parses the type string (e.g. "'info' | 'warning' | 'error' | 'success'") to extract values.
109
118
  * Returns a map of { propName: string[] } for props that are visual (listed in theming targets).
119
+ * @param {string} componentName
120
+ * @returns {Promise<Record<string, string[]>>}
110
121
  */
111
122
  async function loadKnownValues(componentName) {
112
123
  // Resolve core src relative to the CLI package, not cwd (which may be a theme package)
@@ -140,6 +151,7 @@ async function loadKnownValues(componentName) {
140
151
  if (allProps.length === 0) return {};
141
152
 
142
153
  // Collect visual prop names from theming targets
154
+ /** @type {Set<string>} */
143
155
  const visualProps = new Set();
144
156
  for (const target of doc.theming.targets) {
145
157
  if (target.visualProps) {
@@ -148,6 +160,7 @@ async function loadKnownValues(componentName) {
148
160
  }
149
161
 
150
162
  // Extract values from prop type strings
163
+ /** @type {Record<string, string[]>} */
151
164
  const result = {};
152
165
  for (const prop of allProps) {
153
166
  if (!visualProps.has(prop.name)) continue;
@@ -156,7 +169,7 @@ async function loadKnownValues(componentName) {
156
169
  // Parse union type: "'info' | 'warning' | 'error' | 'success'" → ['info', 'warning', 'error', 'success']
157
170
  const matches = prop.type.match(/'([^']+)'/g);
158
171
  if (matches) {
159
- result[prop.name] = matches.map(m => m.replace(/'/g, ''));
172
+ result[prop.name] = matches.map((/** @type {string} */ m) => m.replace(/'/g, ''));
160
173
  }
161
174
  }
162
175
  return result;
@@ -166,12 +179,17 @@ async function loadKnownValues(componentName) {
166
179
  }
167
180
 
168
181
  // Cache for loaded known values
182
+ /** @type {Map<string, Record<string, string[]>>} */
169
183
  const _knownValuesCache = new Map();
184
+ /**
185
+ * @param {string} componentName
186
+ * @returns {Promise<Record<string, string[]>>}
187
+ */
170
188
  async function getKnownValues(componentName) {
171
189
  if (!_knownValuesCache.has(componentName)) {
172
190
  _knownValuesCache.set(componentName, await loadKnownValues(componentName));
173
191
  }
174
- return _knownValuesCache.get(componentName);
192
+ return _knownValuesCache.get(componentName) ?? {};
175
193
  }
176
194
 
177
195
  /**
@@ -195,10 +213,15 @@ function resolveCoreRoot() {
195
213
  * actually sees), falling back to the `src/<Component>/index.ts` in the
196
214
  * monorepo. Returns the file contents, or '' if nothing is found.
197
215
  */
216
+ /** @type {Map<string, string>} */
198
217
  const _componentDeclCache = new Map();
218
+ /**
219
+ * @param {string} pascalName
220
+ * @returns {string}
221
+ */
199
222
  function readComponentDeclarations(pascalName) {
200
223
  if (_componentDeclCache.has(pascalName)) {
201
- return _componentDeclCache.get(pascalName);
224
+ return _componentDeclCache.get(pascalName) ?? '';
202
225
  }
203
226
  let contents = '';
204
227
  const coreRoot = resolveCoreRoot();
@@ -230,6 +253,9 @@ function readComponentDeclarations(pascalName) {
230
253
  * `HeadingType`, `ButtonSize`) are NOT augmentable, so a generated augmentation
231
254
  * against them is dead code. We check that the name is exported (directly or
232
255
  * re-exported) as a type/interface.
256
+ * @param {string} pascalName
257
+ * @param {string} interfaceName
258
+ * @returns {boolean}
233
259
  */
234
260
  function componentHasAugmentableInterface(pascalName, interfaceName) {
235
261
  const decl = readComponentDeclarations(pascalName);
@@ -254,7 +280,7 @@ function componentHasAugmentableInterface(pascalName, interfaceName) {
254
280
  * generating a `declare module` block for them would be dead code — those are
255
281
  * skipped.
256
282
  *
257
- * @param {object} themeDef - Theme definition (resolved by defineTheme)
283
+ * @param {{components?: Record<string, Record<string, Record<string, unknown>>>}} themeDef - Theme definition (resolved by defineTheme)
258
284
  * @returns {Promise<string|null>} TypeScript declaration content, or null if no augmentations needed
259
285
  */
260
286
  async function generateVariantDeclarationsAsync(themeDef) {
@@ -263,6 +289,7 @@ async function generateVariantDeclarationsAsync(themeDef) {
263
289
  }
264
290
 
265
291
  // Collect custom values: { component: { prop: [value, ...] } }
292
+ /** @type {Record<string, Record<string, Set<string>>>} */
266
293
  const customValues = {};
267
294
 
268
295
  for (const [component, rules] of Object.entries(themeDef.components)) {
@@ -336,6 +363,8 @@ async function generateVariantDeclarationsAsync(themeDef) {
336
363
 
337
364
  /**
338
365
  * Resolve a token value — [light, dark] tuple becomes light-dark()
366
+ * @param {unknown} value
367
+ * @returns {unknown}
339
368
  */
340
369
  function resolveTokenValue(value) {
341
370
  if (Array.isArray(value)) {
@@ -347,12 +376,14 @@ function resolveTokenValue(value) {
347
376
  // Theme @scope selector helpers. Keep the `astryx` literal in sync with
348
377
  // packages/core/src/naming.ts (NAMESPACE) and generateThemeRules.ts.
349
378
  // Theme scopes to data-astryx-theme; the static build path must match.
350
- const themeScopeStart = name => `[data-astryx-theme="${name}"]`;
379
+ const themeScopeStart = (/** @type {string} */ name) => `[data-astryx-theme="${name}"]`;
351
380
  const THEME_SCOPE_TO = `[data-astryx-theme]`;
352
381
 
353
382
  /**
354
383
  * Import a theme module using jiti and find the defineTheme() result.
355
384
  * Returns the resolved DefinedTheme object.
385
+ * @param {string} filePath
386
+ * @returns {Promise<any>}
356
387
  */
357
388
  async function importThemeModule(filePath) {
358
389
  const jiti = createJiti(import.meta.url, {
@@ -376,6 +407,10 @@ async function importThemeModule(filePath) {
376
407
  );
377
408
  }
378
409
 
410
+ /**
411
+ * @param {any} value
412
+ * @returns {boolean}
413
+ */
379
414
  function isThemeObject(value) {
380
415
  return (
381
416
  value &&
@@ -389,6 +424,8 @@ function isThemeObject(value) {
389
424
  /**
390
425
  * Extract the theme definition from a JS/TS file.
391
426
  * Tries jiti first (full TS support), falls back to regex+eval.
427
+ * @param {string} filePath
428
+ * @returns {Promise<any>}
392
429
  */
393
430
  async function extractThemeDefinition(filePath) {
394
431
  try {
@@ -397,8 +434,9 @@ async function extractThemeDefinition(filePath) {
397
434
  try {
398
435
  return extractThemeDefinitionLegacy(filePath);
399
436
  } catch {
437
+ const je = /** @type {Error} */ (jitiError);
400
438
  throw new Error(
401
- `Failed to load theme from ${filePath}: ${jitiError.message}\n` +
439
+ `Failed to load theme from ${filePath}: ${je.message}\n` +
402
440
  `Make sure all imports in the theme file are resolvable.`,
403
441
  );
404
442
  }
@@ -408,6 +446,8 @@ async function extractThemeDefinition(filePath) {
408
446
  /**
409
447
  * Fallback extraction via regex + eval.
410
448
  * Only works for plain object literals — can't follow imports or variables.
449
+ * @param {string} filePath
450
+ * @returns {any}
411
451
  */
412
452
  function extractThemeDefinitionLegacy(filePath) {
413
453
  const content = fs.readFileSync(filePath, 'utf8');
@@ -433,8 +473,9 @@ function extractThemeDefinitionLegacy(filePath) {
433
473
 
434
474
  return eval(`(${objStr})`);
435
475
  } catch (e) {
476
+ const err = /** @type {Error} */ (e);
436
477
  throw new Error(
437
- `Failed to parse theme definition in ${filePath}: ${e.message}\n` +
478
+ `Failed to parse theme definition in ${filePath}: ${err.message}\n` +
438
479
  `Make sure the defineTheme() argument is a plain object literal.`,
439
480
  {cause: e},
440
481
  );
@@ -448,6 +489,8 @@ function extractThemeDefinitionLegacy(filePath) {
448
489
  * Looks for patterns like:
449
490
  * import { defaultIconRegistry } from './icons';
450
491
  * icons: defaultIconRegistry,
492
+ * @param {string} filePath
493
+ * @returns {{exportName: string, importPath: string} | null}
451
494
  */
452
495
  function extractIconInfo(filePath) {
453
496
  const content = fs.readFileSync(filePath, 'utf8');
@@ -456,7 +499,7 @@ function extractIconInfo(filePath) {
456
499
  const iconsMatch = content.match(/icons:\s*([a-zA-Z_][a-zA-Z0-9_]*)/);
457
500
  if (!iconsMatch) return null;
458
501
 
459
- const varName = iconsMatch[1];
502
+ const varName = /** @type {string} */ (iconsMatch[1]);
460
503
 
461
504
  // Find the import for that variable
462
505
  const importRegex = new RegExp(
@@ -467,7 +510,7 @@ function extractIconInfo(filePath) {
467
510
 
468
511
  return {
469
512
  exportName: varName,
470
- importPath: importMatch[1],
513
+ importPath: /** @type {string} */ (importMatch[1]),
471
514
  };
472
515
  }
473
516
 
@@ -475,6 +518,9 @@ function extractIconInfo(filePath) {
475
518
  * Generate a minimal JS module for a built theme.
476
519
  * Includes the theme name, marker, and re-exports the icon registry.
477
520
  * All styling is in the CSS file.
521
+ * @param {any} themeDef
522
+ * @param {{exportName: string, importPath: string} | null} iconInfo
523
+ * @returns {string}
478
524
  */
479
525
  function generateBuiltModule(themeDef, iconInfo) {
480
526
  const iconImport = iconInfo
@@ -486,6 +532,7 @@ function generateBuiltModule(themeDef, iconInfo) {
486
532
  : '';
487
533
 
488
534
  // Resolve token values — tuples become light-dark() strings
535
+ /** @type {Record<string, unknown>} */
489
536
  const resolvedTokens = {};
490
537
  if (themeDef.tokens) {
491
538
  for (const [key, value] of Object.entries(themeDef.tokens)) {
@@ -516,6 +563,10 @@ ${iconReExport}`;
516
563
 
517
564
  /**
518
565
  * Generate TypeScript declarations for a built theme module.
566
+ * @param {any} themeDef
567
+ * @param {{exportName: string, importPath: string} | null} iconInfo
568
+ * @param {string | null} variantsFileName
569
+ * @returns {string}
519
570
  */
520
571
  function generateBuiltTypes(themeDef, iconInfo, variantsFileName) {
521
572
  const iconType = iconInfo
@@ -543,6 +594,7 @@ ${iconType}export declare const ${toIdentifier(themeDef.name)}Theme: DefinedThem
543
594
  /**
544
595
  * Known Astryx component names and their visual props.
545
596
  * Used to warn on typos in defineTheme component overrides.
597
+ * @type {Record<string, string[]>}
546
598
  */
547
599
  const KNOWN_COMPONENTS = {
548
600
  appshell: ['position'],
@@ -604,8 +656,11 @@ const KNOWN_COMPONENTS = {
604
656
  * Validate component overrides in a theme definition.
605
657
  * Warns on unknown component names and unknown prop names.
606
658
  * Returns array of warning strings.
659
+ * @param {{components?: Record<string, Record<string, unknown>>}} themeDef
660
+ * @returns {string[]}
607
661
  */
608
662
  function validateComponentOverrides(themeDef) {
663
+ /** @type {string[]} */
609
664
  const warnings = [];
610
665
  if (!themeDef.components) return warnings;
611
666
 
@@ -668,8 +723,11 @@ function validateComponentOverrides(themeDef) {
668
723
  * (e.g. borderRadius, padding) instead.
669
724
  *
670
725
  * Returns array of error strings.
726
+ * @param {{components?: Record<string, Record<string, Record<string, unknown>>>}} themeDef
727
+ * @returns {string[]}
671
728
  */
672
729
  function validatePrivateVars(themeDef) {
730
+ /** @type {string[]} */
673
731
  const errors = [];
674
732
  if (!themeDef.components) return errors;
675
733
 
@@ -706,14 +764,14 @@ function resolveCliBin() {
706
764
  * Resolves with the child's exit code; never rejects.
707
765
  *
708
766
  * @param {string} file - The theme file argument, as the user passed it.
709
- * @param {object} options - Parsed command options (only `out` is forwarded).
767
+ * @param {{out?: string}} options - Parsed command options (only `out` is forwarded).
710
768
  * @returns {Promise<number>}
711
769
  */
712
770
  function runThemeBuildOnceChild(file, options) {
713
771
  const cliBin = resolveCliBin();
714
772
  const args = [cliBin, 'theme', 'build', file];
715
773
  if (options.out) args.push('--out', options.out);
716
- return new Promise(resolve => {
774
+ return new Promise((/** @type {(code: number) => void} */ resolve) => {
717
775
  const child = spawn(process.execPath, args, {
718
776
  stdio: 'inherit',
719
777
  env: process.env,
@@ -732,7 +790,7 @@ function runThemeBuildOnceChild(file, options) {
732
790
  *
733
791
  * @param {string} file - The theme file argument, as the user passed it.
734
792
  * @param {string} filePath - Absolute path to the theme file.
735
- * @param {object} options - Parsed command options.
793
+ * @param {{out?: string}} options - Parsed command options.
736
794
  * @returns {Promise<void>} Resolves when the watcher is stopped (Ctrl-C).
737
795
  */
738
796
  async function runThemeBuildWatch(file, filePath, options) {
@@ -745,7 +803,8 @@ async function runThemeBuildWatch(file, filePath, options) {
745
803
 
746
804
  let building = false;
747
805
  let queued = false;
748
- let debounce = null;
806
+ /** @type {ReturnType<typeof setTimeout> | undefined} */
807
+ let debounce;
749
808
 
750
809
  const rebuild = async () => {
751
810
  if (building) {
@@ -776,7 +835,7 @@ async function runThemeBuildWatch(file, filePath, options) {
776
835
  debounce = setTimeout(rebuild, 100);
777
836
  });
778
837
 
779
- await new Promise(resolve => {
838
+ await new Promise((/** @type {(value?: void) => void} */ resolve) => {
780
839
  const stop = () => {
781
840
  clearTimeout(debounce);
782
841
  watcher.close();
@@ -788,11 +847,14 @@ async function runThemeBuildWatch(file, filePath, options) {
788
847
  });
789
848
  }
790
849
 
850
+ /**
851
+ * @param {import('commander').Command} program
852
+ */
791
853
  export function registerTheme(program) {
792
854
  const theme = program
793
855
  .command('theme')
794
856
  .description('Theme tools — build, export, and manage themes')
795
- .action((options, cmd) => {
857
+ .action((/** @type {unknown} */ options, /** @type {import('commander').Command} */ cmd) => {
796
858
  // Parent group has no default behaviour. If the user passed an
797
859
  // unknown subcommand (e.g. `astryx theme bogus`), Commander hands it to
798
860
  // us as a positional in cmd.args — exit 1 with a clear error.
@@ -816,7 +878,7 @@ export function registerTheme(program) {
816
878
  '-w, --watch',
817
879
  'Rebuild automatically when the theme file changes (Ctrl-C to stop)',
818
880
  )
819
- .action(async (file, options) => {
881
+ .action(async (/** @type {string} */ file, /** @type {{out?: string, watch?: boolean}} */ options) => {
820
882
  const filePath = path.resolve(process.cwd(), file);
821
883
  const json = program.opts().json || false;
822
884
 
@@ -846,7 +908,8 @@ export function registerTheme(program) {
846
908
  try {
847
909
  themeDef = await extractThemeDefinition(filePath);
848
910
  } catch (e) {
849
- cliError(e.message, {code: ERROR_CODES.ERR_THEME_LOAD});
911
+ const err = /** @type {Error} */ (e);
912
+ cliError(err.message, {code: ERROR_CODES.ERR_THEME_LOAD});
850
913
  return;
851
914
  }
852
915
 
@@ -992,7 +1055,10 @@ export function registerTheme(program) {
992
1055
  const augmentationSource = resolvedTheme || themeDef;
993
1056
  const variantDecl = await generateVariantDeclarationsAsync(augmentationSource);
994
1057
  const variantsFileName = variantDecl ? `${baseName}.variants.d.ts` : null;
995
- const variantDtsPath = variantDecl ? path.join(outDir, variantsFileName) : null;
1058
+ const variantDtsPath =
1059
+ variantDecl && variantsFileName
1060
+ ? path.join(outDir, variantsFileName)
1061
+ : null;
996
1062
  const variantContent = variantDecl
997
1063
  ? generatedHeader(sourceRelative, 'ts', buildCommand) + variantDecl
998
1064
  : null;
@@ -1013,11 +1079,12 @@ export function registerTheme(program) {
1013
1079
  {dest: jsPath, content: jsContent},
1014
1080
  {dest: dtsPath, content: dtsContent},
1015
1081
  ];
1016
- if (variantDtsPath) {
1082
+ if (variantDtsPath && variantContent) {
1017
1083
  writes.push({dest: variantDtsPath, content: variantContent});
1018
1084
  }
1019
1085
 
1020
1086
  fs.mkdirSync(outDir, {recursive: true});
1087
+ /** @type {Array<{tmp: string, dest: string}>} */
1021
1088
  const staged = [];
1022
1089
  try {
1023
1090
  for (const w of writes) {
@@ -1033,7 +1100,7 @@ export function registerTheme(program) {
1033
1100
  for (const s of staged) {
1034
1101
  try { fs.rmSync(s.tmp, {force: true}); } catch { /* best-effort */ }
1035
1102
  }
1036
- const msg = `Failed to write theme outputs: ${err.message}`;
1103
+ const msg = `Failed to write theme outputs: ${/** @type {Error} */ (err).message}`;
1037
1104
  cliError(msg, {code: ERROR_CODES.ERR_WRITE_FAILED});
1038
1105
  return;
1039
1106
  }
@@ -1044,7 +1111,7 @@ export function registerTheme(program) {
1044
1111
  humanLog(` ${size} KB`);
1045
1112
  humanLog(`✓ ${path.relative(process.cwd(), jsPath)}`);
1046
1113
  humanLog(`✓ ${path.relative(process.cwd(), dtsPath)}`);
1047
- if (variantDtsPath) {
1114
+ if (variantDtsPath && variantDecl) {
1048
1115
  const augCount = (variantDecl.match(/': true;/g) || []).length;
1049
1116
  humanLog(`✓ ${path.relative(process.cwd(), variantDtsPath)} (${augCount} type augmentations)`);
1050
1117
  }
@@ -1060,7 +1127,7 @@ export function registerTheme(program) {
1060
1127
  css: path.relative(process.cwd(), outPath),
1061
1128
  js: path.relative(process.cwd(), jsPath),
1062
1129
  dts: path.relative(process.cwd(), dtsPath),
1063
- ...(variantDecl ? {variantsDts: path.relative(process.cwd(), variantDtsPath)} : {}),
1130
+ ...(variantDecl && variantDtsPath ? {variantsDts: path.relative(process.cwd(), variantDtsPath)} : {}),
1064
1131
  },
1065
1132
  warnings: warningMessages,
1066
1133
  });
@@ -1107,15 +1174,21 @@ Or with a <link> tag:
1107
1174
  .description('List themes available to add')
1108
1175
  .action(async () => {
1109
1176
  const json = program.opts().json || false;
1177
+ /** @type {import('../../types/theme').ThemeListResponse} */
1110
1178
  let result;
1111
1179
  try {
1112
- result = await themeAdd(undefined, {list: true, cwd: process.cwd()});
1180
+ result = /** @type {import('../../types/theme').ThemeListResponse} */ (
1181
+ await themeAdd(undefined, {list: true, cwd: process.cwd()})
1182
+ );
1113
1183
  } catch (e) {
1114
- cliError(e.message, {suggestions: e.suggestions || [], code: e.code});
1184
+ const err = /** @type {import('../../api/error.mjs').AstryxError} */ (e);
1185
+ cliError(err.message, {suggestions: err.suggestions || [], code: err.code});
1115
1186
  return;
1116
1187
  }
1117
1188
 
1118
- if (json) return jsonOut(result.type, result.data);
1189
+ // theme.list is not registered in CLIResponseType (base.d.ts, owned by the
1190
+ // coordinator) — cast the discriminant until it is added there.
1191
+ if (json) return jsonOut(/** @type {any} */ (result.type), result.data);
1119
1192
 
1120
1193
  const themes = result.data;
1121
1194
  if (themes.length === 0) {
@@ -1137,26 +1210,32 @@ Or with a <link> tag:
1137
1210
  .description('Scaffold a theme into your project as editable source')
1138
1211
  .option('-f, --overwrite', 'Overwrite existing files without prompting')
1139
1212
  .option('--list', 'List available themes')
1140
- .action(async (slug, targetPath, options) => {
1213
+ .action(async (/** @type {string | undefined} */ slug, /** @type {string | undefined} */ targetPath, /** @type {{list?: boolean, overwrite?: boolean}} */ options) => {
1141
1214
  const json = program.opts().json || false;
1142
1215
 
1143
1216
  // The CLI is non-interactive: never prompt to confirm an overwrite.
1144
1217
  // Existing files require an explicit --overwrite; otherwise themeAdd's
1145
1218
  // ERR_FILE_EXISTS guard rejects the write.
1219
+ /** @type {import('../../types/theme').ThemeListResponse | import('../../types/theme').ThemeAddResponse} */
1146
1220
  let result;
1147
1221
  try {
1148
- result = await themeAdd(slug, {
1149
- list: options.list,
1150
- targetPath,
1151
- overwrite: options.overwrite,
1152
- cwd: process.cwd(),
1153
- });
1222
+ result = /** @type {import('../../types/theme').ThemeListResponse | import('../../types/theme').ThemeAddResponse} */ (
1223
+ await themeAdd(slug, {
1224
+ list: options.list,
1225
+ targetPath,
1226
+ overwrite: options.overwrite,
1227
+ cwd: process.cwd(),
1228
+ })
1229
+ );
1154
1230
  } catch (e) {
1155
- cliError(e.message, {suggestions: e.suggestions || [], code: e.code});
1231
+ const err = /** @type {import('../../api/error.mjs').AstryxError} */ (e);
1232
+ cliError(err.message, {suggestions: err.suggestions || [], code: err.code});
1156
1233
  return;
1157
1234
  }
1158
1235
 
1159
- if (json) return jsonOut(result.type, result.data);
1236
+ // theme.list/theme.add are not registered in CLIResponseType (base.d.ts,
1237
+ // owned by the coordinator) — cast the discriminant until they are added.
1238
+ if (json) return jsonOut(/** @type {any} */ (result.type), result.data);
1160
1239
 
1161
1240
  if (result.type === 'theme.list') {
1162
1241
  const themes = result.data;