@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
|
@@ -19,13 +19,20 @@
|
|
|
19
19
|
* // { type: 'hook.detail', data: { name: 'useMediaQuery', ... } }
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
export {component} from './component.mjs';
|
|
23
|
-
export {docs} from './docs.mjs';
|
|
24
|
-
export {blog} from './blog.mjs';
|
|
25
|
-
export {discover} from './discover.mjs';
|
|
26
|
-
export {template} from './template.mjs';
|
|
27
|
-
export {themeAdd, listThemes} from './theme-add.mjs';
|
|
28
|
-
export {hook} from './hook.mjs';
|
|
29
|
-
export {search} from './search.mjs';
|
|
30
|
-
export {
|
|
22
|
+
export {component} from './component/component.mjs';
|
|
23
|
+
export {docs} from './docs/docs.mjs';
|
|
24
|
+
export {blog} from './blog/blog.mjs';
|
|
25
|
+
export {discover} from './discover/discover.mjs';
|
|
26
|
+
export {template} from './template/template.mjs';
|
|
27
|
+
export {themeAdd, listThemes} from './theme/theme-add.mjs';
|
|
28
|
+
export {hook} from './hook/hook.mjs';
|
|
29
|
+
export {search} from './search/search.mjs';
|
|
30
|
+
export {build} from './build/build.mjs';
|
|
31
|
+
export {swizzle} from './swizzle/swizzle.mjs';
|
|
32
|
+
export {doctor} from './doctor/doctor.mjs';
|
|
33
|
+
export {layoutExpand, layoutCheck, layoutGrammar} from './layout/layout.mjs';
|
|
34
|
+
export {
|
|
35
|
+
validateIntegration,
|
|
36
|
+
summarizeIssues,
|
|
37
|
+
} from './integration/validate-integration.mjs';
|
|
31
38
|
export {AstryxError} from './error.mjs';
|
|
@@ -28,13 +28,13 @@ import {
|
|
|
28
28
|
findManifestPaths,
|
|
29
29
|
loadManifestObject,
|
|
30
30
|
resolvePackageDir,
|
|
31
|
-
} from '
|
|
32
|
-
import {discoverIntegrationCodemods} from '
|
|
33
|
-
import {discoverIntegrationTemplatesForOne} from '
|
|
34
|
-
import * as componentDiscovery from '
|
|
31
|
+
} from '../../lib/integrations.mjs';
|
|
32
|
+
import {discoverIntegrationCodemods} from '../../codemods/integration-discovery.mjs';
|
|
33
|
+
import {discoverIntegrationTemplatesForOne} from '../template/template.mjs';
|
|
34
|
+
import * as componentDiscovery from '../../lib/component-discovery.mjs';
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* @typedef {import('
|
|
37
|
+
* @typedef {import('../../types/integration').AstryxIntegrationIssue} Issue
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -75,7 +75,8 @@ function error(code, message) {
|
|
|
75
75
|
* @param {Issue[]} issues
|
|
76
76
|
*/
|
|
77
77
|
function checkRoots(resolved, issues) {
|
|
78
|
-
|
|
78
|
+
const kinds = /** @type {const} */ (['components', 'templates', 'codemods']);
|
|
79
|
+
for (const kind of kinds) {
|
|
79
80
|
const root = resolved[kind];
|
|
80
81
|
if (root == null) continue;
|
|
81
82
|
if (!fs.existsSync(root)) {
|
|
@@ -93,7 +94,7 @@ function checkRoots(resolved, issues) {
|
|
|
93
94
|
* Validate the integration's codemods via the landed discovery. Discovery is
|
|
94
95
|
* strict (throws on bad export / duplicate id); we convert any throw into an
|
|
95
96
|
* `invalid_codemod` error.
|
|
96
|
-
* @param {
|
|
97
|
+
* @param {import('../../lib/integrations.mjs').LoadedIntegration} integration loaded-integration-shaped object
|
|
97
98
|
* @param {Issue[]} issues
|
|
98
99
|
*/
|
|
99
100
|
async function checkCodemods(integration, issues) {
|
|
@@ -101,14 +102,14 @@ async function checkCodemods(integration, issues) {
|
|
|
101
102
|
try {
|
|
102
103
|
await discoverIntegrationCodemods([integration]);
|
|
103
104
|
} catch (err) {
|
|
104
|
-
issues.push(error('invalid_codemod', err.message));
|
|
105
|
+
issues.push(error('invalid_codemod', /** @type {any} */ (err).message));
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
/**
|
|
109
110
|
* Validate the integration's templates via the landed discovery. Per-template
|
|
110
111
|
* problems are reported as `invalid_template` errors.
|
|
111
|
-
* @param {
|
|
112
|
+
* @param {import('../../lib/integrations.mjs').LoadedIntegration} integration loaded-integration-shaped object
|
|
112
113
|
* @param {Issue[]} issues
|
|
113
114
|
*/
|
|
114
115
|
async function checkTemplates(integration, issues) {
|
|
@@ -119,7 +120,7 @@ async function checkTemplates(integration, issues) {
|
|
|
119
120
|
issues.push(error('invalid_template', e.message));
|
|
120
121
|
}
|
|
121
122
|
} catch (err) {
|
|
122
|
-
issues.push(error('invalid_template', err.message));
|
|
123
|
+
issues.push(error('invalid_template', /** @type {any} */ (err).message));
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
|
|
@@ -132,7 +133,7 @@ async function checkTemplates(integration, issues) {
|
|
|
132
133
|
* `discoverIntegrationComponents` returns ownership records and does not throw
|
|
133
134
|
* on a missing same-stem source — it records `sourcePath: null`. We surface
|
|
134
135
|
* each such record as an `invalid_component` error.
|
|
135
|
-
* @param {
|
|
136
|
+
* @param {import('../../lib/integrations.mjs').LoadedIntegration} integration loaded-integration-shaped object
|
|
136
137
|
* @param {Issue[]} issues
|
|
137
138
|
*/
|
|
138
139
|
async function checkComponents(integration, issues) {
|
|
@@ -152,13 +153,13 @@ async function checkComponents(integration, issues) {
|
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
} catch (err) {
|
|
155
|
-
issues.push(error('invalid_component', err.message));
|
|
156
|
+
issues.push(error('invalid_component', /** @type {any} */ (err).message));
|
|
156
157
|
}
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
/**
|
|
160
161
|
* Run every contribution validator against a loaded-integration-shaped object.
|
|
161
|
-
* @param {
|
|
162
|
+
* @param {import('../../lib/integrations.mjs').LoadedIntegration} integration
|
|
162
163
|
* @param {Issue[]} issues
|
|
163
164
|
*/
|
|
164
165
|
async function runContributionChecks(integration, issues) {
|
|
@@ -181,7 +182,7 @@ async function runContributionChecks(integration, issues) {
|
|
|
181
182
|
* contribution checks (roots + codemods/templates/components) because those can
|
|
182
183
|
* regress independently of the manifest (a deleted directory, a broken template).
|
|
183
184
|
*
|
|
184
|
-
* @param {
|
|
185
|
+
* @param {import('../../lib/integrations.mjs').LoadedIntegration} loaded loaded-integration-shaped object
|
|
185
186
|
* @returns {Promise<Issue[]>}
|
|
186
187
|
*/
|
|
187
188
|
export async function validateLoadedIntegration(loaded) {
|
|
@@ -210,6 +211,7 @@ export async function validateLoadedIntegration(loaded) {
|
|
|
210
211
|
async function validateAtPackageDir(packageDir, identity) {
|
|
211
212
|
/** @type {Issue[]} */
|
|
212
213
|
const issues = [];
|
|
214
|
+
/** @type {ValidateResult} */
|
|
213
215
|
const result = {
|
|
214
216
|
found: true,
|
|
215
217
|
name: identity.name,
|
|
@@ -254,10 +256,11 @@ async function validateAtPackageDir(packageDir, identity) {
|
|
|
254
256
|
`Integration manifest (${path.basename(manifestFile)})`,
|
|
255
257
|
);
|
|
256
258
|
} catch (err) {
|
|
257
|
-
issues.push(error('invalid_manifest', err.message));
|
|
259
|
+
issues.push(error('invalid_manifest', /** @type {any} */ (err).message));
|
|
258
260
|
return result;
|
|
259
261
|
}
|
|
260
262
|
|
|
263
|
+
/** @param {string | null | undefined} value */
|
|
261
264
|
const resolveRoot = value =>
|
|
262
265
|
value == null ? undefined : path.resolve(packageDir, value);
|
|
263
266
|
|
|
@@ -300,6 +303,7 @@ export async function validateLocalIntegration(cwd = process.cwd()) {
|
|
|
300
303
|
return {found: false, issues: []};
|
|
301
304
|
}
|
|
302
305
|
|
|
306
|
+
/** @type {{name?: string, version?: string}} */
|
|
303
307
|
let pkg = {};
|
|
304
308
|
try {
|
|
305
309
|
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
@@ -323,6 +327,7 @@ export async function validateInstalledIntegration(spec, cwd = process.cwd()) {
|
|
|
323
327
|
const packageDir = resolvePackageDir(spec, cwd);
|
|
324
328
|
const pkgJsonPath = path.join(packageDir, 'package.json');
|
|
325
329
|
|
|
330
|
+
/** @type {{name?: string, version?: string}} */
|
|
326
331
|
let pkg;
|
|
327
332
|
try {
|
|
328
333
|
pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
@@ -346,6 +351,34 @@ export async function validateInstalledIntegration(spec, cwd = process.cwd()) {
|
|
|
346
351
|
});
|
|
347
352
|
}
|
|
348
353
|
|
|
354
|
+
/**
|
|
355
|
+
* Unified entry: validate the LOCAL integration (no `pkg`) or an INSTALLED one
|
|
356
|
+
* (`pkg` given) and return the `integration.validate` envelope. The no-manifest
|
|
357
|
+
* local case is guidance, not an error — it comes back with `name: null` and no
|
|
358
|
+
* issues so the CLI can print a hint and stay exit-0.
|
|
359
|
+
*
|
|
360
|
+
* This is the seam that keeps the CLI a thin wrapper: the command handler calls
|
|
361
|
+
* this and only chooses how to render (human vs --json) + the exit code.
|
|
362
|
+
*
|
|
363
|
+
* @param {string} [pkg] installed package name; omit to validate the cwd package
|
|
364
|
+
* @param {{cwd?: string}} [options]
|
|
365
|
+
* @returns {Promise<import('../../types/validate-integration').ValidateIntegrationResponse>}
|
|
366
|
+
*/
|
|
367
|
+
export async function validateIntegration(pkg, options = {}) {
|
|
368
|
+
const {cwd = process.cwd()} = options;
|
|
369
|
+
const result = pkg
|
|
370
|
+
? await validateInstalledIntegration(pkg, cwd)
|
|
371
|
+
: await validateLocalIntegration(cwd);
|
|
372
|
+
return {
|
|
373
|
+
type: 'integration.validate',
|
|
374
|
+
data: {
|
|
375
|
+
name: result.found ? result.name ?? null : null,
|
|
376
|
+
version: result.found ? result.version ?? null : null,
|
|
377
|
+
issues: result.issues,
|
|
378
|
+
},
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
|
|
349
382
|
/**
|
|
350
383
|
* Summarize issues by severity.
|
|
351
384
|
* @param {Issue[]} issues
|
|
@@ -24,7 +24,7 @@ let tmpDir;
|
|
|
24
24
|
// Absolute file:// URL to the codemod helper so codemod modules in the temp
|
|
25
25
|
// package can import createCodemod without node_modules wiring.
|
|
26
26
|
const codemodModuleUrl = pathToFileURL(
|
|
27
|
-
path.resolve(process.cwd(), 'packages/cli/
|
|
27
|
+
path.resolve(process.cwd(), 'packages/cli/authoring/codemod.mjs'),
|
|
28
28
|
).href;
|
|
29
29
|
|
|
30
30
|
beforeEach(() => {
|
|
@@ -16,16 +16,29 @@
|
|
|
16
16
|
|
|
17
17
|
import * as fs from 'node:fs';
|
|
18
18
|
import * as path from 'node:path';
|
|
19
|
-
import {AstryxError} from '
|
|
20
|
-
import {ERROR_CODES} from '
|
|
21
|
-
import {assertWithin, isFilePathArg, PathSafetyError} from '
|
|
22
|
-
import {parse, detectForm, XLEParseError} from '
|
|
23
|
-
import {validate} from '
|
|
24
|
-
import {expand} from '
|
|
25
|
-
import {toCompact, toOutline} from '
|
|
26
|
-
import {buildRegistry, ALIAS_TABLE} from '
|
|
27
|
-
import {discoverTemplates, stripTemplateAssetRefs} from '
|
|
28
|
-
import {Project} from '
|
|
19
|
+
import {AstryxError} from '../error.mjs';
|
|
20
|
+
import {ERROR_CODES} from '../../lib/error-codes.mjs';
|
|
21
|
+
import {assertWithin, isFilePathArg, PathSafetyError} from '../../utils/path-safety.mjs';
|
|
22
|
+
import {parse, detectForm, XLEParseError} from '../../lib/xle/parse.mjs';
|
|
23
|
+
import {validate} from '../../lib/xle/validate.mjs';
|
|
24
|
+
import {expand} from '../../lib/xle/expand.mjs';
|
|
25
|
+
import {toCompact, toOutline} from '../../lib/xle/print.mjs';
|
|
26
|
+
import {buildRegistry, ALIAS_TABLE} from '../../lib/xle/registry.mjs';
|
|
27
|
+
import {discoverTemplates, stripTemplateAssetRefs} from '../template/template.mjs';
|
|
28
|
+
import {Project} from '../../lib/project.mjs';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @typedef {object} LayoutBlock
|
|
32
|
+
* @property {string} dirName
|
|
33
|
+
* @property {string} name
|
|
34
|
+
* @property {'template'|'component'} kind
|
|
35
|
+
* @property {string} [type]
|
|
36
|
+
* @property {string} [description]
|
|
37
|
+
* @property {string} [category]
|
|
38
|
+
* @property {string} [importPath]
|
|
39
|
+
* @property {string} [filePath]
|
|
40
|
+
* @property {boolean} [isDefault]
|
|
41
|
+
*/
|
|
29
42
|
|
|
30
43
|
/**
|
|
31
44
|
* The catalog a `{hint}` can resolve to: template blocks (spliced inline) plus
|
|
@@ -33,8 +46,12 @@ import {Project} from '../lib/project.mjs';
|
|
|
33
46
|
* `experimental.xle.components` (imported by name). App components are how XLE
|
|
34
47
|
* reaches domain pieces — the KpiCard/chart/drawer set that the
|
|
35
48
|
* @astryxdesign/core registry can't see.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} cwd
|
|
51
|
+
* @returns {Promise<LayoutBlock[]>}
|
|
36
52
|
*/
|
|
37
53
|
async function loadBlocks(cwd) {
|
|
54
|
+
/** @type {LayoutBlock[]} */
|
|
38
55
|
const blocks = [];
|
|
39
56
|
try {
|
|
40
57
|
const all = await discoverTemplates(cwd);
|
|
@@ -44,6 +61,7 @@ async function loadBlocks(cwd) {
|
|
|
44
61
|
}
|
|
45
62
|
try {
|
|
46
63
|
const project = await Project.load(cwd);
|
|
64
|
+
/** @type {Record<string, {from?: string, description?: string, default?: boolean}>} */
|
|
47
65
|
const components = project.config.experimental?.xle?.components ?? {};
|
|
48
66
|
for (const [name, spec] of Object.entries(components)) {
|
|
49
67
|
const importPath = spec.from;
|
|
@@ -65,11 +83,17 @@ async function loadBlocks(cwd) {
|
|
|
65
83
|
return blocks;
|
|
66
84
|
}
|
|
67
85
|
|
|
86
|
+
/** @param {string} name */
|
|
68
87
|
const normKey = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
69
88
|
|
|
70
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Collect the block names referenced by {hints} anywhere in the doc.
|
|
91
|
+
* @param {import('../../lib/xle/xle-ast').XLEDoc} doc
|
|
92
|
+
*/
|
|
71
93
|
function collectHintNames(doc) {
|
|
94
|
+
/** @type {Set<string>} */
|
|
72
95
|
const names = new Set();
|
|
96
|
+
/** @param {import('../../lib/xle/xle-ast').XLEItem} node */
|
|
73
97
|
const visitNode = (node) => {
|
|
74
98
|
if (!node || node.kind === 'group') {
|
|
75
99
|
(node?.children || []).forEach(visit);
|
|
@@ -77,11 +101,17 @@ function collectHintNames(doc) {
|
|
|
77
101
|
}
|
|
78
102
|
if (node.hint?.block) names.add(node.hint.block.name);
|
|
79
103
|
for (const slot of node.slots || []) {
|
|
80
|
-
|
|
81
|
-
(
|
|
104
|
+
const value = slot.value;
|
|
105
|
+
if (value && typeof value === 'object' && 'hint' in value && value.hint?.block) {
|
|
106
|
+
names.add(value.hint.block.name);
|
|
107
|
+
}
|
|
108
|
+
if (value && typeof value === 'object' && 'subexpr' in value) {
|
|
109
|
+
(value.subexpr || []).forEach(visit);
|
|
110
|
+
}
|
|
82
111
|
}
|
|
83
112
|
(node.children || []).forEach(visit);
|
|
84
113
|
};
|
|
114
|
+
/** @param {import('../../lib/xle/xle-ast').XLEItem} item */
|
|
85
115
|
const visit = (item) => (item?.kind === 'group' ? item.children.forEach(visit) : visitNode(item));
|
|
86
116
|
doc.roots.forEach(visit);
|
|
87
117
|
doc.overlays.forEach(visit);
|
|
@@ -92,24 +122,30 @@ function collectHintNames(doc) {
|
|
|
92
122
|
* Build the blockModules map expand() needs: import-mode for app components,
|
|
93
123
|
* splice-mode (reading + asset-stripping the block source) for template blocks.
|
|
94
124
|
* Only blocks actually referenced are read.
|
|
125
|
+
*
|
|
126
|
+
* @param {import('../../lib/xle/xle-ast').XLEDoc} doc
|
|
127
|
+
* @param {LayoutBlock[]} blocks
|
|
128
|
+
* @returns {Map<string, import('../../lib/xle/xle-ast').BlockModule>}
|
|
95
129
|
*/
|
|
96
130
|
function buildBlockModules(doc, blocks) {
|
|
97
131
|
const referenced = collectHintNames(doc);
|
|
98
132
|
if (referenced.size === 0) return new Map();
|
|
99
133
|
const byKey = new Map(blocks.map(b => [normKey(b.dirName), b]));
|
|
134
|
+
/** @type {Map<string, import('../../lib/xle/xle-ast').BlockModule>} */
|
|
100
135
|
const modules = new Map();
|
|
101
136
|
for (const name of referenced) {
|
|
102
137
|
const block = byKey.get(normKey(name));
|
|
103
138
|
if (!block) continue;
|
|
104
139
|
if (block.kind === 'component') {
|
|
105
|
-
modules.set(name, {mode: 'import', componentName: block.name, importPath: block.importPath, isDefault: block.isDefault});
|
|
140
|
+
modules.set(name, /** @type {import('../../lib/xle/xle-ast').BlockModule} */ (/** @type {unknown} */ ({mode: 'import', componentName: block.name, importPath: block.importPath, isDefault: block.isDefault})));
|
|
106
141
|
} else if (block.filePath && fs.existsSync(block.filePath)) {
|
|
107
|
-
modules.set(name, {mode: 'splice', componentName: block.dirName, source: stripTemplateAssetRefs(fs.readFileSync(block.filePath, 'utf-8'))});
|
|
142
|
+
modules.set(name, /** @type {import('../../lib/xle/xle-ast').BlockModule} */ ({mode: 'splice', componentName: block.dirName, source: stripTemplateAssetRefs(fs.readFileSync(block.filePath, 'utf-8'))}));
|
|
108
143
|
}
|
|
109
144
|
}
|
|
110
145
|
return modules;
|
|
111
146
|
}
|
|
112
147
|
|
|
148
|
+
/** @param {import('../../lib/xle/xle-ast').RawIssue} issue */
|
|
113
149
|
function formatIssue(issue) {
|
|
114
150
|
const where = issue.line != null ? `line ${issue.line}: ` : '';
|
|
115
151
|
return `${where}${issue.message}`;
|
|
@@ -118,11 +154,17 @@ function formatIssue(issue) {
|
|
|
118
154
|
/**
|
|
119
155
|
* Parse + validate, throwing structured XDSErrors on failure.
|
|
120
156
|
* Returns {doc, registry, blocks, warnings}.
|
|
157
|
+
*
|
|
158
|
+
* @param {string} expression
|
|
159
|
+
* @param {{form?: 'compact'|'outline'|'auto', loose?: boolean, cwd?: string}} [options]
|
|
121
160
|
*/
|
|
122
161
|
async function analyze(expression, {form = 'auto', loose = false, cwd = process.cwd()} = {}) {
|
|
123
|
-
const registry =
|
|
162
|
+
const registry = /** @type {import('../../lib/xle/xle-ast').Registry} */ (
|
|
163
|
+
/** @type {unknown} */ (await buildRegistry({cwd}))
|
|
164
|
+
);
|
|
124
165
|
const blocks = await loadBlocks(cwd);
|
|
125
166
|
|
|
167
|
+
/** @type {import('../../lib/xle/xle-ast').XLEDoc} */
|
|
126
168
|
let doc;
|
|
127
169
|
try {
|
|
128
170
|
doc = parse(expression, {form});
|
|
@@ -212,6 +254,9 @@ export async function layoutExpand(expression, options = {}) {
|
|
|
212
254
|
/**
|
|
213
255
|
* `astryx layout check "<expr>" [--form compact|outline]`
|
|
214
256
|
* Validates without expanding; echoes both canonical surfaces.
|
|
257
|
+
*
|
|
258
|
+
* @param {string} expression
|
|
259
|
+
* @param {{form?: 'compact'|'outline'|'auto', loose?: boolean, cwd?: string}} [options]
|
|
215
260
|
*/
|
|
216
261
|
export async function layoutCheck(expression, options = {}) {
|
|
217
262
|
const {form = 'auto', loose = false, cwd = process.cwd()} = options;
|
|
@@ -233,16 +278,20 @@ export async function layoutCheck(expression, options = {}) {
|
|
|
233
278
|
/**
|
|
234
279
|
* `astryx layout grammar` — the agent cheatsheet, with the alias table
|
|
235
280
|
* generated from this branch's registry (never hand-maintained).
|
|
281
|
+
*
|
|
282
|
+
* @param {{cwd?: string}} [options]
|
|
236
283
|
*/
|
|
237
284
|
export async function layoutGrammar(options = {}) {
|
|
238
285
|
const {cwd = process.cwd()} = options;
|
|
239
286
|
const registry = await buildRegistry({cwd});
|
|
240
287
|
|
|
288
|
+
/** @type {string[]} */
|
|
241
289
|
const aliasLines = [];
|
|
290
|
+
/** @type {Map<string, string[]>} */
|
|
242
291
|
const byTarget = new Map();
|
|
243
292
|
for (const [alias, target] of registry.aliases) {
|
|
244
293
|
if (!byTarget.has(target)) byTarget.set(target, []);
|
|
245
|
-
byTarget.get(target)
|
|
294
|
+
byTarget.get(target)?.push(alias);
|
|
246
295
|
}
|
|
247
296
|
for (const [target, aliases] of [...byTarget.entries()].sort(([a], [b]) => a.localeCompare(b))) {
|
|
248
297
|
aliasLines.push(`${aliases.join('/')}=${target}`);
|
|
@@ -13,7 +13,7 @@ import {tmpdir} from 'node:os';
|
|
|
13
13
|
import {join} from 'node:path';
|
|
14
14
|
import ts from 'typescript';
|
|
15
15
|
import {layoutExpand, layoutCheck, layoutGrammar} from './layout.mjs';
|
|
16
|
-
import {buildRegistry} from '
|
|
16
|
+
import {buildRegistry} from '../../lib/xle/registry.mjs';
|
|
17
17
|
|
|
18
18
|
// The registry imports ~140 .doc.mjs modules on first use; under full-suite
|
|
19
19
|
// parallel load that can exceed the default 5s test timeout. Warm it once.
|
|
@@ -33,19 +33,34 @@
|
|
|
33
33
|
import * as fs from 'node:fs';
|
|
34
34
|
import * as path from 'node:path';
|
|
35
35
|
import {pathToFileURL} from 'node:url';
|
|
36
|
-
import {findCoreDir, CLI_ROOT} from '
|
|
36
|
+
import {findCoreDir, CLI_ROOT} from '../../utils/paths.mjs';
|
|
37
37
|
import {
|
|
38
38
|
discoverComponents,
|
|
39
39
|
findComponentReadme,
|
|
40
40
|
resolveImportPath,
|
|
41
|
-
} from '
|
|
42
|
-
import {discoverHooks, findHookDoc} from '
|
|
43
|
-
import {levenshteinDistance} from '
|
|
44
|
-
import {discoverTemplates, extractComponents} from '
|
|
45
|
-
import {AstryxError} from '
|
|
41
|
+
} from '../../lib/component-discovery.mjs';
|
|
42
|
+
import {discoverHooks, findHookDoc} from '../../lib/hook-discovery.mjs';
|
|
43
|
+
import {levenshteinDistance} from '../../lib/string-utils.mjs';
|
|
44
|
+
import {discoverTemplates, extractComponents} from '../template/template.mjs';
|
|
45
|
+
import {AstryxError} from '../error.mjs';
|
|
46
46
|
|
|
47
47
|
const DOCS_DIR = path.join(CLI_ROOT, 'docs');
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* A search candidate gathered from one content domain. Extra underscore-
|
|
51
|
+
* prefixed fields carry domain-specific payload used only by {@link toResult}.
|
|
52
|
+
* @typedef {object} Candidate
|
|
53
|
+
* @property {'component'|'hook'|'doc'|'template'} domain
|
|
54
|
+
* @property {string} name
|
|
55
|
+
* @property {string[]} [keywords]
|
|
56
|
+
* @property {string} [description]
|
|
57
|
+
* @property {string[]} [prose]
|
|
58
|
+
* @property {string} [_import]
|
|
59
|
+
* @property {string} [_title]
|
|
60
|
+
* @property {string} [_displayName]
|
|
61
|
+
* @property {'page'|'block'} [_kind]
|
|
62
|
+
*/
|
|
63
|
+
|
|
49
64
|
/**
|
|
50
65
|
* Synonym / intent map: product-language terms an agent is likely to type,
|
|
51
66
|
* expanded to the catalog's vocabulary so oblique queries still rank. Keys and
|
|
@@ -72,10 +87,19 @@ const SYNONYMS = {
|
|
|
72
87
|
|
|
73
88
|
// Flatten into a token -> Set(expansions) lookup (bidirectional).
|
|
74
89
|
const SYNONYM_INDEX = (() => {
|
|
90
|
+
/** @type {Map<string, Set<string>>} */
|
|
75
91
|
const idx = new Map();
|
|
92
|
+
/**
|
|
93
|
+
* @param {string} a
|
|
94
|
+
* @param {string} b
|
|
95
|
+
*/
|
|
76
96
|
const add = (a, b) => {
|
|
77
|
-
|
|
78
|
-
|
|
97
|
+
let set = idx.get(a);
|
|
98
|
+
if (!set) {
|
|
99
|
+
set = new Set();
|
|
100
|
+
idx.set(a, set);
|
|
101
|
+
}
|
|
102
|
+
set.add(b);
|
|
79
103
|
};
|
|
80
104
|
for (const [key, vals] of Object.entries(SYNONYMS)) {
|
|
81
105
|
for (const v of vals) {
|
|
@@ -159,6 +183,8 @@ const MIN_TOKEN_SCORE = 50;
|
|
|
159
183
|
/**
|
|
160
184
|
* Best score for a token against a candidate, fanning out through synonyms
|
|
161
185
|
* (synonym hits are discounted so a direct hit always wins).
|
|
186
|
+
* @param {string} tok
|
|
187
|
+
* @param {Candidate} candidate
|
|
162
188
|
* @returns {{score: number, reason: string} | null}
|
|
163
189
|
*/
|
|
164
190
|
function bestForToken(tok, candidate) {
|
|
@@ -176,6 +202,12 @@ function bestForToken(tok, candidate) {
|
|
|
176
202
|
return best;
|
|
177
203
|
}
|
|
178
204
|
|
|
205
|
+
/**
|
|
206
|
+
* @param {string} term - Lowercased full query.
|
|
207
|
+
* @param {string[]} tokens - Content tokens from tokenizeQuery(term).
|
|
208
|
+
* @param {Candidate} candidate
|
|
209
|
+
* @returns {{score: number, reason: string} | null}
|
|
210
|
+
*/
|
|
179
211
|
export function scoreQuery(term, tokens, candidate) {
|
|
180
212
|
const full = scoreCandidate(term, candidate);
|
|
181
213
|
|
|
@@ -192,6 +224,7 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
192
224
|
// strong hits, then reward coverage so candidates matching more terms win.
|
|
193
225
|
let sum = 0;
|
|
194
226
|
let matched = 0;
|
|
227
|
+
/** @type {string[]} */
|
|
195
228
|
const hitTerms = [];
|
|
196
229
|
for (const tok of tokens) {
|
|
197
230
|
const h = bestForToken(tok, candidate);
|
|
@@ -235,6 +268,10 @@ export function scoreQuery(term, tokens, candidate) {
|
|
|
235
268
|
export function scoreCandidate(term, {name, keywords = [], description = '', prose = []}) {
|
|
236
269
|
let best = 0;
|
|
237
270
|
let reason = '';
|
|
271
|
+
/**
|
|
272
|
+
* @param {number} score
|
|
273
|
+
* @param {string} why
|
|
274
|
+
*/
|
|
238
275
|
const consider = (score, why) => {
|
|
239
276
|
if (score > best) {
|
|
240
277
|
best = score;
|
|
@@ -299,7 +336,12 @@ export function scoreCandidate(term, {name, keywords = [], description = '', pro
|
|
|
299
336
|
return best > 0 ? {score: best, reason} : null;
|
|
300
337
|
}
|
|
301
338
|
|
|
302
|
-
/**
|
|
339
|
+
/**
|
|
340
|
+
* Load a doc module's `docs`/`doc` export, swallowing errors.
|
|
341
|
+
* @param {string} docPath
|
|
342
|
+
* @param {string} [exportName]
|
|
343
|
+
* @returns {Promise<any>}
|
|
344
|
+
*/
|
|
303
345
|
async function loadModuleDoc(docPath, exportName = 'docs') {
|
|
304
346
|
try {
|
|
305
347
|
const mod = await import(pathToFileURL(docPath).href);
|
|
@@ -313,13 +355,16 @@ async function loadModuleDoc(docPath, exportName = 'docs') {
|
|
|
313
355
|
* Build component candidates: name + keywords + usage/description from the
|
|
314
356
|
* component's .doc.mjs.
|
|
315
357
|
* @param {string} coreDir
|
|
358
|
+
* @returns {Promise<Candidate[]>}
|
|
316
359
|
*/
|
|
317
360
|
async function gatherComponents(coreDir) {
|
|
318
361
|
const grouped = discoverComponents(coreDir);
|
|
319
362
|
const names = Object.values(grouped).flat();
|
|
363
|
+
/** @type {Candidate[]} */
|
|
320
364
|
const candidates = [];
|
|
321
365
|
for (const comp of names) {
|
|
322
366
|
const readme = findComponentReadme(coreDir, comp);
|
|
367
|
+
/** @type {string[]} */
|
|
323
368
|
let keywords = [];
|
|
324
369
|
let description = '';
|
|
325
370
|
if (readme && readme.endsWith('.doc.mjs')) {
|
|
@@ -344,13 +389,16 @@ async function gatherComponents(coreDir) {
|
|
|
344
389
|
* Build hook candidates: name + keywords + usage/description from the hook's
|
|
345
390
|
* .doc.mjs.
|
|
346
391
|
* @param {string} coreDir
|
|
392
|
+
* @returns {Promise<Candidate[]>}
|
|
347
393
|
*/
|
|
348
394
|
async function gatherHooks(coreDir) {
|
|
349
395
|
const grouped = discoverHooks(coreDir);
|
|
350
396
|
const names = Object.values(grouped).flat();
|
|
397
|
+
/** @type {Candidate[]} */
|
|
351
398
|
const candidates = [];
|
|
352
399
|
for (const hookName of names) {
|
|
353
400
|
const docPath = findHookDoc(coreDir, hookName);
|
|
401
|
+
/** @type {string[]} */
|
|
354
402
|
let keywords = [];
|
|
355
403
|
let description = '';
|
|
356
404
|
let importPath = '@astryxdesign/core/hooks';
|
|
@@ -373,9 +421,13 @@ async function gatherHooks(coreDir) {
|
|
|
373
421
|
return candidates;
|
|
374
422
|
}
|
|
375
423
|
|
|
376
|
-
/**
|
|
424
|
+
/**
|
|
425
|
+
* Build doc-topic candidates: topic name + description + section prose.
|
|
426
|
+
* @returns {Promise<Candidate[]>}
|
|
427
|
+
*/
|
|
377
428
|
async function gatherDocs() {
|
|
378
429
|
if (!fs.existsSync(DOCS_DIR)) return [];
|
|
430
|
+
/** @type {Candidate[]} */
|
|
379
431
|
const candidates = [];
|
|
380
432
|
for (const file of fs.readdirSync(DOCS_DIR)) {
|
|
381
433
|
const match = file.match(/^([\w-]+)\.doc\.mjs$/);
|
|
@@ -383,6 +435,7 @@ async function gatherDocs() {
|
|
|
383
435
|
const topic = match[1];
|
|
384
436
|
const doc = await loadModuleDoc(path.join(DOCS_DIR, file));
|
|
385
437
|
let description = '';
|
|
438
|
+
/** @type {string[]} */
|
|
386
439
|
const prose = [];
|
|
387
440
|
if (doc) {
|
|
388
441
|
description = doc.description || '';
|
|
@@ -405,7 +458,11 @@ async function gatherDocs() {
|
|
|
405
458
|
return candidates;
|
|
406
459
|
}
|
|
407
460
|
|
|
408
|
-
/**
|
|
461
|
+
/**
|
|
462
|
+
* Build template candidates (page + block) from the template discovery API.
|
|
463
|
+
* @param {string} cwd
|
|
464
|
+
* @returns {Promise<Candidate[]>}
|
|
465
|
+
*/
|
|
409
466
|
async function gatherTemplates(cwd) {
|
|
410
467
|
let templates;
|
|
411
468
|
try {
|
|
@@ -444,7 +501,7 @@ async function gatherTemplates(cwd) {
|
|
|
444
501
|
* carries enough to act on it: the domain, name, a one-line description, and
|
|
445
502
|
* the follow-up command (and import path where relevant).
|
|
446
503
|
*
|
|
447
|
-
* @param {
|
|
504
|
+
* @param {Candidate} c - candidate
|
|
448
505
|
* @param {number} score
|
|
449
506
|
* @param {string} reason
|
|
450
507
|
*/
|
|
@@ -522,6 +579,7 @@ export async function search(query, options = {}) {
|
|
|
522
579
|
}
|
|
523
580
|
|
|
524
581
|
// Gather candidates from each requested domain in parallel.
|
|
582
|
+
/** @param {string} d */
|
|
525
583
|
const wants = d => !type || type === d;
|
|
526
584
|
const [components, hooks, docTopics, templates] = await Promise.all([
|
|
527
585
|
wants('component') ? gatherComponents(coreDir) : [],
|
|
@@ -543,6 +601,7 @@ export async function search(query, options = {}) {
|
|
|
543
601
|
}
|
|
544
602
|
|
|
545
603
|
// Sort by score desc, then domain (stable order), then name.
|
|
604
|
+
/** @type {Record<string, number>} */
|
|
546
605
|
const domainOrder = {component: 0, hook: 1, doc: 2, template: 3};
|
|
547
606
|
scored.sort(
|
|
548
607
|
(a, b) =>
|