@astryxdesign/cli 0.1.7 → 0.1.8-canary.07362a9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (389) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +115 -19
  3. package/{src/api → api/blog}/blog.mjs +42 -6
  4. package/{src/api → api/blog}/blog.test.mjs +2 -2
  5. package/api/build/build.mjs +92 -0
  6. package/api/build/build.test.mjs +92 -0
  7. package/{src/api → api/component}/component.mjs +49 -26
  8. package/{src/api → api/discover}/discover.mjs +55 -18
  9. package/{src/api → api/docs}/docs.mjs +47 -21
  10. package/{src/api → api/doctor}/doctor.mjs +13 -10
  11. package/{src/api → api}/error.mjs +2 -2
  12. package/{src/api → api/hook}/hook.mjs +11 -11
  13. package/{src/api → api}/index.mjs +16 -9
  14. package/{src/api → api/integration}/validate-integration.mjs +48 -15
  15. package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
  16. package/{src/api → api/layout}/layout.mjs +66 -17
  17. package/{src/api → api/layout}/layout.test.mjs +1 -1
  18. package/{src/api → api/search}/search.mjs +71 -12
  19. package/api/swizzle/swizzle.mjs +283 -0
  20. package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
  21. package/{src/api → api/template}/template-integration.test.mjs +2 -2
  22. package/{src/api → api/template}/template-suffix.test.mjs +3 -3
  23. package/{src/api → api/template}/template.mjs +96 -19
  24. package/{src/api → api/theme}/theme-add.mjs +35 -7
  25. package/{src → authoring}/codemod.mjs +6 -6
  26. package/{src → authoring}/config.test.mjs +1 -1
  27. package/{src → authoring}/doc.mjs +1 -1
  28. package/{src → authoring}/doc.test.mjs +1 -1
  29. package/{src → authoring}/template.mjs +1 -1
  30. package/bin/astryx.mjs +12 -10
  31. package/{src → cli}/commands/blog.mjs +48 -7
  32. package/{src → cli}/commands/build-theme.mjs +133 -115
  33. package/cli/commands/build.mjs +172 -0
  34. package/cli/commands/cli-postinstall.test.mjs +42 -0
  35. package/{src → cli}/commands/component/index.mjs +52 -25
  36. package/{src → cli}/commands/component-ownership.test.mjs +3 -3
  37. package/{src → cli}/commands/component-package.test.mjs +1 -1
  38. package/{src → cli}/commands/component-resolution.test.mjs +2 -2
  39. package/{src → cli}/commands/discover.mjs +23 -12
  40. package/{src → cli}/commands/docs.mjs +42 -10
  41. package/{src → cli}/commands/docs.test.mjs +1 -1
  42. package/{src → cli}/commands/doctor.mjs +3 -3
  43. package/{src → cli}/commands/doctor.test.mjs +2 -2
  44. package/{src → cli}/commands/ensure-core-built.mjs +3 -2
  45. package/{src → cli}/commands/external-showcase.test.mjs +1 -1
  46. package/{src → cli}/commands/hook/index.mjs +40 -17
  47. package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
  48. package/cli/commands/init.mjs +195 -0
  49. package/{src → cli}/commands/init.next-steps.test.mjs +1 -1
  50. package/cli/commands/interactive-guard.test.mjs +66 -0
  51. package/{src → cli}/commands/json-contract.test.mjs +2 -2
  52. package/{src → cli}/commands/layout.mjs +59 -19
  53. package/{src → cli}/commands/search.mjs +22 -15
  54. package/{src → cli}/commands/search.test.mjs +1 -1
  55. package/cli/commands/setup-nudge.test.mjs +108 -0
  56. package/cli/commands/swizzle.mjs +103 -0
  57. package/{src → cli}/commands/template.mjs +84 -53
  58. package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
  59. package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
  60. package/{src → cli}/commands/upgrade.mjs +291 -77
  61. package/cli/commands/upgrade.test.mjs +314 -0
  62. package/{src → cli}/commands/validate-integration.mjs +17 -37
  63. package/{src → cli}/index.mjs +55 -19
  64. package/{src/codemods → codemods}/__tests__/registry.test.mjs +1 -0
  65. package/{src/codemods → codemods}/ensure-jscodeshift.mjs +12 -28
  66. package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
  67. package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
  68. package/{src/codemods → codemods}/integration-runner.mjs +8 -3
  69. package/{src/codemods → codemods}/registry.mjs +4 -1
  70. package/{src/codemods → codemods}/run-codemod.mjs +18 -11
  71. package/{src/codemods → codemods}/runner.mjs +24 -14
  72. package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
  73. package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
  74. package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
  75. package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
  76. package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
  77. package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
  78. package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
  79. package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
  80. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
  81. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
  82. package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
  83. package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
  84. package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
  85. package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
  86. package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
  87. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
  88. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
  89. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
  90. package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
  91. package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
  92. package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
  93. package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
  94. package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
  95. package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
  96. package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
  97. package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
  98. package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
  99. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
  100. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
  101. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
  102. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
  103. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
  104. package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
  105. package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
  106. package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
  107. package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
  108. package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +42 -7
  109. package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +43 -0
  110. package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +117 -13
  111. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
  112. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
  113. package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +86 -15
  114. package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
  115. package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
  116. package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
  117. package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
  118. package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
  119. package/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +161 -0
  120. package/codemods/transforms/v0.1.8/index.mjs +19 -0
  121. package/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +239 -0
  122. package/docs/cli-integrations.doc.mjs +150 -0
  123. package/docs/elevation.doc.mjs +79 -1
  124. package/docs/getting-started.doc.mjs +9 -9
  125. package/docs/internationalization.doc.mjs +92 -46
  126. package/docs/migration.doc.mjs +18 -18
  127. package/docs/principles.doc.dense.mjs +1 -1
  128. package/docs/principles.doc.mjs +6 -6
  129. package/docs/principles.doc.zh.mjs +1 -1
  130. package/docs/styling-libraries.doc.mjs +3 -3
  131. package/docs/styling.doc.mjs +4 -4
  132. package/docs/theme.doc.dense.mjs +2 -2
  133. package/docs/theme.doc.mjs +7 -7
  134. package/docs/theme.doc.zh.mjs +1 -1
  135. package/docs/tokens.doc.mjs +1 -1
  136. package/docs/working-with-ai.doc.mjs +19 -19
  137. package/{src/commands → lib/agent-docs}/agent-docs.mjs +164 -29
  138. package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
  139. package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +123 -10
  140. package/{src/lib → lib}/cli-error.mjs +2 -2
  141. package/{src/lib → lib}/component-discovery.mjs +44 -2
  142. package/{src/lib → lib}/component-format.mjs +67 -25
  143. package/{src/lib → lib}/component-loader.mjs +27 -13
  144. package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
  145. package/{src/lib → lib}/error-codes.test.mjs +1 -1
  146. package/{src/lib → lib}/hook-discovery.mjs +14 -1
  147. package/{src/lib → lib}/hook-format.mjs +29 -5
  148. package/{src/lib → lib}/integration-warnings.mjs +2 -2
  149. package/{src/lib → lib}/integrations.mjs +20 -0
  150. package/{src/lib → lib}/integrations.test.mjs +1 -1
  151. package/{src/lib → lib}/json-contract.test.mjs +1 -1
  152. package/{src/lib → lib}/json-shim.mjs +11 -6
  153. package/{src/lib → lib}/json-shim.test.mjs +1 -1
  154. package/{src/lib → lib}/json.mjs +3 -3
  155. package/{src/lib → lib}/levenshtein.mjs +6 -0
  156. package/{src/lib → lib}/manifest.mjs +7 -5
  157. package/{src/lib → lib}/manifest.test.mjs +2 -2
  158. package/{src/lib → lib}/module-loader.mjs +1 -0
  159. package/{src/lib → lib}/package-scanner.mjs +47 -0
  160. package/{src/lib → lib}/project.mjs +48 -18
  161. package/{src/lib → lib}/project.test.mjs +1 -1
  162. package/{src/lib → lib}/resolve-theme.mjs +5 -0
  163. package/{src/lib → lib}/string-utils.mjs +15 -0
  164. package/lib/term-log.mjs +57 -0
  165. package/{src/lib → lib}/xle/browser.mjs +18 -8
  166. package/{src/lib → lib}/xle/expand.mjs +155 -22
  167. package/{src/lib → lib}/xle/parse.mjs +119 -13
  168. package/{src/lib → lib}/xle/print.mjs +54 -14
  169. package/{src/lib → lib}/xle/registry-core.mjs +28 -3
  170. package/{src/lib → lib}/xle/registry.mjs +9 -4
  171. package/{src/lib → lib}/xle/splice.mjs +13 -2
  172. package/{src/lib → lib}/xle/validate.mjs +95 -14
  173. package/lib/xle/xle-ast.d.ts +214 -0
  174. package/package.json +37 -28
  175. package/scripts/postinstall.mjs +74 -0
  176. package/templates/blocks/components/Avatar/AvatarFallbackChain.tsx +4 -4
  177. package/templates/blocks/components/Avatar/AvatarGroup.tsx +2 -2
  178. package/templates/blocks/components/Avatar/AvatarInitialsFallback.tsx +1 -1
  179. package/templates/blocks/components/Avatar/AvatarShowcase.tsx +5 -5
  180. package/templates/blocks/components/Avatar/AvatarUserCard.tsx +1 -1
  181. package/templates/blocks/components/Avatar/AvatarWithImage.tsx +4 -4
  182. package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +3 -3
  183. package/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.tsx +2 -2
  184. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowCustomText.tsx +1 -1
  185. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowDefault.tsx +1 -1
  186. package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowShowcase.tsx +2 -2
  187. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotShowcase.tsx +3 -3
  188. package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +3 -3
  189. package/templates/blocks/components/Banner/BannerFloating.doc.mjs +14 -0
  190. package/templates/blocks/components/Banner/BannerFloating.tsx +16 -0
  191. package/templates/blocks/components/Button/ButtonFloating.doc.mjs +14 -0
  192. package/templates/blocks/components/Button/ButtonFloating.tsx +37 -0
  193. package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.doc.mjs +14 -0
  194. package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.tsx +23 -0
  195. package/templates/blocks/components/Card/CardElevations.doc.mjs +14 -0
  196. package/templates/blocks/components/Card/CardElevations.tsx +32 -0
  197. package/templates/blocks/components/Card/ClickableCardElevated.doc.mjs +14 -0
  198. package/templates/blocks/components/Card/ClickableCardElevated.tsx +21 -0
  199. package/templates/blocks/components/Card/SelectableCardElevated.doc.mjs +14 -0
  200. package/templates/blocks/components/Card/SelectableCardElevated.tsx +37 -0
  201. package/templates/blocks/components/Carousel/CarouselSnap.tsx +1 -1
  202. package/templates/blocks/components/ChatComposer/ChatComposerFlat.doc.mjs +14 -0
  203. package/templates/blocks/components/ChatComposer/ChatComposerFlat.tsx +75 -0
  204. package/templates/blocks/components/ChatMessage/ChatMessageAvatarName.tsx +2 -2
  205. package/templates/blocks/components/ChatMessage/ChatMessageMultiBubble.tsx +1 -1
  206. package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleGrouping.tsx +1 -1
  207. package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleMetadata.tsx +1 -1
  208. package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +5 -9
  209. package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -1
  210. package/templates/blocks/components/CodeBlock/CodeBlockTerminal.tsx +1 -1
  211. package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -1
  212. package/templates/blocks/components/IconButton/IconButtonFloating.doc.mjs +14 -0
  213. package/templates/blocks/components/IconButton/IconButtonFloating.tsx +37 -0
  214. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
  215. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
  216. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
  217. package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
  218. package/templates/blocks/components/Item/ItemWithMedia.tsx +2 -2
  219. package/templates/blocks/components/ListItem/ListItemWithMedia.tsx +2 -2
  220. package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.doc.mjs +14 -0
  221. package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.tsx +39 -0
  222. package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.doc.mjs +14 -0
  223. package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.tsx +44 -0
  224. package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -6
  225. package/templates/blocks/components/Stack/StackFillItem.tsx +2 -6
  226. package/templates/blocks/components/TabList/TabListTabsWithActions.doc.mjs +1 -1
  227. package/templates/blocks/components/TabList/TabListTabsWithActions.tsx +2 -7
  228. package/templates/blocks/components/Table/TableRowStatusTable.doc.mjs +14 -0
  229. package/templates/blocks/components/Table/TableRowStatusTable.tsx +59 -0
  230. package/templates/blocks/components/Thumbnail/ThumbnailDisabled.tsx +6 -1
  231. package/templates/blocks/components/Thumbnail/ThumbnailGallery.tsx +1 -0
  232. package/templates/blocks/components/Thumbnail/ThumbnailRemovable.tsx +1 -0
  233. package/templates/blocks/components/TypeaheadItem/TypeaheadItemShowcase.tsx +1 -1
  234. package/templates/pages/ai-chat/page.tsx +4 -4
  235. package/templates/pages/dashboard-portfolio/page.tsx +3 -11
  236. package/templates/pages/detail-page/page.tsx +5 -12
  237. package/templates/pages/documentation-design/page.tsx +1 -1
  238. package/templates/pages/messaging-shell/page.tsx +6 -8
  239. package/templates/pages/table-grouped/page.tsx +9 -14
  240. package/templates/pages/table-page/page.tsx +7 -9
  241. package/templates/pages/table-page-heatmap-status/page.tsx +5 -13
  242. package/{src/types → types}/api.contract.assert.ts +17 -8
  243. package/{src/types → types}/api.d.ts +110 -9
  244. package/{src/types → types}/base.d.ts +40 -4
  245. package/types/build.d.ts +53 -0
  246. package/types/codemod.d.ts +166 -0
  247. package/{src/types → types}/component.d.ts +1 -1
  248. package/{src/types → types}/discover.d.ts +1 -1
  249. package/{src/types → types}/docs.d.ts +1 -4
  250. package/{src/types → types}/hook.d.ts +1 -1
  251. package/{src/types → types}/index.d.ts +1 -0
  252. package/types/jscodeshift.d.ts +19 -0
  253. package/types/layout.d.ts +74 -0
  254. package/{src/types → types}/swizzle.d.ts +4 -0
  255. package/{src/types → types}/template-api.d.ts +4 -1
  256. package/types/theme.d.ts +53 -0
  257. package/types/upgrade.d.ts +108 -0
  258. package/utils/package-manager.mjs +178 -0
  259. package/utils/package-manager.test.mjs +220 -0
  260. package/{src/utils → utils}/path-safety.mjs +0 -18
  261. package/{src/utils → utils}/paths.mjs +4 -1
  262. package/{src/utils → utils}/update-check.mjs +5 -4
  263. package/{src/utils → utils}/update-check.test.mjs +3 -3
  264. package/docs/integration-authoring.md +0 -105
  265. package/src/commands/build.mjs +0 -196
  266. package/src/commands/init.mjs +0 -288
  267. package/src/commands/interactive-guard.test.mjs +0 -69
  268. package/src/commands/swizzle.mjs +0 -440
  269. package/src/commands/upgrade.test.mjs +0 -160
  270. package/src/types/codemod.d.ts +0 -81
  271. package/src/types/theme.d.ts +0 -23
  272. package/src/types/upgrade.d.ts +0 -64
  273. package/src/utils/interactive.mjs +0 -76
  274. package/src/utils/interactive.test.mjs +0 -70
  275. package/src/utils/package-manager.mjs +0 -74
  276. package/src/utils/package-manager.test.mjs +0 -113
  277. /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
  278. /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
  279. /package/{src/api → api/template}/template.test.mjs +0 -0
  280. /package/{src → authoring}/codemod.test.mjs +0 -0
  281. /package/{src → authoring}/config.mjs +0 -0
  282. /package/{src → authoring}/integration.mjs +0 -0
  283. /package/{src → authoring}/template.test.mjs +0 -0
  284. /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
  285. /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
  286. /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
  287. /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
  288. /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
  289. /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
  290. /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
  291. /package/{src → cli}/commands/component.test.mjs +0 -0
  292. /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
  293. /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
  294. /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
  295. /package/{src → cli}/commands/template.test.mjs +0 -0
  296. /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
  297. /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
  298. /package/{src → cli}/update-hint-commands.test.mjs +0 -0
  299. /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
  300. /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
  301. /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
  302. /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
  303. /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
  304. /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
  305. /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
  306. /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
  307. /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
  308. /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
  309. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
  310. /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
  311. /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
  312. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
  313. /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
  314. /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
  315. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
  316. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
  317. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
  318. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
  319. /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
  320. /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
  321. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
  322. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
  323. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
  324. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
  325. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
  326. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
  327. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
  328. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
  329. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
  330. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
  331. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
  332. /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
  333. /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
  334. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
  335. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
  336. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
  337. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
  338. /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
  339. /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
  340. /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
  341. /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
  342. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
  343. /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
  344. /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
  345. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
  346. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
  347. /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
  348. /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
  349. /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
  350. /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
  351. /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
  352. /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
  353. /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
  354. /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
  355. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
  356. /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
  357. /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
  358. /package/{src/lib → lib}/cli-error.test.mjs +0 -0
  359. /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
  360. /package/{src/lib → lib}/component-format.test.mjs +0 -0
  361. /package/{src/lib → lib}/component-loader.test.mjs +0 -0
  362. /package/{src/lib → lib}/config-cache.mjs +0 -0
  363. /package/{src/lib → lib}/config-cache.test.mjs +0 -0
  364. /package/{src/lib → lib}/config-schema.mjs +0 -0
  365. /package/{src/lib → lib}/error-codes.mjs +0 -0
  366. /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
  367. /package/{src/lib → lib}/module-loader.test.mjs +0 -0
  368. /package/{src/lib → lib}/node-version.mjs +0 -0
  369. /package/{src/lib → lib}/node-version.test.mjs +0 -0
  370. /package/{src/lib → lib}/parse.mjs +0 -0
  371. /package/{src/lib → lib}/site.mjs +0 -0
  372. /package/{src/lib → lib}/xle/browser.d.ts +0 -0
  373. /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
  374. /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
  375. /package/{src/schemas → schemas}/template-schema.mjs +0 -0
  376. /package/{src/types → types}/config.d.ts +0 -0
  377. /package/{src/types → types}/doc.d.ts +0 -0
  378. /package/{src/types → types}/doctor.d.ts +0 -0
  379. /package/{src/types → types}/error-codes.d.ts +0 -0
  380. /package/{src/types → types}/integration.d.ts +0 -0
  381. /package/{src/types → types}/manifest.d.ts +0 -0
  382. /package/{src/types → types}/search.d.ts +0 -0
  383. /package/{src/types → types}/template.d.ts +0 -0
  384. /package/{src/types → types}/validate-integration.d.ts +0 -0
  385. /package/{src/utils → utils}/github.mjs +0 -0
  386. /package/{src/utils → utils}/path-safety.test.mjs +0 -0
  387. /package/{src/utils → utils}/paths.test.mjs +0 -0
  388. /package/{src/utils → utils}/semver.mjs +0 -0
  389. /package/{src/utils → utils}/semver.test.mjs +0 -0
@@ -148,7 +148,7 @@ function App() {
148
148
  type: 'code',
149
149
  lang: 'bash',
150
150
  label: 'Scaffold with CLI',
151
- code: 'npx astryx theme',
151
+ code: 'astryx theme',
152
152
  },
153
153
  ],
154
154
  },
@@ -287,7 +287,7 @@ const brandTheme = defineTheme({
287
287
  },
288
288
  {
289
289
  type: 'prose',
290
- text: 'Run `npx astryx component <Name>` to see a component\'s theming targets, public CSS variables, and which standard CSS properties are supported.',
290
+ text: 'Run `astryx component <Name>` to see a component\'s theming targets, public CSS variables, and which standard CSS properties are supported.',
291
291
  },
292
292
  {
293
293
  type: 'list',
@@ -361,13 +361,13 @@ const brandTheme = defineTheme({
361
361
  content: [
362
362
  {
363
363
  type: 'prose',
364
- text: '`npx astryx theme build` compiles a defineTheme file into production-ready artifacts. Recommended for SSR apps (Next.js, Remix) where styles must be present on first paint.',
364
+ text: '`astryx theme build` compiles a defineTheme file into production-ready artifacts. Recommended for SSR apps (Next.js, Remix) where styles must be present on first paint.',
365
365
  },
366
366
  {
367
367
  type: 'code',
368
368
  lang: 'bash',
369
369
  label: 'Build a theme',
370
- code: 'npx astryx theme build ./src/themes/ocean.ts',
370
+ code: 'astryx theme build ./src/themes/ocean.ts',
371
371
  },
372
372
  {
373
373
  type: 'prose',
@@ -432,7 +432,7 @@ import './themes/ocean.css';
432
432
  [
433
433
  'Import (custom theme)',
434
434
  'defineTheme() directly',
435
- "Built .js + .css from `npx astryx theme build`",
435
+ "Built .js + .css from `astryx theme build`",
436
436
  ],
437
437
  [
438
438
  'How it works',
@@ -462,7 +462,7 @@ import './themes/ocean.css';
462
462
  items: [
463
463
  'Use the /built subpath + theme.css for production SSR apps.',
464
464
  'Use runtime themes during development for fast iteration.',
465
- 'Run `npx astryx theme build` for custom themes to get the built artifacts.',
465
+ 'Run `astryx theme build` for custom themes to get the built artifacts.',
466
466
  ],
467
467
  },
468
468
  {
@@ -610,7 +610,7 @@ function ChartConfig() {
610
610
  },
611
611
  {
612
612
  type: 'prose',
613
- text: 'See `npx astryx docs styling-libraries` for styling-library interop and `npx astryx docs tokens` for the full token reference.',
613
+ text: 'See `astryx docs styling-libraries` for styling-library interop and `astryx docs tokens` for the full token reference.',
614
614
  },
615
615
  ],
616
616
  },
@@ -10,7 +10,7 @@ export const docsZh = {
10
10
  { section: 'Theme Props', title: 'Theme 属性', content: [null] },
11
11
  { section: 'Creating a Custom Theme', title: '创建自定义主题', content: [{ type: 'prose', text: '使用 CLI 向导(推荐)或手动 defineTheme。只覆盖与默认值不同的令牌。' }, null] },
12
12
  { section: 'defineTheme', title: 'defineTheme', content: [{ type: 'prose', text: '支持比例配置(typography、radius、motion)+ 显式令牌覆盖 + 组件覆盖。' }, null, null] },
13
- { section: 'Building Themes for Production', title: '生产构建', content: [{ type: 'prose', text: 'npx astryx theme build 将 defineTheme 编译为静态 CSS。输出 .css + .js(__built:true)+ .d.ts。' }, null, null, null, null] },
13
+ { section: 'Building Themes for Production', title: '生产构建', content: [{ type: 'prose', text: 'astryx theme build 将 defineTheme 编译为静态 CSS。输出 .css + .js(__built:true)+ .d.ts。' }, null, null, null, null] },
14
14
  { section: 'Runtime vs Built Themes', title: '运行时 vs 构建', content: [{ type: 'prose', text: '运行时:useInsertionEffect 在客户端注入样式。构建:静态 CSS 在首次渲染时就存在。SSR 应用请使用 /built + theme.css。' }, null, null, null] },
15
15
  { section: 'Light/Dark Mode', title: '亮/暗模式', content: [{ type: 'prose', text: "令牌值使用 [light, dark] 元组实现自动模式切换。Theme 上 mode='system'(默认)跟随系统偏好。" }, null, null] },
16
16
  { section: 'Nesting Themes', title: '嵌套主题', content: [{ type: 'prose', text: '将不同部分包裹在独立的 <Theme> 提供者中。' }, null] },
@@ -1068,7 +1068,7 @@ export const docs = {
1068
1068
  },
1069
1069
  {
1070
1070
  "type": "prose",
1071
- "text": "See `npx astryx docs styling` for how to apply tokens via xstyle, className, and compound component patterns. See `npx astryx docs theme` for overriding tokens with defineTheme."
1071
+ "text": "See `astryx docs styling` for how to apply tokens via xstyle, className, and compound component patterns. See `astryx docs theme` for overriding tokens with defineTheme."
1072
1072
  }
1073
1073
  ]
1074
1074
  }
@@ -34,7 +34,7 @@ export const docs = {
34
34
  type: 'code',
35
35
  lang: 'text',
36
36
  label: 'Paste this into your AI',
37
- code: 'Install @astryxdesign/cli and run `npx astryx init --features agents` to set up your Astryx context. Read the generated file.',
37
+ code: 'Install @astryxdesign/cli and run `npx @astryxdesign/cli init --features agents` to set up your Astryx context. Read the generated file.',
38
38
  },
39
39
  {
40
40
  type: 'prose',
@@ -42,15 +42,15 @@ export const docs = {
42
42
  },
43
43
  {
44
44
  type: 'prose',
45
- text: 'If you prefer to target a specific file format:',
45
+ text: 'By default this creates `AGENTS.md` (the tool-agnostic standard most agents read). To target a specific tool\'s file instead:',
46
46
  },
47
47
  {
48
48
  type: 'code',
49
49
  lang: 'bash',
50
50
  label: 'Manual options',
51
- code: `npx astryx init --features agents --agent claude # CLAUDE.md
52
- npx astryx init --features agents --agent cursor # .cursorrules
53
- npx astryx init --features agents --agent codex # AGENTS.md (Copilot, Codex, etc.)`,
51
+ code: `npx @astryxdesign/cli init --features agents --agent claude # .claude/CLAUDE.md
52
+ npx @astryxdesign/cli init --features agents --agent cursor # .cursorrules
53
+ npx @astryxdesign/cli init --features agents --agent codex # AGENTS.md (Copilot, Codex, etc.)`,
54
54
  },
55
55
  ],
56
56
  },
@@ -65,9 +65,9 @@ npx astryx init --features agents --agent codex # AGENTS.md (Copilot, Codex,
65
65
  type: 'list',
66
66
  style: 'ordered',
67
67
  items: [
68
- '`npx astryx template --list`: find a related page pattern to use as reference',
69
- '`npx astryx template <name> --skeleton`: study the layout structure',
70
- '`npx astryx component <Name>`: read props and examples for every component used',
68
+ '`astryx template --list`: find a related page pattern to use as reference',
69
+ '`astryx template <name> --skeleton`: study the layout structure',
70
+ '`astryx component <Name>`: read props and examples for every component used',
71
71
  ],
72
72
  },
73
73
  {
@@ -88,7 +88,7 @@ npx astryx init --features agents --agent codex # AGENTS.md (Copilot, Codex,
88
88
  lang: 'bash',
89
89
  label: 'Install as a Cursor user rule',
90
90
  code: `mkdir -p ~/.cursor/rules
91
- npx astryx init --features agents --agent-docs-path ~/.cursor/rules/xds.mdc`,
91
+ npx @astryxdesign/cli init --features agents --agent-docs-path ~/.cursor/rules/xds.mdc`,
92
92
  },
93
93
  ],
94
94
  },
@@ -109,12 +109,12 @@ npx astryx init --features agents --agent-docs-path ~/.cursor/rules/xds.mdc`,
109
109
  2. How do you make an Dialog non-dismissible?
110
110
  3. What prop does Selector use for its items?
111
111
 
112
- If you don't know all three, run \`npx astryx init --features agents\` to generate agent docs, then read the generated file.`,
112
+ If you don't know all three, run \`npx @astryxdesign/cli init --features agents\` to generate agent docs, then read the generated file.`,
113
113
  },
114
114
  ],
115
115
  },
116
116
  {
117
- title: 'The npx astryx Pattern',
117
+ title: 'The astryx Pattern',
118
118
  content: [
119
119
  {
120
120
  type: 'prose',
@@ -130,16 +130,16 @@ If you don't know all three, run \`npx astryx init --features agents\` to genera
130
130
  },
131
131
  {
132
132
  type: 'prose',
133
- text: 'With this alias, agents use `npx astryx component --list` instead of guessing the binary path. The `--` separator is standard npm convention for passing flags to scripts.',
133
+ text: 'With this alias, agents use `astryx component --list` instead of guessing the binary path. The `--` separator is standard npm convention for passing flags to scripts.',
134
134
  },
135
135
  {
136
136
  type: 'code',
137
137
  lang: 'bash',
138
138
  label: 'Reliable CLI invocation',
139
- code: `npx astryx component --list
140
- npx astryx component Dialog --dense
141
- npx astryx docs styling --dense
142
- npx astryx docs tokens --dense`,
139
+ code: `astryx component --list
140
+ astryx component Dialog --dense
141
+ astryx docs styling --dense
142
+ astryx docs tokens --dense`,
143
143
  },
144
144
  ],
145
145
  },
@@ -154,9 +154,9 @@ npx astryx docs tokens --dense`,
154
154
  type: 'code',
155
155
  lang: 'bash',
156
156
  label: 'Dense output for pasting into AI conversations',
157
- code: `npx astryx component Dialog --dense
158
- npx astryx docs styling --dense
159
- npx astryx docs tokens --dense`,
157
+ code: `astryx component Dialog --dense
158
+ astryx docs styling --dense
159
+ astryx docs tokens --dense`,
160
160
  },
161
161
  ],
162
162
  },
@@ -12,7 +12,7 @@
12
12
  * - Hermes Agent: .hermes.md or HERMES.md (existing), else AGENTS.md
13
13
  *
14
14
  * Auto-detect: discovers existing files and updates them in place.
15
- * Default (no existing files): creates .claude/CLAUDE.md.
15
+ * Default (no existing files): creates AGENTS.md (the tool-agnostic standard).
16
16
  *
17
17
  * --agent <tool>: target a specific tool preset (claude, cursor, codex, hermes, all)
18
18
  * --agent-docs-path <path>: explicit file path(s)
@@ -20,17 +20,20 @@
20
20
 
21
21
  import * as fs from 'node:fs';
22
22
  import * as path from 'node:path';
23
- import {findCoreDir, CLI_ROOT} from '../utils/paths.mjs';
24
- import {assertWithin, PathSafetyError} from '../utils/path-safety.mjs';
25
- import {getRunPrefix} from '../utils/package-manager.mjs';
26
- import {discoverComponents} from '../lib/component-discovery.mjs';
27
- import {humanLog} from '../lib/json.mjs';
28
- import {cliError} from '../lib/cli-error.mjs';
29
- import {ERROR_CODES} from '../lib/error-codes.mjs';
23
+ import {findCoreDir, CLI_ROOT} from '../../utils/paths.mjs';
24
+ import {assertWithin, PathSafetyError} from '../../utils/path-safety.mjs';
25
+ import {getCliInvocation} from '../../utils/package-manager.mjs';
26
+ import {discoverComponents} from '../../lib/component-discovery.mjs';
27
+ import {humanLog} from '../../lib/json.mjs';
28
+ import {cliError} from '../../lib/cli-error.mjs';
29
+ import {ERROR_CODES} from '../../lib/error-codes.mjs';
30
30
 
31
31
  const AGENTS_MD = 'AGENTS.md';
32
32
  const CLAUDE_MD = 'CLAUDE.md';
33
33
  const CLAUDE_DIR_MD = '.claude/CLAUDE.md'; // cross-platform literal
34
+ const CURSOR_RULES = '.cursorrules';
35
+ const HERMES_DOT_MD = '.hermes.md';
36
+ const HERMES_MD = 'HERMES.md';
34
37
 
35
38
 
36
39
  const MARKER_START = '<!-- ASTRYX:START -->';
@@ -45,20 +48,135 @@ const LEGACY_MARKER_END = '<!-- XDS:END -->';
45
48
  */
46
49
  const AGENT_PRESETS = {
47
50
  claude: [CLAUDE_MD, CLAUDE_DIR_MD],
48
- cursor: ['.cursorrules', AGENTS_MD],
51
+ cursor: [CURSOR_RULES, AGENTS_MD],
49
52
  codex: [AGENTS_MD],
50
- hermes: ['.hermes.md', 'HERMES.md', AGENTS_MD],
53
+ hermes: [HERMES_DOT_MD, HERMES_MD, AGENTS_MD],
51
54
  };
52
55
 
53
56
  /**
54
- * Find all existing agent doc files in a directory.
55
- * Searches all known locations (AGENTS.md, CLAUDE.md, .claude/CLAUDE.md, .cursorrules).
57
+ * The canonical set of EVERY location an --agent preset (or the default) can
58
+ * write the Astryx block. SINGLE SOURCE OF TRUTH: discovery, removal, and the
59
+ * `isAstryxInitialized` predicate all derive from this list, so "where init
60
+ * writes" and "where we look" can never drift. (Explicit --agent-docs-path
61
+ * targets are user-chosen and not enumerable here.)
62
+ */
63
+ const AGENT_DOC_PATHS = [
64
+ AGENTS_MD, // Codex / ChatGPT / generic
65
+ CLAUDE_MD, // Claude Code (root)
66
+ CLAUDE_DIR_MD, // Claude Code (.claude/CLAUDE.md)
67
+ CURSOR_RULES, // Cursor
68
+ HERMES_DOT_MD, // Hermes
69
+ HERMES_MD, // Hermes
70
+ ];
71
+
72
+ /**
73
+ * Find all existing agent doc files in a directory, across EVERY location any
74
+ * preset can write (see {@link AGENT_DOC_PATHS}: AGENTS.md, CLAUDE.md,
75
+ * .claude/CLAUDE.md, .cursorrules, .hermes.md, HERMES.md).
56
76
  * @param {string} targetDir
57
77
  * @returns {string[]} Relative paths of existing agent doc files
58
78
  */
59
79
  export function discoverAgentDocs(targetDir) {
60
- const allPaths = [AGENTS_MD, CLAUDE_MD, CLAUDE_DIR_MD, '.cursorrules'];
61
- return allPaths.filter(p => fs.existsSync(path.join(targetDir, p)));
80
+ return AGENT_DOC_PATHS.filter(p => fs.existsSync(path.join(targetDir, p)));
81
+ }
82
+
83
+ /**
84
+ * Single source of truth for "is Astryx set up in this project?" — true when any
85
+ * agent-doc file already carries the Astryx marker, i.e. `init` / `agent-docs`
86
+ * has run. Reused by the init & upgrade commands, the per-command setup nudge
87
+ * (enforcement layer 3), and the cli postinstall nudge (layer 2). Core's
88
+ * postinstall (separate package, layer 1) mirrors the same marker contract.
89
+ *
90
+ * @param {string} [targetDir=process.cwd()]
91
+ * @returns {boolean}
92
+ */
93
+ export function isAstryxInitialized(targetDir = process.cwd()) {
94
+ for (const rel of discoverAgentDocs(targetDir)) {
95
+ try {
96
+ const content = fs.readFileSync(path.join(targetDir, rel), 'utf-8');
97
+ if (content.includes(MARKER_START) || content.includes(LEGACY_MARKER_START)) {
98
+ return true;
99
+ }
100
+ } catch {
101
+ // Unreadable file — ignore and keep checking the others.
102
+ }
103
+ }
104
+ return false;
105
+ }
106
+
107
+ /**
108
+ * Parse the Astryx version a managed block was generated for, from its header
109
+ * line ("Astryx v1.2.3 · N components"). Returns null when the block predates
110
+ * the versioned header (e.g. a legacy XDS block) or has no header at all.
111
+ *
112
+ * @param {string} content File contents, or just the block text.
113
+ * @returns {string|null}
114
+ */
115
+ export function parseBlockVersion(content) {
116
+ const match = /Astryx v(\d+\.\d+\.\d+[^\s·]*)/.exec(content ?? '');
117
+ return match ? match[1] : null;
118
+ }
119
+
120
+ /**
121
+ * Read-only staleness assessment of the managed agent-docs block(s) against the
122
+ * installed core version. This is the detection half of the `astryx upgrade`
123
+ * agent-docs refresh: it never writes, so `upgrade` can run it on EVERY path —
124
+ * including the up-to-date / no-codemods short-circuits — and decide whether to
125
+ * rewrite a stale block, nudge an uninitialized repo, or stay silent.
126
+ *
127
+ * A managed block is:
128
+ * - `stale` — it carries a legacy XDS marker, has no parseable version, or
129
+ * records a version other than the installed one.
130
+ * - `current` — every managed block already matches the installed version.
131
+ * And the project is `missing` when no managed block exists anywhere (the repo
132
+ * has agent-doc files without our markers, or none at all — i.e. never `init`ed).
133
+ *
134
+ * @param {string} targetDir
135
+ * @param {string} [installedVersion] Defaults to the installed core version.
136
+ * @returns {{
137
+ * installedVersion: string,
138
+ * status: 'missing' | 'stale' | 'current',
139
+ * files: Array<{path: string, blockVersion: string|null, legacy: boolean, stale: boolean}>,
140
+ * staleFiles: string[],
141
+ * blockVersions: string[],
142
+ * }}
143
+ */
144
+ export function inspectAgentDocs(targetDir, installedVersion) {
145
+ const version = installedVersion ?? getXdsVersion(findCoreDir(targetDir));
146
+ /** @type {Array<{path: string, blockVersion: string|null, legacy: boolean, stale: boolean}>} */
147
+ const files = [];
148
+
149
+ for (const rel of discoverAgentDocs(targetDir)) {
150
+ /** @type {string} */
151
+ let content;
152
+ try {
153
+ content = fs.readFileSync(path.join(targetDir, rel), 'utf-8');
154
+ } catch {
155
+ continue; // Unreadable — treat as absent.
156
+ }
157
+ const hasNew = content.includes(MARKER_START);
158
+ const hasLegacy = content.includes(LEGACY_MARKER_START);
159
+ if (!hasNew && !hasLegacy) continue; // Not a block we manage.
160
+
161
+ const legacy = !hasNew && hasLegacy;
162
+ const blockVersion = parseBlockVersion(content);
163
+ const stale = legacy || blockVersion == null || blockVersion !== version;
164
+ files.push({path: rel, blockVersion, legacy, stale});
165
+ }
166
+
167
+ const staleEntries = files.filter(f => f.stale);
168
+ const staleFiles = staleEntries.map(f => f.path);
169
+ const blockVersions = [
170
+ ...new Set(staleEntries.map(f => f.blockVersion).filter(/** @returns {v is string} */ (v) => v != null)),
171
+ ];
172
+
173
+ /** @type {'missing' | 'stale' | 'current'} */
174
+ let status;
175
+ if (files.length === 0) status = 'missing';
176
+ else if (staleFiles.length > 0) status = 'stale';
177
+ else status = 'current';
178
+
179
+ return {installedVersion: version, status, files, staleFiles, blockVersions};
62
180
  }
63
181
 
64
182
  /**
@@ -80,7 +198,7 @@ export function resolveAgentPaths(targetDir, agent) {
80
198
  return {inject: [], create: [AGENTS_MD, CLAUDE_DIR_MD]};
81
199
  }
82
200
 
83
- const searchPaths = AGENT_PRESETS[agent];
201
+ const searchPaths = /** @type {Record<string, string[]>} */ (AGENT_PRESETS)[agent];
84
202
  if (!searchPaths) {
85
203
  return {inject: [], create: [AGENTS_MD]};
86
204
  }
@@ -143,9 +261,13 @@ export function detectStylingSystem(targetDir) {
143
261
  * `stylingSystem` tailors the custom-styling guidance to what the project has
144
262
  * configured (see {@link detectStylingSystem}) so the agent never reaches for a
145
263
  * styling path that isn't compiled here.
264
+ *
265
+ * @param {string} version
266
+ * @param {{coreDir?: string|null, invocation?: string, stylingSystem?: 'stylex'|'tailwind'|'css', zh?: boolean, lang?: string}} [options]
267
+ * @returns {string}
146
268
  */
147
- export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPrefix(), stylingSystem = 'css'} = {}) {
148
- const run = `${runPrefix} astryx`;
269
+ export function generateCompressedIndex(version, {coreDir, invocation = getCliInvocation(), stylingSystem = 'css'} = {}) {
270
+ const run = invocation;
149
271
  const lines = [MARKER_START];
150
272
 
151
273
  // Component count from live discovery
@@ -222,7 +344,7 @@ export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPre
222
344
  if (fs.existsSync(docsDir)) {
223
345
  const topics = fs.readdirSync(docsDir)
224
346
  .map(f => f.match(/^(\w+)\.doc\.mjs$/))
225
- .filter(Boolean)
347
+ .filter(/** @returns {m is RegExpMatchArray} */ (m) => m != null)
226
348
  .map(m => m[1])
227
349
  .sort();
228
350
  if (topics.length > 0) lines.push(` docs <topic> ${topics.join(', ')}`);
@@ -236,6 +358,8 @@ export function generateCompressedIndex(version, {coreDir, runPrefix = getRunPre
236
358
 
237
359
  /**
238
360
  * Get Astryx version from core package.
361
+ * @param {string|null} coreDir
362
+ * @returns {string}
239
363
  */
240
364
  export function getXdsVersion(coreDir) {
241
365
  if (coreDir) {
@@ -304,6 +428,9 @@ export function injectXdsBlock(filePath, compressedIndex, {createIfMissing = fal
304
428
  /**
305
429
  * Inject or update Astryx section in AGENTS.md.
306
430
  * Always creates the file if it doesn't exist.
431
+ *
432
+ * @param {string} targetDir
433
+ * @param {string} version
307
434
  */
308
435
  export function injectAgentsMd(targetDir, version) {
309
436
  const agentsPath = path.join(targetDir, AGENTS_MD);
@@ -321,6 +448,8 @@ export function injectAgentsMd(targetDir, version) {
321
448
  * Inject or update Astryx section in CLAUDE.md.
322
449
  * Only injects if CLAUDE.md already exists.
323
450
  *
451
+ * @param {string} targetDir
452
+ * @param {string} version
324
453
  * @returns {boolean} Whether the file was written
325
454
  */
326
455
  export function injectClaudeMd(targetDir, version) {
@@ -336,6 +465,8 @@ export function injectClaudeMd(targetDir, version) {
336
465
  * Remove Astryx section from a file.
337
466
  * If the file becomes empty (only boilerplate header remains), deletes it.
338
467
  *
468
+ * @param {string} filePath
469
+ * @param {{deleteIfEmpty?: boolean}} [options]
339
470
  * @returns {boolean} Whether the Astryx section was found and removed
340
471
  */
341
472
  export function removeXdsBlock(filePath, {deleteIfEmpty = false} = {}) {
@@ -372,6 +503,7 @@ export function removeXdsBlock(filePath, {deleteIfEmpty = false} = {}) {
372
503
 
373
504
  /**
374
505
  * Remove Astryx section from all known agent doc files.
506
+ * @param {string} targetDir
375
507
  */
376
508
  export function removeAgentDocs(targetDir) {
377
509
  const allPaths = discoverAgentDocs(targetDir);
@@ -392,11 +524,11 @@ export function removeAgentDocs(targetDir) {
392
524
 
393
525
  /**
394
526
  * Programmatic entry point for installing agent docs.
395
- * Used by the init wizard, upgrade command, and agent-docs command.
527
+ * Used by the init command, upgrade command, and agent-docs command.
396
528
  *
397
529
  * Strategy (when no agent/paths specified):
398
530
  * - Discover all existing agent doc files and update them
399
- * - If nothing found, create .claude/CLAUDE.md as default
531
+ * - If nothing found, create AGENTS.md as default (tool-agnostic standard)
400
532
  *
401
533
  * @param {string} targetDir
402
534
  * @param {object} [options]
@@ -410,9 +542,10 @@ export function removeAgentDocs(targetDir) {
410
542
  export function installAgentDocs(targetDir, {zh = false, lang, agent, paths, onlyReplace = false} = {}) {
411
543
  const coreDir = findCoreDir(targetDir);
412
544
  const version = getXdsVersion(coreDir);
413
- const runPrefix = getRunPrefix(targetDir);
545
+ const invocation = getCliInvocation(targetDir);
414
546
  const stylingSystem = detectStylingSystem(targetDir);
415
- const compressedIndex = generateCompressedIndex(version, {coreDir, zh, lang, runPrefix, stylingSystem});
547
+ const compressedIndex = generateCompressedIndex(version, {coreDir, zh, lang, invocation, stylingSystem});
548
+ /** @type {string[]} */
416
549
  const written = [];
417
550
 
418
551
  // Explicit paths override everything
@@ -471,14 +604,16 @@ export function installAgentDocs(targetDir, {zh = false, lang, agent, paths, onl
471
604
  return written;
472
605
  }
473
606
 
474
- // Nothing exists — create .claude/CLAUDE.md as default (skip if onlyReplace)
607
+ // Nothing exists — create root AGENTS.md as the default (skip if onlyReplace).
608
+ // AGENTS.md is the tool-agnostic standard (Codex/Copilot, Cursor, and most
609
+ // agents read it), so it's the safe default. Claude-specific output is opt-in
610
+ // via `--agent claude` (→ .claude/CLAUDE.md); `--agent all` writes both.
475
611
  if (onlyReplace) return written;
476
612
 
477
- const defaultPath = CLAUDE_DIR_MD;
478
- fs.mkdirSync(path.join(targetDir, '.claude'), {recursive: true});
613
+ const defaultPath = AGENTS_MD;
479
614
  injectXdsBlock(path.join(targetDir, defaultPath), compressedIndex, {
480
615
  createIfMissing: true,
481
- header: `# CLAUDE.md\n\nProject-specific guidance for AI coding agents.`,
616
+ header: `# AGENTS.md\n\nProject-specific guidance for AI coding agents.`,
482
617
  });
483
618
  written.push(defaultPath);
484
619
  return written;
@@ -486,6 +621,7 @@ export function installAgentDocs(targetDir, {zh = false, lang, agent, paths, onl
486
621
 
487
622
  const VALID_AGENTS = ['claude', 'cursor', 'codex', 'hermes', 'all'];
488
623
 
624
+ /** @param {import('commander').Command} program */
489
625
  export function registerAgentDocs(program) {
490
626
  program
491
627
  .command('agent-docs')
@@ -493,7 +629,7 @@ export function registerAgentDocs(program) {
493
629
  .option('--remove', 'Remove the design system section from all agent doc files')
494
630
  .option('--agent <tool>', 'Target tool: claude, cursor, codex, hermes, all')
495
631
  .option('--agent-docs-path <path...>', 'Explicit file path(s) to write to')
496
- .action(options => {
632
+ .action(/** @param {{remove?: boolean, agent?: string, agentDocsPath?: string|string[]}} options */ options => {
497
633
  const targetDir = process.cwd();
498
634
  const coreDir = findCoreDir(targetDir);
499
635
  const version = getXdsVersion(coreDir);
@@ -538,8 +674,7 @@ export function registerAgentDocs(program) {
538
674
  throw err;
539
675
  }
540
676
 
541
- const runPrefix = getRunPrefix(targetDir);
542
- const run = `${runPrefix} astryx`;
677
+ const run = getCliInvocation(targetDir);
543
678
 
544
679
  for (const t of targets) {
545
680
  humanLog(`✓ ${t}`);
@@ -16,7 +16,7 @@ import * as fs from 'node:fs';
16
16
  import * as path from 'node:path';
17
17
  import * as os from 'node:os';
18
18
  import {installAgentDocs} from './agent-docs.mjs';
19
- import {PathSafetyError} from '../utils/path-safety.mjs';
19
+ import {PathSafetyError} from '../../utils/path-safety.mjs';
20
20
 
21
21
  let tmpDir;
22
22
  beforeEach(() => {