@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.
- package/CHANGELOG.md +40 -0
- package/README.md +115 -19
- package/{src/api → api/blog}/blog.mjs +42 -6
- package/{src/api → api/blog}/blog.test.mjs +2 -2
- package/api/build/build.mjs +92 -0
- package/api/build/build.test.mjs +92 -0
- package/{src/api → api/component}/component.mjs +49 -26
- package/{src/api → api/discover}/discover.mjs +55 -18
- package/{src/api → api/docs}/docs.mjs +47 -21
- package/{src/api → api/doctor}/doctor.mjs +13 -10
- package/{src/api → api}/error.mjs +2 -2
- package/{src/api → api/hook}/hook.mjs +11 -11
- package/{src/api → api}/index.mjs +16 -9
- package/{src/api → api/integration}/validate-integration.mjs +48 -15
- package/{src/api → api/integration}/validate-integration.test.mjs +1 -1
- package/{src/api → api/layout}/layout.mjs +66 -17
- package/{src/api → api/layout}/layout.test.mjs +1 -1
- package/{src/api → api/search}/search.mjs +71 -12
- package/api/swizzle/swizzle.mjs +283 -0
- package/{src/commands → api/swizzle}/swizzle.test.mjs +26 -1
- package/{src/api → api/template}/template-integration.test.mjs +2 -2
- package/{src/api → api/template}/template-suffix.test.mjs +3 -3
- package/{src/api → api/template}/template.mjs +96 -19
- package/{src/api → api/theme}/theme-add.mjs +35 -7
- package/{src → authoring}/codemod.mjs +6 -6
- package/{src → authoring}/config.test.mjs +1 -1
- package/{src → authoring}/doc.mjs +1 -1
- package/{src → authoring}/doc.test.mjs +1 -1
- package/{src → authoring}/template.mjs +1 -1
- package/bin/astryx.mjs +12 -10
- package/{src → cli}/commands/blog.mjs +48 -7
- package/{src → cli}/commands/build-theme.mjs +133 -115
- package/cli/commands/build.mjs +172 -0
- package/cli/commands/cli-postinstall.test.mjs +42 -0
- package/{src → cli}/commands/component/index.mjs +52 -25
- package/{src → cli}/commands/component-ownership.test.mjs +3 -3
- package/{src → cli}/commands/component-package.test.mjs +1 -1
- package/{src → cli}/commands/component-resolution.test.mjs +2 -2
- package/{src → cli}/commands/discover.mjs +23 -12
- package/{src → cli}/commands/docs.mjs +42 -10
- package/{src → cli}/commands/docs.test.mjs +1 -1
- package/{src → cli}/commands/doctor.mjs +3 -3
- package/{src → cli}/commands/doctor.test.mjs +2 -2
- package/{src → cli}/commands/ensure-core-built.mjs +3 -2
- package/{src → cli}/commands/external-showcase.test.mjs +1 -1
- package/{src → cli}/commands/hook/index.mjs +40 -17
- package/{src → cli}/commands/import-hint-correctness.test.mjs +1 -1
- package/cli/commands/init.mjs +195 -0
- package/{src → cli}/commands/init.next-steps.test.mjs +1 -1
- package/cli/commands/interactive-guard.test.mjs +66 -0
- package/{src → cli}/commands/json-contract.test.mjs +2 -2
- package/{src → cli}/commands/layout.mjs +59 -19
- package/{src → cli}/commands/search.mjs +22 -15
- package/{src → cli}/commands/search.test.mjs +1 -1
- package/cli/commands/setup-nudge.test.mjs +108 -0
- package/cli/commands/swizzle.mjs +103 -0
- package/{src → cli}/commands/template.mjs +84 -53
- package/{src → cli}/commands/template.path-safety.test.mjs +2 -2
- package/{src → cli}/commands/upgrade.integration-policy.test.mjs +1 -1
- package/{src → cli}/commands/upgrade.mjs +291 -77
- package/cli/commands/upgrade.test.mjs +314 -0
- package/{src → cli}/commands/validate-integration.mjs +17 -37
- package/{src → cli}/index.mjs +55 -19
- package/{src/codemods → codemods}/__tests__/registry.test.mjs +1 -0
- package/{src/codemods → codemods}/ensure-jscodeshift.mjs +12 -28
- package/{src/codemods → codemods}/integration-discovery.mjs +6 -3
- package/{src/codemods → codemods}/integration-discovery.test.mjs +1 -1
- package/{src/codemods → codemods}/integration-runner.mjs +8 -3
- package/{src/codemods → codemods}/registry.mjs +4 -1
- package/{src/codemods → codemods}/run-codemod.mjs +18 -11
- package/{src/codemods → codemods}/runner.mjs +24 -14
- package/{src/codemods → codemods}/transforms/v0.0.10/remove-size-props.mjs +9 -4
- package/{src/codemods → codemods}/transforms/v0.0.12/add-is-icon-only.mjs +27 -22
- package/{src/codemods → codemods}/transforms/v0.0.13/icon-name-deprecations.mjs +12 -5
- package/{src/codemods → codemods}/transforms/v0.0.13/rename-attachments-to-drawer.mjs +15 -8
- package/{src/codemods → codemods}/transforms/v0.0.13/toolbar-density-to-size.mjs +10 -4
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-action-props.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-section-wash-to-muted.mjs +11 -6
- package/{src/codemods → codemods}/transforms/v0.0.14/rename-status-variants.mjs +15 -10
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-item-children-to-endcontent.mjs +13 -8
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-selector-children-to-render-option.mjs +18 -13
- package/{src/codemods → codemods}/transforms/v0.0.15/migrate-theme-selectors-to-data-attrs.mjs +8 -4
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-date-picker-to-input.mjs +11 -6
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-imperative-ref-to-handleRef.mjs +6 -1
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-isStreaming-to-isStopShown.mjs +6 -1
- package/{src/codemods → codemods}/transforms/v0.0.15/rename-stack-element-to-as.mjs +8 -3
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-badge-dot-to-statusdot.mjs +17 -10
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-gap-to-numeric.mjs +7 -1
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-isFullBleed-to-padding.mjs +9 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/migrate-useXDSIcon-to-getIcon.mjs +12 -7
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-banner-endButton-to-endContent.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-form-tooltip-startIcon.mjs +8 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-isShown-to-isOpen.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-selector-items-to-options.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-sidenav-header-to-heading.mjs +11 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/rename-topnav-title-to-heading.mjs +10 -4
- package/{src/codemods → codemods}/transforms/v0.0.2/unify-uncontrolled-to-defaultX.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.2/unify-visibility-to-onOpenChange.mjs +10 -5
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-badge-children-to-label.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-collapse-to-collapsible.mjs +9 -3
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-radius-tokens.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-shadow-tokens.mjs +13 -6
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-skeleton-radius.mjs +7 -1
- package/{src/codemods → codemods}/transforms/v0.0.6/migrate-token-names.mjs +11 -5
- package/{src/codemods → codemods}/transforms/v0.0.7/rename-banner-variant-to-container.mjs +8 -3
- package/{src/codemods → codemods}/transforms/v0.0.8/migrate-token-renames.mjs +15 -8
- package/{src/codemods → codemods}/transforms/v0.0.8/rename-endslot-to-endcontent.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/drop-xds-prefix-imports.test.mjs +42 -7
- package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-module-specifiers.test.mjs +43 -0
- package/{src/codemods → codemods}/transforms/v0.1.0/drop-xds-prefix-imports.mjs +117 -13
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-css-surfaces.mjs +21 -17
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-declare-module.mjs +7 -2
- package/{src/codemods → codemods}/transforms/v0.1.0/migrate-xds-module-specifiers.mjs +86 -15
- package/{src/codemods → codemods}/transforms/v0.1.2/rename-text-color-active-to-accent.mjs +15 -9
- package/{src/codemods → codemods}/transforms/v0.1.3/migrate-layout-components-to-experimental.mjs +17 -12
- package/{src/codemods → codemods}/transforms/v0.1.5/rename-switch-label-spacing-default-to-hug.mjs +15 -9
- package/{src/codemods → codemods}/transforms/v0.1.7/migrate-table-tableprops-to-direct-props.mjs +17 -10
- package/{src/codemods → codemods}/transforms/v0.1.7/rename-table-renderprops-styles-to-xstyle.mjs +18 -13
- package/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +161 -0
- package/codemods/transforms/v0.1.8/index.mjs +19 -0
- package/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +239 -0
- package/docs/cli-integrations.doc.mjs +150 -0
- package/docs/elevation.doc.mjs +79 -1
- package/docs/getting-started.doc.mjs +9 -9
- package/docs/internationalization.doc.mjs +92 -46
- package/docs/migration.doc.mjs +18 -18
- package/docs/principles.doc.dense.mjs +1 -1
- package/docs/principles.doc.mjs +6 -6
- package/docs/principles.doc.zh.mjs +1 -1
- package/docs/styling-libraries.doc.mjs +3 -3
- package/docs/styling.doc.mjs +4 -4
- package/docs/theme.doc.dense.mjs +2 -2
- package/docs/theme.doc.mjs +7 -7
- package/docs/theme.doc.zh.mjs +1 -1
- package/docs/tokens.doc.mjs +1 -1
- package/docs/working-with-ai.doc.mjs +19 -19
- package/{src/commands → lib/agent-docs}/agent-docs.mjs +164 -29
- package/{src/commands → lib/agent-docs}/agent-docs.path-safety.test.mjs +1 -1
- package/{src/commands → lib/agent-docs}/agent-docs.test.mjs +123 -10
- package/{src/lib → lib}/cli-error.mjs +2 -2
- package/{src/lib → lib}/component-discovery.mjs +44 -2
- package/{src/lib → lib}/component-format.mjs +67 -25
- package/{src/lib → lib}/component-loader.mjs +27 -13
- package/{src/lib → lib}/componentDocOverlay.test.mjs +0 -1
- package/{src/lib → lib}/error-codes.test.mjs +1 -1
- package/{src/lib → lib}/hook-discovery.mjs +14 -1
- package/{src/lib → lib}/hook-format.mjs +29 -5
- package/{src/lib → lib}/integration-warnings.mjs +2 -2
- package/{src/lib → lib}/integrations.mjs +20 -0
- package/{src/lib → lib}/integrations.test.mjs +1 -1
- package/{src/lib → lib}/json-contract.test.mjs +1 -1
- package/{src/lib → lib}/json-shim.mjs +11 -6
- package/{src/lib → lib}/json-shim.test.mjs +1 -1
- package/{src/lib → lib}/json.mjs +3 -3
- package/{src/lib → lib}/levenshtein.mjs +6 -0
- package/{src/lib → lib}/manifest.mjs +7 -5
- package/{src/lib → lib}/manifest.test.mjs +2 -2
- package/{src/lib → lib}/module-loader.mjs +1 -0
- package/{src/lib → lib}/package-scanner.mjs +47 -0
- package/{src/lib → lib}/project.mjs +48 -18
- package/{src/lib → lib}/project.test.mjs +1 -1
- package/{src/lib → lib}/resolve-theme.mjs +5 -0
- package/{src/lib → lib}/string-utils.mjs +15 -0
- package/lib/term-log.mjs +57 -0
- package/{src/lib → lib}/xle/browser.mjs +18 -8
- package/{src/lib → lib}/xle/expand.mjs +155 -22
- package/{src/lib → lib}/xle/parse.mjs +119 -13
- package/{src/lib → lib}/xle/print.mjs +54 -14
- package/{src/lib → lib}/xle/registry-core.mjs +28 -3
- package/{src/lib → lib}/xle/registry.mjs +9 -4
- package/{src/lib → lib}/xle/splice.mjs +13 -2
- package/{src/lib → lib}/xle/validate.mjs +95 -14
- package/lib/xle/xle-ast.d.ts +214 -0
- package/package.json +37 -28
- package/scripts/postinstall.mjs +74 -0
- package/templates/blocks/components/Avatar/AvatarFallbackChain.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarGroup.tsx +2 -2
- package/templates/blocks/components/Avatar/AvatarInitialsFallback.tsx +1 -1
- package/templates/blocks/components/Avatar/AvatarShowcase.tsx +5 -5
- package/templates/blocks/components/Avatar/AvatarUserCard.tsx +1 -1
- package/templates/blocks/components/Avatar/AvatarWithImage.tsx +4 -4
- package/templates/blocks/components/Avatar/AvatarWithStatus.tsx +3 -3
- package/templates/blocks/components/AvatarGroup/AvatarGroupShowcase.tsx +2 -2
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowCustomText.tsx +1 -1
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowDefault.tsx +1 -1
- package/templates/blocks/components/AvatarGroupOverflow/AvatarGroupOverflowShowcase.tsx +2 -2
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotShowcase.tsx +3 -3
- package/templates/blocks/components/AvatarStatusDot/AvatarStatusDotVariants.tsx +3 -3
- package/templates/blocks/components/Banner/BannerFloating.doc.mjs +14 -0
- package/templates/blocks/components/Banner/BannerFloating.tsx +16 -0
- package/templates/blocks/components/Button/ButtonFloating.doc.mjs +14 -0
- package/templates/blocks/components/Button/ButtonFloating.tsx +37 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.doc.mjs +14 -0
- package/templates/blocks/components/ButtonGroup/ButtonGroupFloating.tsx +23 -0
- package/templates/blocks/components/Card/CardElevations.doc.mjs +14 -0
- package/templates/blocks/components/Card/CardElevations.tsx +32 -0
- package/templates/blocks/components/Card/ClickableCardElevated.doc.mjs +14 -0
- package/templates/blocks/components/Card/ClickableCardElevated.tsx +21 -0
- package/templates/blocks/components/Card/SelectableCardElevated.doc.mjs +14 -0
- package/templates/blocks/components/Card/SelectableCardElevated.tsx +37 -0
- package/templates/blocks/components/Carousel/CarouselSnap.tsx +1 -1
- package/templates/blocks/components/ChatComposer/ChatComposerFlat.doc.mjs +14 -0
- package/templates/blocks/components/ChatComposer/ChatComposerFlat.tsx +75 -0
- package/templates/blocks/components/ChatMessage/ChatMessageAvatarName.tsx +2 -2
- package/templates/blocks/components/ChatMessage/ChatMessageMultiBubble.tsx +1 -1
- package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleGrouping.tsx +1 -1
- package/templates/blocks/components/ChatMessageBubble/ChatMessageBubbleMetadata.tsx +1 -1
- package/templates/blocks/components/ChatMessageList/ChatMessageListDensity.tsx +5 -9
- package/templates/blocks/components/ChatMessageList/ChatMessageListFullFeatured.tsx +1 -1
- package/templates/blocks/components/CodeBlock/CodeBlockTerminal.tsx +1 -1
- package/templates/blocks/components/HoverCard/HoverCardShowcase.tsx +1 -1
- package/templates/blocks/components/IconButton/IconButtonFloating.doc.mjs +14 -0
- package/templates/blocks/components/IconButton/IconButtonFloating.tsx +37 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.doc.mjs +19 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +46 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.doc.mjs +14 -0
- package/templates/blocks/components/InternationalizationProvider/InternationalizationProvider02Overrides.tsx +33 -0
- package/templates/blocks/components/Item/ItemWithMedia.tsx +2 -2
- package/templates/blocks/components/ListItem/ListItemWithMedia.tsx +2 -2
- package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.doc.mjs +14 -0
- package/templates/blocks/components/OverflowList/OverflowListCappedToolbar.tsx +39 -0
- package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.doc.mjs +14 -0
- package/templates/blocks/components/OverflowList/OverflowListMultiRowTags.tsx +44 -0
- package/templates/blocks/components/Pagination/PaginationDotsCarousel.tsx +2 -6
- package/templates/blocks/components/Stack/StackFillItem.tsx +2 -6
- package/templates/blocks/components/TabList/TabListTabsWithActions.doc.mjs +1 -1
- package/templates/blocks/components/TabList/TabListTabsWithActions.tsx +2 -7
- package/templates/blocks/components/Table/TableRowStatusTable.doc.mjs +14 -0
- package/templates/blocks/components/Table/TableRowStatusTable.tsx +59 -0
- package/templates/blocks/components/Thumbnail/ThumbnailDisabled.tsx +6 -1
- package/templates/blocks/components/Thumbnail/ThumbnailGallery.tsx +1 -0
- package/templates/blocks/components/Thumbnail/ThumbnailRemovable.tsx +1 -0
- package/templates/blocks/components/TypeaheadItem/TypeaheadItemShowcase.tsx +1 -1
- package/templates/pages/ai-chat/page.tsx +4 -4
- package/templates/pages/dashboard-portfolio/page.tsx +3 -11
- package/templates/pages/detail-page/page.tsx +5 -12
- package/templates/pages/documentation-design/page.tsx +1 -1
- package/templates/pages/messaging-shell/page.tsx +6 -8
- package/templates/pages/table-grouped/page.tsx +9 -14
- package/templates/pages/table-page/page.tsx +7 -9
- package/templates/pages/table-page-heatmap-status/page.tsx +5 -13
- package/{src/types → types}/api.contract.assert.ts +17 -8
- package/{src/types → types}/api.d.ts +110 -9
- package/{src/types → types}/base.d.ts +40 -4
- package/types/build.d.ts +53 -0
- package/types/codemod.d.ts +166 -0
- package/{src/types → types}/component.d.ts +1 -1
- package/{src/types → types}/discover.d.ts +1 -1
- package/{src/types → types}/docs.d.ts +1 -4
- package/{src/types → types}/hook.d.ts +1 -1
- package/{src/types → types}/index.d.ts +1 -0
- package/types/jscodeshift.d.ts +19 -0
- package/types/layout.d.ts +74 -0
- package/{src/types → types}/swizzle.d.ts +4 -0
- package/{src/types → types}/template-api.d.ts +4 -1
- package/types/theme.d.ts +53 -0
- package/types/upgrade.d.ts +108 -0
- package/utils/package-manager.mjs +178 -0
- package/utils/package-manager.test.mjs +220 -0
- package/{src/utils → utils}/path-safety.mjs +0 -18
- package/{src/utils → utils}/paths.mjs +4 -1
- package/{src/utils → utils}/update-check.mjs +5 -4
- package/{src/utils → utils}/update-check.test.mjs +3 -3
- package/docs/integration-authoring.md +0 -105
- package/src/commands/build.mjs +0 -196
- package/src/commands/init.mjs +0 -288
- package/src/commands/interactive-guard.test.mjs +0 -69
- package/src/commands/swizzle.mjs +0 -440
- package/src/commands/upgrade.test.mjs +0 -160
- package/src/types/codemod.d.ts +0 -81
- package/src/types/theme.d.ts +0 -23
- package/src/types/upgrade.d.ts +0 -64
- package/src/utils/interactive.mjs +0 -76
- package/src/utils/interactive.test.mjs +0 -70
- package/src/utils/package-manager.mjs +0 -74
- package/src/utils/package-manager.test.mjs +0 -113
- /package/{src/api → api/docs}/docOverlays.test.mjs +0 -0
- /package/{src/api → api/integration}/integration-block-exports.test.mjs +0 -0
- /package/{src/api → api/template}/template.test.mjs +0 -0
- /package/{src → authoring}/codemod.test.mjs +0 -0
- /package/{src → authoring}/config.mjs +0 -0
- /package/{src → authoring}/integration.mjs +0 -0
- /package/{src → authoring}/template.test.mjs +0 -0
- /package/{src → cli}/cli-exit-codes.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.color-scheme.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.import-path.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.path-safety.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.prose.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.variants.test.mjs +0 -0
- /package/{src → cli}/commands/build-theme.watch.test.mjs +0 -0
- /package/{src → cli}/commands/component.test.mjs +0 -0
- /package/{src → cli}/commands/detail-levels.test.mjs +0 -0
- /package/{src → cli}/commands/swizzle.path-safety.test.mjs +0 -0
- /package/{src → cli}/commands/swizzle.routing.test.mjs +0 -0
- /package/{src → cli}/commands/template.test.mjs +0 -0
- /package/{src → cli}/commands/upgrade.config-ordering.test.mjs +0 -0
- /package/{src → cli}/commands/validate-integration.test.mjs +0 -0
- /package/{src → cli}/update-hint-commands.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-imperative-ref-to-handleRef.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-isStreaming-to-isStopShown.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/rename-section-wash-to-muted.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/runner.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/toolbar-density-to-size.test.mjs +0 -0
- /package/{src/codemods → codemods}/__tests__/validation.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.10/__tests__/remove-size-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.10/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.12/__tests__/add-is-icon-only.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.12/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/icon-name-deprecations.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/__tests__/rename-attachments-to-drawer.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.13/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-action-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.14/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-item-children-to-endcontent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-selector-children-to-render-option.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/migrate-theme-selectors-to-data-attrs.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-date-picker-to-input.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/__tests__/rename-stack-element-to-as.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.15/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-badge-dot-to-statusdot.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-gap-to-numeric.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-isFullBleed-to-padding.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/migrate-useXDSIcon-to-getIcon.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-banner-endButton-to-endContent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-form-tooltip-startIcon.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-isShown-to-isOpen.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-selector-items-to-options.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-sidenav-header-to-heading.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/rename-topnav-title-to-heading.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-uncontrolled-to-defaultX.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/__tests__/unify-visibility-to-onOpenChange.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.2/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-collapse-to-collapsible.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-radius-tokens.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-shadow-tokens.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-skeleton-radius.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/__tests__/migrate-token-names.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.6/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.7/__tests__/rename-banner-variant-to-container.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.7/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/migrate-token-renames.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/__tests__/rename-endslot-to-endcontent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.0.8/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-css-surfaces.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/migrate-xds-declare-module.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/__tests__/v0.1.0-ordering.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.0/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.2/__tests__/rename-text-color-active-to-accent.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.2/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.3/__tests__/migrate-layout-components-to-experimental.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.3/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.5/__tests__/rename-switch-label-spacing-default-to-hug.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.5/index.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/migrate-table-tableprops-to-direct-props.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/__tests__/rename-table-renderprops-styles-to-xstyle.test.mjs +0 -0
- /package/{src/codemods → codemods}/transforms/v0.1.7/index.mjs +0 -0
- /package/{src/lib → lib}/cli-error.test.mjs +0 -0
- /package/{src/lib → lib}/component-discovery.importpath.test.mjs +0 -0
- /package/{src/lib → lib}/component-format.test.mjs +0 -0
- /package/{src/lib → lib}/component-loader.test.mjs +0 -0
- /package/{src/lib → lib}/config-cache.mjs +0 -0
- /package/{src/lib → lib}/config-cache.test.mjs +0 -0
- /package/{src/lib → lib}/config-schema.mjs +0 -0
- /package/{src/lib → lib}/error-codes.mjs +0 -0
- /package/{src/lib → lib}/integration-warnings.test.mjs +0 -0
- /package/{src/lib → lib}/module-loader.test.mjs +0 -0
- /package/{src/lib → lib}/node-version.mjs +0 -0
- /package/{src/lib → lib}/node-version.test.mjs +0 -0
- /package/{src/lib → lib}/parse.mjs +0 -0
- /package/{src/lib → lib}/site.mjs +0 -0
- /package/{src/lib → lib}/xle/browser.d.ts +0 -0
- /package/{src/lib → lib}/xle/xle.test.mjs +0 -0
- /package/{src/schemas → schemas}/doc-schema.mjs +0 -0
- /package/{src/schemas → schemas}/template-schema.mjs +0 -0
- /package/{src/types → types}/config.d.ts +0 -0
- /package/{src/types → types}/doc.d.ts +0 -0
- /package/{src/types → types}/doctor.d.ts +0 -0
- /package/{src/types → types}/error-codes.d.ts +0 -0
- /package/{src/types → types}/integration.d.ts +0 -0
- /package/{src/types → types}/manifest.d.ts +0 -0
- /package/{src/types → types}/search.d.ts +0 -0
- /package/{src/types → types}/template.d.ts +0 -0
- /package/{src/types → types}/validate-integration.d.ts +0 -0
- /package/{src/utils → utils}/github.mjs +0 -0
- /package/{src/utils → utils}/path-safety.test.mjs +0 -0
- /package/{src/utils → utils}/paths.test.mjs +0 -0
- /package/{src/utils → utils}/semver.mjs +0 -0
- /package/{src/utils → utils}/semver.test.mjs +0 -0
package/docs/theme.doc.mjs
CHANGED
|
@@ -148,7 +148,7 @@ function App() {
|
|
|
148
148
|
type: 'code',
|
|
149
149
|
lang: 'bash',
|
|
150
150
|
label: 'Scaffold with CLI',
|
|
151
|
-
code: '
|
|
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 `
|
|
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: '`
|
|
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: '
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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
|
},
|
package/docs/theme.doc.zh.mjs
CHANGED
|
@@ -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: '
|
|
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] },
|
package/docs/tokens.doc.mjs
CHANGED
|
@@ -1068,7 +1068,7 @@ export const docs = {
|
|
|
1068
1068
|
},
|
|
1069
1069
|
{
|
|
1070
1070
|
"type": "prose",
|
|
1071
|
-
"text": "See `
|
|
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
|
|
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: '
|
|
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
|
|
52
|
-
npx
|
|
53
|
-
npx
|
|
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
|
-
'`
|
|
69
|
-
'`
|
|
70
|
-
'`
|
|
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
|
|
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
|
|
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
|
|
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 `
|
|
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: `
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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: `
|
|
158
|
-
|
|
159
|
-
|
|
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 .
|
|
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 '
|
|
24
|
-
import {assertWithin, PathSafetyError} from '
|
|
25
|
-
import {
|
|
26
|
-
import {discoverComponents} from '
|
|
27
|
-
import {humanLog} from '
|
|
28
|
-
import {cliError} from '
|
|
29
|
-
import {ERROR_CODES} from '
|
|
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: [
|
|
51
|
+
cursor: [CURSOR_RULES, AGENTS_MD],
|
|
49
52
|
codex: [AGENTS_MD],
|
|
50
|
-
hermes: [
|
|
53
|
+
hermes: [HERMES_DOT_MD, HERMES_MD, AGENTS_MD],
|
|
51
54
|
};
|
|
52
55
|
|
|
53
56
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
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
|
-
|
|
61
|
-
|
|
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,
|
|
148
|
-
const run =
|
|
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(
|
|
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
|
|
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 .
|
|
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
|
|
545
|
+
const invocation = getCliInvocation(targetDir);
|
|
414
546
|
const stylingSystem = detectStylingSystem(targetDir);
|
|
415
|
-
const compressedIndex = generateCompressedIndex(version, {coreDir, zh, lang,
|
|
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 .
|
|
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 =
|
|
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: `#
|
|
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
|
|
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 '
|
|
19
|
+
import {PathSafetyError} from '../../utils/path-safety.mjs';
|
|
20
20
|
|
|
21
21
|
let tmpDir;
|
|
22
22
|
beforeEach(() => {
|