@astryxdesign/cli 0.6.3-canary.ebaebc4 → 0.6.3-canary.ee13359
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/README.md +114 -77
- package/api/blog/blog.doc.mjs +1 -0
- package/api/build/build.doc.mjs +4 -3
- package/api/build/build.test.mjs +14 -3
- package/api/build/build.type.d.mts +35 -1
- package/api/build/build.type.mjs +24 -3
- package/api/build/help/help.d.mts +8 -5
- package/api/build/help/help.mjs +56 -6
- package/api/component/_adapter.d.mts +6 -12
- package/api/component/_adapter.mjs +20 -10
- package/api/component/component.doc.mjs +13 -3
- package/api/component/component.mjs +91 -14
- package/api/component/component.test.mjs +38 -0
- package/api/component/component.type.d.mts +16 -5
- package/api/component/component.type.mjs +13 -5
- package/api/component/detail/blocks/blocks.d.mts +2 -1
- package/api/component/detail/blocks/blocks.mjs +4 -3
- package/api/component/list/list.d.mts +0 -5
- package/api/component/list/list.mjs +40 -11
- package/api/discover/discover.doc.mjs +2 -1
- package/api/docs/_adapter.d.mts +210 -34
- package/api/docs/_adapter.mjs +674 -134
- package/api/docs/detail/detail.mjs +11 -3
- package/api/docs/detail/section/section.mjs +24 -13
- package/api/docs/detail/section/section.test.mjs +15 -6
- package/api/docs/docs.d.mts +5 -3
- package/api/docs/docs.doc.mjs +36 -15
- package/api/docs/docs.mjs +44 -8
- package/api/docs/docs.test.mjs +158 -4
- package/api/docs/docs.type.d.mts +165 -2
- package/api/docs/docs.type.mjs +101 -3
- package/api/docs/index/index.mjs +11 -3
- package/api/docs/index/index.test.mjs +1 -1
- package/api/docs/integration-tree.test.mjs +547 -0
- package/api/docs/integrationDocs.test.mjs +14 -14
- package/api/docs/list/list.mjs +28 -12
- package/api/docs/node/node.d.mts +43 -0
- package/api/docs/node/node.mjs +192 -0
- package/api/doctor/doctor.d.mts +54 -4
- package/api/doctor/doctor.doc.mjs +1 -0
- package/api/doctor/doctor.mjs +327 -16
- package/api/doctor/doctor.test.mjs +420 -7
- package/api/gap-report/gap-report.doc.mjs +8 -4
- package/api/hook/_adapter.mjs +19 -5
- package/api/hook/hook.doc.mjs +1 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/hook/list/list.mjs +69 -17
- package/api/index.d.mts +1 -1
- package/api/index.mjs +1 -0
- package/api/init/init.doc.mjs +6 -1
- package/api/init/init.test.mjs +41 -1
- package/api/init/remove/remove.mjs +1 -1
- package/api/init/run/run.mjs +20 -10
- package/api/integration/add-contribution.component-names.test.mjs +120 -0
- package/api/integration/add-contribution.d.mts +2 -1
- package/api/integration/add-contribution.mjs +125 -12
- package/api/integration/add-contribution.test.mjs +254 -3
- package/api/integration/add-theme.mjs +34 -64
- package/api/integration/add-theme.test.mjs +105 -21
- package/api/integration/authoring-checks.mjs +108 -31
- package/api/integration/authoring-checks.test.mjs +171 -6
- package/api/integration/authoring-checks.type.d.mts +3 -1
- package/api/integration/authoring-checks.type.mjs +3 -1
- package/api/integration/integration-authoring.type.d.mts +2 -0
- package/api/integration/integration-authoring.type.mjs +2 -0
- package/api/integration/integration-block-exports.test.mjs +10 -6
- package/api/integration/integrationAdd.doc.mjs +14 -4
- package/api/integration/integrationAddAgentDoc.doc.mjs +1 -0
- package/api/integration/integrationAddCodemod.doc.mjs +1 -0
- package/api/integration/integrationAddComponent.doc.mjs +2 -1
- package/api/integration/integrationAddDoc.doc.mjs +8 -1
- package/api/integration/integrationAddTemplate.doc.mjs +1 -0
- package/api/integration/integrationAddTheme.doc.mjs +6 -5
- package/api/integration/integrationComponentConflicts.doc.mjs +1 -0
- package/api/integration/integrationDocConflicts.doc.mjs +2 -1
- package/api/integration/integrationPackCheck.doc.mjs +2 -1
- package/api/integration/integrationTemplateConflicts.doc.mjs +7 -5
- package/api/integration/pack-check.mjs +34 -0
- package/api/integration/pack-check.test.mjs +138 -47
- package/api/integration/pack-check.type.d.mts +26 -2
- package/api/integration/pack-check.type.mjs +14 -1
- package/api/integration/summarizeIssues.doc.mjs +1 -0
- package/api/integration/validate-integration-fixes.test.mjs +1389 -0
- package/api/integration/validate-integration.mjs +52 -102
- package/api/integration/validate-integration.test.mjs +179 -26
- package/api/integration/validate-unread-theme-folders.test.mjs +110 -0
- package/api/integration/validateIntegration.doc.mjs +3 -2
- package/api/json/assertResponse.doc.mjs +1 -0
- package/api/json/envelope-types.test.mjs +76 -0
- package/api/json/index.ts +2 -0
- package/api/json/isError.doc.mjs +1 -0
- package/api/json/parseResponse.doc.mjs +3 -2
- package/api/layout/_adapter.mjs +20 -5
- package/api/layout/expand/expand.mjs +7 -5
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.mjs +2 -1
- package/api/layout/layoutCheck.doc.mjs +1 -0
- package/api/layout/layoutExpand.doc.mjs +2 -1
- package/api/layout/layoutGrammar.doc.mjs +1 -0
- package/api/search/search-return-type.test.mjs +54 -0
- package/api/search/search.d.mts +28 -10
- package/api/search/search.doc.mjs +8 -2
- package/api/search/search.mjs +334 -38
- package/api/search/search.test.mjs +124 -1
- package/api/search/search.type.d.mts +13 -1
- package/api/search/search.type.mjs +4 -1
- package/api/swizzle/copy/copy.mjs +28 -11
- package/api/swizzle/swizzle.doc.mjs +2 -1
- package/api/template/copy/copy.mjs +17 -23
- package/api/template/copy/copy.test.mjs +17 -0
- package/api/template/list/list.mjs +1 -0
- package/api/template/template-integration.test.mjs +1022 -3
- package/api/template/template-suffix.test.mjs +41 -21
- package/api/template/template.doc.mjs +30 -8
- package/api/template/template.mjs +45 -8
- package/api/template/template.type.d.mts +6 -8
- package/api/template/template.type.mjs +3 -2
- package/api/theme/_adapter.d.mts +2 -3
- package/api/theme/_adapter.mjs +4 -5
- package/api/theme/add/add.binary.test.mjs +84 -0
- package/api/theme/add/add.mjs +20 -3
- package/api/theme/add/add.staging.test.mjs +66 -0
- package/api/theme/add/add.test.mjs +14 -1
- package/api/theme/build/build.mjs +114 -37
- package/api/theme/build/build.public-component-vars.test.mjs +1 -1
- package/api/theme/build/build.receipt-doc.test.mjs +111 -0
- package/api/theme/build/font-warning.mjs +3 -3
- package/api/theme/build/font-warning.test.mjs +5 -2
- package/api/theme/generateTonalPalette.doc.mjs +1 -0
- package/api/theme/integration-themes.test.mjs +39 -28
- package/api/theme/list/list.test.mjs +19 -20
- package/api/theme/listThemes.doc.mjs +6 -5
- package/api/theme/palette/generate/generate.mjs +7 -2
- package/api/theme/palette/generate/generate.test.mjs +96 -0
- package/api/theme/palette/generate/generator.mjs +8 -1
- package/api/theme/palette/generate/generator.test.mjs +10 -0
- package/api/theme/template/template.mjs +11 -2
- package/api/theme/template/template.test.mjs +20 -0
- package/api/theme/themeAdd.doc.mjs +4 -3
- package/api/theme/themeBuild.doc.mjs +8 -4
- package/api/theme/themeList.doc.mjs +6 -3
- package/api/theme/themeListAvailable.doc.mjs +5 -3
- package/api/theme/themePaletteGenerate.doc.mjs +1 -0
- package/api/theme/themeTargets.doc.mjs +1 -0
- package/api/theme/themeTemplate.doc.mjs +6 -2
- package/api/upgrade/_adapter.d.mts +32 -5
- package/api/upgrade/_adapter.mjs +124 -73
- package/api/upgrade/list/list.mjs +2 -1
- package/api/upgrade/list/list.test.mjs +73 -0
- package/api/upgrade/provider-agreement.test.mjs +152 -0
- package/api/upgrade/run/run.mjs +356 -59
- package/api/upgrade/status/status.mjs +2 -2
- package/api/upgrade/upgrade.doc.mjs +8 -2
- package/api/upgrade/upgrade.type.d.mts +38 -0
- package/api/upgrade/upgrade.type.mjs +16 -0
- package/assets/codemods/__tests__/runner.test.mjs +330 -8
- package/assets/codemods/integration-discovery.mjs +8 -2
- package/assets/codemods/integration-discovery.test.mjs +15 -0
- package/assets/codemods/integration-runner.mjs +56 -4
- package/assets/codemods/integration-runner.protection.test.mjs +153 -0
- package/assets/codemods/run-codemod.mjs +177 -34
- package/assets/codemods/runner.mjs +350 -102
- package/assets/codemods/term-log.mjs +32 -8
- package/assets/codemods/term-log.test.mjs +19 -1
- package/assets/codemods/transform-prop.mjs +109 -0
- package/assets/codemods/transform-prop.test.mjs +95 -0
- package/assets/codemods/transforms/next/__tests__/migrate-native-picker-to-presentation.test.mjs +63 -0
- package/assets/codemods/transforms/next/__tests__/migrate-theme-catalog-to-descriptors.test.mjs +220 -0
- package/assets/codemods/transforms/next/index.mjs +19 -1
- package/assets/codemods/transforms/next/migrate-native-picker-to-presentation.mjs +148 -0
- package/assets/codemods/transforms/next/migrate-theme-catalog-to-descriptors.mjs +141 -0
- package/assets/codemods/transforms/v0.0.14/__tests__/rename-status-variants.test.mjs +86 -165
- package/assets/codemods/transforms/v0.0.14/rename-status-variants.mjs +72 -210
- package/assets/codemods/transforms/v0.1.8/__tests__/rename-avatar-size-scale.test.mjs +83 -115
- package/assets/codemods/transforms/v0.1.8/rename-avatar-size-scale.mjs +57 -186
- package/assets/codemods/transforms/v0.6.0/__tests__/next-codemods.test.mjs +47 -0
- package/assets/codemods/transforms/v0.6.0/rename-resizable-pixel-bounds.mjs +57 -10
- package/assets/docs/getting-started.doc.mjs +2 -2
- package/assets/docs/principles.doc.mjs +6 -6
- package/assets/docs/styling-libraries.doc.mjs +2 -2
- package/assets/docs/styling.doc.mjs +4 -4
- package/assets/docs/theme.doc.mjs +4 -4
- package/assets/docs/tokens.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +30 -0
- package/assets/docs/tree/cli.doc.mjs +23 -0
- package/assets/docs/tree/commands.doc.mjs +25 -0
- package/assets/docs/{cli-integrations.doc.mjs → tree/integrations.doc.mjs} +66 -38
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/templates/blocks/components/DateInput/DateInputDateRange.tsx +1 -1
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.doc.mjs +14 -0
- package/assets/templates/blocks/components/Item/ItemDocumentTabs.tsx +100 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaInlineRail.tsx +61 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaOverscrollChaining.tsx +126 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.doc.mjs +15 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaShowcase.tsx +86 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyGroupHeaders.tsx +99 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaStickyPassthrough.tsx +122 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.doc.mjs +14 -0
- package/assets/templates/blocks/components/ScrollableArea/ScrollableAreaTwoAxisBoard.tsx +95 -0
- package/assets/templates/blocks/components/TimeInput/TimeInputConstrained.tsx +1 -0
- package/assets/templates/pages/table-tree/page.tsx +1704 -0
- package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
- package/assets/templates/themes/butter/butterTheme.doc.mjs +11 -0
- package/assets/templates/themes/chocolate/chocolateTheme.doc.mjs +11 -0
- package/assets/templates/themes/gothic/gothicTheme.doc.mjs +11 -0
- package/assets/templates/themes/matcha/matchaTheme.doc.mjs +11 -0
- package/assets/templates/themes/neutral/neutralTheme.doc.mjs +11 -0
- package/assets/templates/themes/stone/stoneTheme.doc.mjs +11 -0
- package/assets/templates/themes/y2k/y2kTheme.doc.mjs +11 -0
- package/authoring/codemod/codemod.doc.mjs +1 -1
- package/authoring/codemod/type.ts +12 -0
- package/authoring/config/config.doc.mjs +2 -2
- package/authoring/config/debug-composition.test.mjs +92 -0
- package/authoring/config/type.ts +15 -3
- package/authoring/debug/debug.doc.d.mts +11 -0
- package/authoring/debug/debug.doc.mjs +182 -0
- package/authoring/debug/parse.d.mts +3 -3
- package/authoring/doctypes/_schema.d.mts +71 -141
- package/authoring/doctypes/_schema.mjs +29 -2
- package/authoring/doctypes/base/graph-fields.doc.mjs +8 -6
- package/authoring/doctypes/base/type.ts +6 -5
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +2 -2
- package/authoring/doctypes/component/type.ts +2 -2
- package/authoring/doctypes/doctypes-new.test.mjs +48 -6
- package/authoring/doctypes/enum/enum.doc.mjs +1 -1
- package/authoring/doctypes/enum/type.ts +1 -1
- package/authoring/doctypes/function/function.doc.mjs +3 -2
- package/authoring/doctypes/function/type.ts +3 -2
- package/authoring/doctypes/hook/type.ts +2 -2
- package/authoring/doctypes/load-contract.test.mjs +3 -2
- package/authoring/doctypes/namespace/namespace.doc.mjs +6 -10
- package/authoring/doctypes/namespace/parse.test.mjs +23 -25
- package/authoring/doctypes/namespace/type.ts +5 -2
- package/authoring/doctypes/parse.d.mts +4 -2
- package/authoring/doctypes/parse.mjs +10 -5
- package/authoring/doctypes/reference/reference.doc.mjs +7 -5
- package/authoring/doctypes/reference/type.ts +12 -10
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/doctypes/schema/type.ts +1 -2
- package/authoring/doctypes/template/parse.d.mts +2 -0
- package/authoring/doctypes/template/parse.mjs +4 -0
- package/authoring/doctypes/template/parse.test.mjs +18 -0
- package/authoring/doctypes/template/template.doc.mjs +9 -3
- package/authoring/doctypes/template/type.ts +8 -0
- package/authoring/doctypes/theme/parse.d.mts +35 -0
- package/authoring/doctypes/theme/parse.mjs +76 -0
- package/authoring/doctypes/theme/theme.doc.d.mts +9 -0
- package/authoring/doctypes/theme/theme.doc.mjs +79 -0
- package/authoring/doctypes/theme/type.ts +42 -0
- package/authoring/doctypes/types.ts +2 -1
- package/authoring/gap-report/gap-report.doc.d.mts +12 -0
- package/authoring/gap-report/gap-report.doc.mjs +183 -0
- package/authoring/identity/identity.doc.mjs +2 -2
- package/authoring/index.d.mts +1 -0
- package/authoring/index.d.ts +7 -4
- package/authoring/index.mjs +2 -1
- package/authoring/integration/integration.doc.mjs +2 -2
- package/authoring/integration/type.ts +4 -10
- package/clients/cli/__tests__/cliManifest.test.ts +27 -29
- package/clients/cli/command-load-failure.test.mjs +83 -0
- package/clients/cli/commands/blog.doc.mjs +1 -1
- package/clients/cli/commands/blog.mjs +23 -8
- package/clients/cli/commands/blog.test.mjs +42 -1
- package/clients/cli/commands/build-theme.adaptations.test.mjs +100 -1
- package/clients/cli/commands/build-theme.ascii-output.test.mjs +161 -0
- package/clients/cli/commands/build-theme.flag-docs.test.mjs +110 -0
- package/clients/cli/commands/build-theme.mjs +16 -50
- package/clients/cli/commands/build-theme.path-safety.test.mjs +86 -1
- package/clients/cli/commands/build-theme.variants.test.mjs +76 -0
- package/clients/cli/commands/build.doc.mjs +5 -2
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +50 -0
- package/clients/cli/commands/build.mjs +37 -49
- package/clients/cli/commands/build.playbook.test.mjs +75 -0
- package/clients/cli/commands/build.text-fields.test.mjs +40 -0
- package/clients/cli/commands/component/index.mjs +3 -8
- package/clients/cli/commands/component-ownership.test.mjs +3 -3
- package/clients/cli/commands/component-package.test.mjs +46 -0
- package/clients/cli/commands/component-resolution.test.mjs +21 -0
- package/clients/cli/commands/component.doc.mjs +1 -1
- package/clients/cli/commands/component.test.mjs +19 -0
- package/clients/cli/commands/detail-levels.test.mjs +2 -2
- package/clients/cli/commands/discover.broken-integration.test.mjs +52 -5
- package/clients/cli/commands/discover.components-flag.test.mjs +97 -0
- package/clients/cli/commands/discover.doc.mjs +5 -3
- package/clients/cli/commands/discover.mjs +4 -4
- package/clients/cli/commands/discover.text-projection.test.mjs +103 -0
- package/clients/cli/commands/docs.doc.mjs +21 -9
- package/clients/cli/commands/docs.mjs +182 -68
- package/clients/cli/commands/docs.test.mjs +120 -16
- package/clients/cli/commands/doctor-integration-components.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +3 -3
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +15 -8
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.doc.mjs +1 -1
- package/clients/cli/commands/doctor-integration.package-json.test.mjs +53 -0
- package/clients/cli/commands/doctor-integration.test.mjs +83 -8
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +30 -25
- package/clients/cli/commands/doctor.test.mjs +42 -0
- package/clients/cli/commands/gap-report.doc.mjs +17 -6
- package/clients/cli/commands/gap-report.test.mjs +72 -0
- package/clients/cli/commands/hook/index.mjs +7 -17
- package/clients/cli/commands/hook.doc.mjs +1 -1
- package/clients/cli/commands/hook.text-projection.test.mjs +45 -0
- package/clients/cli/commands/init.doc.mjs +20 -9
- package/clients/cli/commands/init.flag-help.test.mjs +153 -0
- package/clients/cli/commands/integration-add.controls.test.mjs +132 -0
- package/clients/cli/commands/integration-add.doc.mjs +32 -6
- package/clients/cli/commands/integration-pack.doc.mjs +1 -1
- package/clients/cli/commands/integration-real-world.test.mjs +3 -9
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/integration.mjs +1 -0
- package/clients/cli/commands/interactive-guard.test.mjs +101 -24
- package/clients/cli/commands/json-contract.test.mjs +33 -0
- package/clients/cli/commands/layout-check.doc.mjs +15 -4
- package/clients/cli/commands/layout-expand.doc.mjs +22 -5
- package/clients/cli/commands/layout-grammar.doc.mjs +1 -1
- package/clients/cli/commands/layout.doc.mjs +3 -3
- package/clients/cli/commands/layout.mjs +21 -9
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/no-prompt-wording.test.mjs +94 -0
- package/clients/cli/commands/search.doc.mjs +7 -4
- package/clients/cli/commands/search.mjs +28 -9
- package/clients/cli/commands/search.test.mjs +75 -0
- package/clients/cli/commands/setup-nudge.test.mjs +6 -0
- package/clients/cli/commands/swizzle.doc.mjs +3 -2
- package/clients/cli/commands/swizzle.path-safety.test.mjs +42 -0
- package/clients/cli/commands/template.doc.mjs +52 -13
- package/clients/cli/commands/template.flag-help.test.mjs +117 -0
- package/clients/cli/commands/template.mjs +4 -91
- package/clients/cli/commands/template.path-help.test.mjs +40 -0
- package/clients/cli/commands/text-json-parity.test.mjs +719 -0
- package/clients/cli/commands/theme-add.doc.mjs +4 -3
- package/clients/cli/commands/theme-build.doc.mjs +8 -7
- package/clients/cli/commands/theme-list.doc.mjs +2 -2
- package/clients/cli/commands/theme-palette-generate.doc.mjs +3 -3
- package/clients/cli/commands/theme-palette-generate.test.mjs +19 -0
- package/clients/cli/commands/theme-palette.doc.mjs +1 -1
- package/clients/cli/commands/theme-targets.behavior.test.mjs +4 -3
- package/clients/cli/commands/theme-targets.doc.mjs +1 -1
- package/clients/cli/commands/theme-template.behavior.test.mjs +12 -0
- package/clients/cli/commands/theme-template.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -1
- package/clients/cli/commands/upgrade.ascii-output.test.mjs +87 -0
- package/clients/cli/commands/upgrade.doc.mjs +20 -8
- package/clients/cli/commands/upgrade.file-protection.test.mjs +228 -0
- package/clients/cli/commands/upgrade.flag-help.test.mjs +188 -0
- package/clients/cli/commands/upgrade.hook-output.test.mjs +88 -0
- package/clients/cli/commands/upgrade.mjs +29 -7
- package/clients/cli/formatters/index.mjs +2 -0
- package/clients/cli/formatters/index.test.mjs +6 -0
- package/clients/cli/index.mjs +21 -30
- package/clients/cli/latest-version-env.test.mjs +50 -0
- package/clients/cli/lib/cli-error.test.mjs +7 -0
- package/clients/cli/lib/component-format.mjs +9 -9
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +32 -6
- package/clients/cli/lib/doc-text-ascii.test.mjs +82 -0
- package/clients/cli/lib/exit-codes.test.mjs +97 -0
- package/clients/cli/lib/hook-format.mjs +19 -10
- package/clients/cli/lib/json-shim.mjs +38 -2
- package/clients/cli/lib/json-shim.test.mjs +83 -0
- package/clients/cli/lib/manifest.d.ts +2 -0
- package/clients/cli/lib/manifest.mjs +31 -2
- package/clients/cli/lib/manifest.test.mjs +17 -0
- package/foundation/agent-docs/agent-docs.d.mts +4 -0
- package/foundation/agent-docs/agent-docs.mjs +70 -3
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +266 -4
- package/foundation/agent-docs/agent-docs.test.mjs +10 -1
- package/foundation/config/integration-debug.test.mjs +28 -3
- package/foundation/config/project-themes.test.mjs +11 -19
- package/foundation/config/project.d.mts +20 -11
- package/foundation/config/project.mjs +246 -89
- package/foundation/config/project.test.mjs +270 -21
- package/foundation/discovery/authoring-self-docs.d.mts +6 -0
- package/foundation/discovery/authoring-self-docs.mjs +17 -7
- package/foundation/discovery/authoring-self-docs.test.mjs +20 -9
- package/foundation/discovery/authoring-surface.d.mts +74 -0
- package/foundation/discovery/authoring-surface.mjs +525 -0
- package/foundation/discovery/authoring-surface.test.mjs +392 -0
- package/foundation/discovery/cli-self-docs.d.mts +119 -0
- package/foundation/discovery/cli-self-docs.mjs +490 -0
- package/foundation/discovery/cli-self-docs.test.mjs +375 -0
- package/foundation/discovery/component-discovery.d.mts +38 -0
- package/foundation/discovery/component-discovery.mjs +48 -0
- package/foundation/discovery/component-loader.d.mts +35 -38
- package/foundation/discovery/component-loader.mjs +53 -222
- package/foundation/discovery/docs-discovery.d.mts +108 -10
- package/foundation/discovery/docs-discovery.mjs +191 -30
- package/foundation/discovery/docs-discovery.test.mjs +71 -32
- package/foundation/discovery/docs-output-budget.d.mts +2 -2
- package/foundation/discovery/docs-output-budget.mjs +1 -1
- package/foundation/discovery/docs-section-key.d.mts +28 -10
- package/foundation/discovery/docs-section-key.mjs +134 -33
- package/foundation/discovery/docs-section-key.test.mjs +41 -19
- package/foundation/discovery/template-adapter.d.mts +113 -11
- package/foundation/discovery/template-adapter.fixture-refs.test.mjs +248 -0
- package/foundation/discovery/template-adapter.integration-isolation.test.mjs +94 -0
- package/foundation/discovery/template-adapter.mjs +772 -82
- package/foundation/discovery/template-adapter.test.mjs +57 -0
- package/foundation/discovery/theme-discovery.d.mts +67 -7
- package/foundation/discovery/theme-discovery.mjs +916 -186
- package/foundation/discovery/theme-discovery.test.mjs +613 -219
- package/foundation/doc-compiler/bundle.d.mts +47 -0
- package/foundation/doc-compiler/bundle.mjs +278 -0
- package/foundation/doc-compiler/bundle.test.mjs +266 -0
- package/foundation/doc-compiler/compile.d.mts +220 -39
- package/foundation/doc-compiler/compile.mjs +311 -15
- package/foundation/doc-compiler/diagnostics.d.mts +126 -0
- package/foundation/doc-compiler/diagnostics.mjs +305 -0
- package/foundation/doc-compiler/doc-compiler.test.mjs +28 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +1642 -0
- package/foundation/doc-compiler/import.d.mts +24 -0
- package/foundation/doc-compiler/import.mjs +59 -0
- package/foundation/doc-compiler/inputs.d.mts +102 -0
- package/foundation/doc-compiler/inputs.mjs +291 -0
- package/foundation/doc-compiler/inputs.test.mjs +299 -0
- package/foundation/doc-compiler/ir.d.mts +13 -0
- package/foundation/doc-compiler/ir.mjs +196 -12
- package/foundation/doc-compiler/lenses.d.mts +3 -2
- package/foundation/doc-compiler/lenses.mjs +2 -1
- package/foundation/doc-compiler/links.d.mts +135 -0
- package/foundation/doc-compiler/links.mjs +253 -0
- package/foundation/doc-compiler/links.test.mjs +139 -0
- package/foundation/doc-compiler/lower-doc.test.mjs +495 -0
- package/foundation/doc-compiler/overlays.d.mts +37 -0
- package/foundation/doc-compiler/overlays.mjs +206 -0
- package/foundation/doc-compiler/parse-readable.d.mts +9 -0
- package/foundation/doc-compiler/parse-readable.mjs +29 -0
- package/foundation/doc-compiler/read.d.mts +127 -0
- package/foundation/doc-compiler/read.mjs +325 -0
- package/foundation/doc-compiler/read.test.mjs +313 -0
- package/foundation/doc-compiler/source.d.mts +33 -0
- package/foundation/doc-compiler/source.mjs +128 -0
- package/foundation/doc-compiler/tree.d.mts +288 -0
- package/foundation/doc-compiler/tree.mjs +876 -0
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/fs/file-protection.d.mts +33 -0
- package/foundation/fs/file-protection.mjs +825 -0
- package/foundation/fs/file-protection.test.mjs +250 -0
- package/foundation/fs/module-loader.d.mts +1 -0
- package/foundation/fs/module-loader.mjs +50 -1
- package/foundation/fs/module-loader.stdout.test.mjs +332 -0
- package/foundation/fs/path-safety.d.mts +3 -2
- package/foundation/fs/path-safety.mjs +49 -19
- package/foundation/fs/path-safety.test.mjs +50 -0
- package/foundation/fs/publish-file-hardlink-unavailable.test.mjs +129 -94
- package/foundation/integrations/autolink.d.mts +58 -1
- package/foundation/integrations/autolink.mjs +143 -52
- package/foundation/integrations/autolink.test.mjs +1 -1
- package/foundation/integrations/cli-requirement.d.mts +45 -0
- package/foundation/integrations/cli-requirement.mjs +154 -0
- package/foundation/integrations/cli-requirement.test.mjs +109 -0
- package/foundation/integrations/contribution-fixes.d.mts +145 -0
- package/foundation/integrations/contribution-fixes.mjs +1284 -0
- package/foundation/integrations/contribution-inventory.d.mts +3 -2
- package/foundation/integrations/contribution-inventory.mjs +27 -24
- package/foundation/integrations/contribution-inventory.test.mjs +86 -27
- package/foundation/integrations/integration-warnings.d.mts +9 -2
- package/foundation/integrations/integration-warnings.mjs +51 -26
- package/foundation/integrations/integration-warnings.test.mjs +74 -1
- package/foundation/integrations/integrations.d.mts +3 -0
- package/foundation/integrations/integrations.mjs +11 -97
- package/foundation/integrations/provider-ledger.test.mjs +275 -0
- package/foundation/integrations/provider-resolution.d.mts +152 -0
- package/foundation/integrations/provider-resolution.mjs +576 -0
- package/foundation/integrations/provider-resolution.test.mjs +369 -0
- package/foundation/integrations/theme-descriptor.d.mts +8 -0
- package/foundation/integrations/theme-descriptor.mjs +44 -0
- package/foundation/integrations/validate-contributions.mjs +121 -29
- package/foundation/response/base.d.ts +8 -4
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.d.ts +2 -0
- package/foundation/response/error-codes.doc.mjs +13 -4
- package/foundation/response/error-codes.mjs +8 -2
- package/foundation/response/error-codes.test.mjs +137 -10
- package/foundation/response/json-contract.test.mjs +11 -0
- package/foundation/response/json.d.mts +4 -2
- package/foundation/response/json.mjs +8 -10
- package/foundation/response/response-types.doc.mjs +22 -17
- package/foundation/response/response-types.doc.test.mjs +158 -0
- package/foundation/response/response.doc.mjs +1 -1
- package/foundation/text/string-utils.mjs +22 -10
- package/foundation/xle/expand.d.mts +2 -0
- package/foundation/xle/expand.mjs +4 -3
- package/foundation/xle/expand.test.mjs +54 -0
- package/foundation/xle/xle.test.mjs +13 -0
- package/package.json +10 -9
- package/assets/templates/themes/manifest.json +0 -95
- package/clients/cli/lib/update-check.mjs +0 -83
- package/clients/cli/lib/update-check.test.mjs +0 -137
- package/clients/cli/update-hint-commands.test.mjs +0 -54
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
4
|
+
import * as fs from 'node:fs';
|
|
5
|
+
import * as path from 'node:path';
|
|
6
|
+
import {runCli} from '../../../test-utils/run-cli.mjs';
|
|
7
|
+
import {validateIntegration} from '../../../api/integration/validate-integration.mjs';
|
|
8
|
+
|
|
9
|
+
const NO_MANIFEST = 'No astryx.integration.* found next to package.json.';
|
|
10
|
+
|
|
11
|
+
let tmpDir;
|
|
12
|
+
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-doctor-pkgjson-'));
|
|
15
|
+
fs.writeFileSync(path.join(tmpDir, 'package.json'), '{"name": "@acme/widgets",}\n');
|
|
16
|
+
fs.writeFileSync(
|
|
17
|
+
path.join(tmpDir, 'astryx.integration.mjs'),
|
|
18
|
+
"export default {\n templates: './templates',\n};\n",
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
fs.rmSync(tmpDir, {recursive: true, force: true});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('doctor integration with a malformed package.json', () => {
|
|
27
|
+
it('keeps a null name for the no-manifest case only', async () => {
|
|
28
|
+
const result = await validateIntegration(undefined, {cwd: tmpDir});
|
|
29
|
+
|
|
30
|
+
expect(result.data.name).toBe('(local package)');
|
|
31
|
+
expect(result.data.issues.map(issue => issue.code)).toEqual([
|
|
32
|
+
'invalid_package_json',
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
for (const leaf of ['validate', 'templates', 'components', 'docs']) {
|
|
37
|
+
it(`${leaf} prints the package.json error instead of "no manifest"`, async () => {
|
|
38
|
+
const text = await runCli(['doctor', 'integration', leaf], tmpDir);
|
|
39
|
+
const json = await runCli(
|
|
40
|
+
['doctor', 'integration', leaf, '--json'],
|
|
41
|
+
tmpDir,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(text.status).toBe(1);
|
|
45
|
+
expect(json.status).toBe(1);
|
|
46
|
+
expect(text.stdout).not.toContain(NO_MANIFEST);
|
|
47
|
+
expect(text.stdout).toContain('invalid_package_json');
|
|
48
|
+
expect(JSON.parse(json.stdout).data.issues).toContainEqual(
|
|
49
|
+
expect.objectContaining({code: 'invalid_package_json'}),
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
@@ -31,6 +31,8 @@ function writeIntegration({
|
|
|
31
31
|
id,
|
|
32
32
|
name = 'Integration template',
|
|
33
33
|
missingRoot = false,
|
|
34
|
+
replacements,
|
|
35
|
+
type = 'page',
|
|
34
36
|
}) {
|
|
35
37
|
fs.writeFileSync(
|
|
36
38
|
path.join(tmpDir, 'package.json'),
|
|
@@ -44,8 +46,8 @@ function writeIntegration({
|
|
|
44
46
|
const stem = path.join(tmpDir, 'templates', id);
|
|
45
47
|
fs.mkdirSync(path.dirname(stem), {recursive: true});
|
|
46
48
|
fs.writeFileSync(
|
|
47
|
-
`${stem}.
|
|
48
|
-
`export default {type: '
|
|
49
|
+
`${stem}.doc.mjs`,
|
|
50
|
+
`export default {type: '${type}', name: ${JSON.stringify(name)}, description: 'fixture'${replacements?.[id] == null ? '' : `, replaces: ${JSON.stringify(replacements[id])}`}};\n`,
|
|
49
51
|
);
|
|
50
52
|
fs.writeFileSync(
|
|
51
53
|
`${stem}.tsx`,
|
|
@@ -124,7 +126,12 @@ describe('doctor integration — command', () => {
|
|
|
124
126
|
return true;
|
|
125
127
|
});
|
|
126
128
|
|
|
127
|
-
await createProgram().parseAsync([
|
|
129
|
+
await createProgram().parseAsync([
|
|
130
|
+
'node',
|
|
131
|
+
'astryx',
|
|
132
|
+
'doctor',
|
|
133
|
+
'integration',
|
|
134
|
+
]);
|
|
128
135
|
|
|
129
136
|
const output = writes.join('');
|
|
130
137
|
expect(output).toContain('validate [package]');
|
|
@@ -136,7 +143,9 @@ describe('doctor integration — command', () => {
|
|
|
136
143
|
|
|
137
144
|
it('explains the optional package argument in every leaf help', () => {
|
|
138
145
|
const program = createProgram();
|
|
139
|
-
const doctor = program.commands.find(
|
|
146
|
+
const doctor = program.commands.find(
|
|
147
|
+
command => command.name() === 'doctor',
|
|
148
|
+
);
|
|
140
149
|
const integration = doctor?.commands.find(
|
|
141
150
|
command => command.name() === 'integration',
|
|
142
151
|
);
|
|
@@ -152,7 +161,10 @@ describe('doctor integration — command', () => {
|
|
|
152
161
|
});
|
|
153
162
|
|
|
154
163
|
it('templates explains how to check an installed package when no local manifest exists', async () => {
|
|
155
|
-
fs.writeFileSync(
|
|
164
|
+
fs.writeFileSync(
|
|
165
|
+
path.join(tmpDir, 'package.json'),
|
|
166
|
+
JSON.stringify({name: 'plain'}),
|
|
167
|
+
);
|
|
156
168
|
process.chdir(tmpDir);
|
|
157
169
|
|
|
158
170
|
await createProgram().parseAsync([
|
|
@@ -239,6 +251,71 @@ describe('doctor integration — command', () => {
|
|
|
239
251
|
expect(process.exitCode).toBeUndefined();
|
|
240
252
|
});
|
|
241
253
|
|
|
254
|
+
it('templates reports an intentional replacement and the Core-original command', async () => {
|
|
255
|
+
const core = (await discoverCoreTemplates()).find(
|
|
256
|
+
template => template.type === 'page',
|
|
257
|
+
);
|
|
258
|
+
expect(core).toBeDefined();
|
|
259
|
+
writeIntegration({
|
|
260
|
+
id: 'acme-app-shell',
|
|
261
|
+
type: core.type,
|
|
262
|
+
replacements: {'acme-app-shell': core.dirName},
|
|
263
|
+
});
|
|
264
|
+
process.chdir(tmpDir);
|
|
265
|
+
|
|
266
|
+
await createProgram().parseAsync([
|
|
267
|
+
'node',
|
|
268
|
+
'astryx',
|
|
269
|
+
'--json',
|
|
270
|
+
'doctor',
|
|
271
|
+
'integration',
|
|
272
|
+
'templates',
|
|
273
|
+
]);
|
|
274
|
+
|
|
275
|
+
const parsed = JSON.parse(logCalls.join('\n'));
|
|
276
|
+
expect(parsed.data.issues).toEqual([]);
|
|
277
|
+
expect(parsed.data.conflicts).toEqual([
|
|
278
|
+
expect.objectContaining({
|
|
279
|
+
id: 'acme-app-shell',
|
|
280
|
+
relationship: 'replaces',
|
|
281
|
+
replaces: core.dirName,
|
|
282
|
+
severity: 'info',
|
|
283
|
+
}),
|
|
284
|
+
]);
|
|
285
|
+
expect(parsed.data.conflicts[0].command).toContain(
|
|
286
|
+
`--package @astryxdesign/core`,
|
|
287
|
+
);
|
|
288
|
+
expect(process.exitCode).toBeUndefined();
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('templates exits 1 for a missing replacement target', async () => {
|
|
292
|
+
writeIntegration({
|
|
293
|
+
id: 'acme-app-shell',
|
|
294
|
+
replacements: {'acme-app-shell': 'missing-core-shell'},
|
|
295
|
+
});
|
|
296
|
+
process.chdir(tmpDir);
|
|
297
|
+
|
|
298
|
+
await createProgram().parseAsync([
|
|
299
|
+
'node',
|
|
300
|
+
'astryx',
|
|
301
|
+
'--json',
|
|
302
|
+
'doctor',
|
|
303
|
+
'integration',
|
|
304
|
+
'templates',
|
|
305
|
+
]);
|
|
306
|
+
|
|
307
|
+
const parsed = JSON.parse(logCalls.join('\n'));
|
|
308
|
+
expect(parsed.data.issues).toEqual(
|
|
309
|
+
expect.arrayContaining([
|
|
310
|
+
expect.objectContaining({
|
|
311
|
+
code: 'missing_template_replacement_target',
|
|
312
|
+
severity: 'error',
|
|
313
|
+
}),
|
|
314
|
+
]),
|
|
315
|
+
);
|
|
316
|
+
expect(process.exitCode).toBe(1);
|
|
317
|
+
});
|
|
318
|
+
|
|
242
319
|
it('templates exits 1 when structural errors prevent a trustworthy check', async () => {
|
|
243
320
|
writeIntegration({missingRoot: true});
|
|
244
321
|
process.chdir(tmpDir);
|
|
@@ -278,9 +355,7 @@ describe('doctor integration — command', () => {
|
|
|
278
355
|
const output = logCalls.join('\n');
|
|
279
356
|
expect(output).toContain('[warn]');
|
|
280
357
|
expect(output).toContain(core.name);
|
|
281
|
-
expect(output).toContain(
|
|
282
|
-
`component ${core.name} --package @acme/widgets`,
|
|
283
|
-
);
|
|
358
|
+
expect(output).toContain(`component ${core.name} --package @acme/widgets`);
|
|
284
359
|
expect(process.exitCode).toBeUndefined();
|
|
285
360
|
});
|
|
286
361
|
|
|
@@ -12,7 +12,7 @@ export const doc = {
|
|
|
12
12
|
type: 'command',
|
|
13
13
|
name: 'doctor',
|
|
14
14
|
displayName: 'astryx doctor',
|
|
15
|
-
namespace: 'cli',
|
|
15
|
+
namespace: 'cli/commands',
|
|
16
16
|
summary: 'Diagnose Astryx projects and integration packages',
|
|
17
17
|
description:
|
|
18
18
|
'Runs read-only project health diagnostics by default: Node version, @astryxdesign/core ' +
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
validateIntegration,
|
|
18
18
|
} from '../../../api/integration/validate-integration.mjs';
|
|
19
19
|
import {jsonOut} from '../../../foundation/response/json.mjs';
|
|
20
|
-
import {emit, section, records, text} from '../formatters/index.mjs';
|
|
20
|
+
import {emit, section, record, records, text} from '../formatters/index.mjs';
|
|
21
21
|
import {defineCommand} from '../lib/define-command.mjs';
|
|
22
22
|
import {doc as doctorCommand} from './doctor.doc.mjs';
|
|
23
23
|
import {doc as doctorIntegrationGroup} from './doctor-integration.doc.mjs';
|
|
@@ -55,7 +55,7 @@ function integrationLabel(data) {
|
|
|
55
55
|
* @param {import('../../../api/doctor/doctor.mjs').DoctorReport} report
|
|
56
56
|
*/
|
|
57
57
|
function printHuman(report) {
|
|
58
|
-
const {
|
|
58
|
+
const {warn, fail} = report.summary;
|
|
59
59
|
const closing =
|
|
60
60
|
fail > 0
|
|
61
61
|
? 'Some checks failed. Address the items marked [fail] above.'
|
|
@@ -63,18 +63,15 @@ function printHuman(report) {
|
|
|
63
63
|
? 'No failures — but review the [warn] warnings above when you can.'
|
|
64
64
|
: 'All checks passed. Your Astryx setup looks healthy.';
|
|
65
65
|
|
|
66
|
+
// Field names are the JSON keys, so text and --json map one to one.
|
|
66
67
|
emit(
|
|
67
68
|
section('astryx doctor — diagnosing your setup'),
|
|
68
69
|
records(report.checks, {
|
|
69
|
-
fields: ['status', 'label', 'message', 'fix'],
|
|
70
|
-
labels: {label: 'check'},
|
|
70
|
+
fields: ['id', 'status', 'label', 'message', 'fix'],
|
|
71
71
|
format: {status: statusToken},
|
|
72
72
|
}),
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
`${fail} failure${fail === 1 ? '' : 's'}` +
|
|
76
|
-
(info ? `, ${info} info` : ''),
|
|
77
|
-
),
|
|
73
|
+
section('summary'),
|
|
74
|
+
record(report.summary, {fields: ['pass', 'warn', 'fail', 'info']}),
|
|
78
75
|
text(closing),
|
|
79
76
|
);
|
|
80
77
|
}
|
|
@@ -128,14 +125,18 @@ function printTemplateConflicts(data) {
|
|
|
128
125
|
),
|
|
129
126
|
...issueBlocks(data.issues),
|
|
130
127
|
];
|
|
131
|
-
if (data.conflicts.length === 0) {
|
|
132
|
-
output.push(
|
|
133
|
-
|
|
128
|
+
if (data.conflicts.length === 0 && data.issues.length === 0) {
|
|
129
|
+
output.push(
|
|
130
|
+
text('[ok] No template replacements or id conflicts with Core.'),
|
|
131
|
+
);
|
|
132
|
+
} else if (data.conflicts.length > 0) {
|
|
134
133
|
output.push(
|
|
135
134
|
records(data.conflicts, {
|
|
136
135
|
fields: [
|
|
137
136
|
'severity',
|
|
137
|
+
'relationship',
|
|
138
138
|
'id',
|
|
139
|
+
'replaces',
|
|
139
140
|
'integrationPackage',
|
|
140
141
|
'integrationType',
|
|
141
142
|
'integrationName',
|
|
@@ -144,10 +145,7 @@ function printTemplateConflicts(data) {
|
|
|
144
145
|
],
|
|
145
146
|
format: {severity: statusToken},
|
|
146
147
|
}),
|
|
147
|
-
text(
|
|
148
|
-
`${data.conflicts.length} Core template conflict(s). ` +
|
|
149
|
-
'Renaming is recommended but optional; keep the package-qualified command if the overlap is intentional.',
|
|
150
|
-
),
|
|
148
|
+
text(`${data.conflicts.length} Core template relationship(s).`),
|
|
151
149
|
);
|
|
152
150
|
}
|
|
153
151
|
emit(...output);
|
|
@@ -168,7 +166,13 @@ function printComponentConflicts(data) {
|
|
|
168
166
|
} else {
|
|
169
167
|
output.push(
|
|
170
168
|
records(data.conflicts, {
|
|
171
|
-
fields: [
|
|
169
|
+
fields: [
|
|
170
|
+
'severity',
|
|
171
|
+
'name',
|
|
172
|
+
'integrationPackage',
|
|
173
|
+
'message',
|
|
174
|
+
'command',
|
|
175
|
+
],
|
|
172
176
|
format: {severity: statusToken},
|
|
173
177
|
}),
|
|
174
178
|
text(
|
|
@@ -190,6 +194,13 @@ function printDocConflicts(data) {
|
|
|
190
194
|
),
|
|
191
195
|
...issueBlocks(data.issues),
|
|
192
196
|
];
|
|
197
|
+
if (
|
|
198
|
+
!data.issues.some(
|
|
199
|
+
issue => issue.severity === 'error' || issue.code === 'invalid_doc_graph',
|
|
200
|
+
)
|
|
201
|
+
) {
|
|
202
|
+
output.push(text('[ok] The docs tree and every link in these docs check out.'));
|
|
203
|
+
}
|
|
193
204
|
if (data.findings.length === 0) {
|
|
194
205
|
output.push(text('[ok] No doc topics overlap with Core.'));
|
|
195
206
|
} else {
|
|
@@ -275,7 +286,8 @@ async function runAuthoringCheck(program, pkg, kind) {
|
|
|
275
286
|
const structuralErrors = summarizeIssues(result.data.issues).errors;
|
|
276
287
|
const docErrors =
|
|
277
288
|
result.type === 'integration.doc-conflicts'
|
|
278
|
-
? result.data.findings.filter(finding => finding.severity === 'error')
|
|
289
|
+
? result.data.findings.filter(finding => finding.severity === 'error')
|
|
290
|
+
.length
|
|
279
291
|
: 0;
|
|
280
292
|
if (structuralErrors > 0 || docErrors > 0) process.exitCode = 1;
|
|
281
293
|
return NO_RESULT_SET;
|
|
@@ -290,13 +302,6 @@ export function registerDoctor(program) {
|
|
|
290
302
|
fn: doctorFn,
|
|
291
303
|
action: async () => runProjectDoctor(program),
|
|
292
304
|
});
|
|
293
|
-
doctorCmd.addHelpText(
|
|
294
|
-
'after',
|
|
295
|
-
'\nExit code:\n' +
|
|
296
|
-
' 0 no failures (warnings are allowed) — safe as a CI gate\n' +
|
|
297
|
-
' 1 one or more checks failed\n',
|
|
298
|
-
);
|
|
299
|
-
|
|
300
305
|
/** @type {import('commander').Command} */
|
|
301
306
|
let integrationCmd;
|
|
302
307
|
integrationCmd = defineCommand(doctorCmd, doctorIntegrationGroup, {
|
|
@@ -354,3 +354,45 @@ describe('doctor — command', () => {
|
|
|
354
354
|
}
|
|
355
355
|
});
|
|
356
356
|
});
|
|
357
|
+
|
|
358
|
+
describe('doctor — text output mirrors the JSON', () => {
|
|
359
|
+
/** @param {string} line */
|
|
360
|
+
const field = line => /^(\w+):\s+(.*)$/.exec(line)?.slice(1) ?? [line, ''];
|
|
361
|
+
|
|
362
|
+
it('prints every check and summary field under its JSON key', async () => {
|
|
363
|
+
const prevCwd = process.cwd();
|
|
364
|
+
const prevExit = process.exitCode;
|
|
365
|
+
process.chdir(tmpDir);
|
|
366
|
+
try {
|
|
367
|
+
await createProgram().parseAsync(['node', 'astryx', '--json', 'doctor']);
|
|
368
|
+
const {checks, summary} = JSON.parse(logCalls.join('\n')).data;
|
|
369
|
+
logCalls = [];
|
|
370
|
+
await createProgram().parseAsync(['node', 'astryx', 'doctor']);
|
|
371
|
+
const blocks = logCalls
|
|
372
|
+
.join('\n')
|
|
373
|
+
.split(/\n{2,}/)
|
|
374
|
+
.map(block => block.split('\n').map(field));
|
|
375
|
+
|
|
376
|
+
for (const check of checks) {
|
|
377
|
+
const block = blocks.find(fields =>
|
|
378
|
+
fields.some(([key, value]) => key === 'id' && value === check.id),
|
|
379
|
+
);
|
|
380
|
+
expect(block, `no text record for check ${check.id}`).toBeDefined();
|
|
381
|
+
expect(
|
|
382
|
+
/** @type {string[][]} */ (block).map(([key]) => key).sort(),
|
|
383
|
+
).toEqual(Object.keys(check).sort());
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const heading = blocks.findIndex(
|
|
387
|
+
fields => fields.length === 1 && fields[0][0] === 'summary',
|
|
388
|
+
);
|
|
389
|
+
expect(heading, 'no summary section').toBeGreaterThan(-1);
|
|
390
|
+
expect(blocks[heading + 1]).toEqual(
|
|
391
|
+
Object.entries(summary).map(([key, count]) => [key, String(count)]),
|
|
392
|
+
);
|
|
393
|
+
} finally {
|
|
394
|
+
process.chdir(prevCwd);
|
|
395
|
+
process.exitCode = prevExit;
|
|
396
|
+
}
|
|
397
|
+
}, 60_000);
|
|
398
|
+
});
|
|
@@ -10,27 +10,37 @@ export const doc = {
|
|
|
10
10
|
type: 'command',
|
|
11
11
|
name: 'gap-report',
|
|
12
12
|
displayName: 'astryx gap-report',
|
|
13
|
-
namespace: 'cli',
|
|
13
|
+
namespace: 'cli/commands',
|
|
14
14
|
summary: 'Route a design-system gap to its owning package',
|
|
15
15
|
description:
|
|
16
16
|
'Reports a missing component, variant, layout, styling, accessibility, API, or documentation capability. The command selects an explicit package first, then a unique component owner, then Core. The report fans out to every effective handler: project config first, then each loaded integration in config order. Public handlers require --confirm-public per handler; internal handlers always run. A handler failure is isolated and does not prevent later handlers.',
|
|
17
17
|
fn: 'gapReport',
|
|
18
|
-
args: [
|
|
18
|
+
args: [
|
|
19
|
+
{
|
|
20
|
+
name: 'component',
|
|
21
|
+
param: 'component',
|
|
22
|
+
required: false,
|
|
23
|
+
description:
|
|
24
|
+
'Component or design-system area the gap is about, up to 120 characters. Required unless --list-categories is set.',
|
|
25
|
+
},
|
|
26
|
+
],
|
|
19
27
|
options: [
|
|
20
28
|
{
|
|
21
29
|
flag: '--category <category>',
|
|
22
30
|
param: 'options.category',
|
|
23
|
-
description:
|
|
31
|
+
description:
|
|
32
|
+
'Gap category (run --list-categories for values). Required unless --list-categories is set.',
|
|
24
33
|
},
|
|
25
34
|
{
|
|
26
35
|
flag: '--reason <reason>',
|
|
27
36
|
param: 'options.reason',
|
|
28
|
-
description:
|
|
37
|
+
description:
|
|
38
|
+
'What capability was missing or difficult, up to 2000 characters. Required unless --list-categories is set.',
|
|
29
39
|
},
|
|
30
40
|
{
|
|
31
41
|
flag: '--additional-context <text>',
|
|
32
42
|
param: 'options.detail',
|
|
33
|
-
description: 'Optional additional context',
|
|
43
|
+
description: 'Optional additional context, up to 8000 characters',
|
|
34
44
|
},
|
|
35
45
|
{
|
|
36
46
|
flag: '--package <pkg>',
|
|
@@ -45,7 +55,8 @@ export const doc = {
|
|
|
45
55
|
{
|
|
46
56
|
flag: '--list-categories',
|
|
47
57
|
param: 'options.listCategories',
|
|
48
|
-
description:
|
|
58
|
+
description:
|
|
59
|
+
'List valid report categories without filing; the component and the other gap-report options are ignored',
|
|
49
60
|
},
|
|
50
61
|
],
|
|
51
62
|
examples: [
|
|
@@ -196,3 +196,75 @@ export default {};\n`,
|
|
|
196
196
|
});
|
|
197
197
|
});
|
|
198
198
|
});
|
|
199
|
+
|
|
200
|
+
describe('gap-report control docs', () => {
|
|
201
|
+
const REQUIRED = 'Required unless --list-categories is set.';
|
|
202
|
+
|
|
203
|
+
it('help and manifest say which inputs are required and how long they may be', async () => {
|
|
204
|
+
const help = await runCli(['gap-report', '--help']);
|
|
205
|
+
expect(help.status).toBe(0);
|
|
206
|
+
const manifest = JSON.parse((await runCli(['manifest', '--json'])).stdout);
|
|
207
|
+
const entry = manifest.data.commands.find(
|
|
208
|
+
(/** @type {{name: string}} */ command) => command.name === 'gap-report',
|
|
209
|
+
);
|
|
210
|
+
/** @param {string} flag @returns {string} */
|
|
211
|
+
const option = flag =>
|
|
212
|
+
entry.options.find(
|
|
213
|
+
(/** @type {{flag: string}} */ item) => item.flag.split(' ')[0] === flag,
|
|
214
|
+
)?.description ?? '';
|
|
215
|
+
const component = entry.arguments[0].description;
|
|
216
|
+
|
|
217
|
+
for (const text of [component, option('--category'), option('--reason')]) {
|
|
218
|
+
expect(text).toContain(REQUIRED);
|
|
219
|
+
expect(help.stdout).toContain(text);
|
|
220
|
+
}
|
|
221
|
+
expect(option('--list-categories')).toContain(
|
|
222
|
+
'the component and the other gap-report options are ignored',
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-gap-limits-'));
|
|
226
|
+
try {
|
|
227
|
+
fs.writeFileSync(
|
|
228
|
+
path.join(cwd, 'package.json'),
|
|
229
|
+
JSON.stringify({name: 'fixture-app'}),
|
|
230
|
+
);
|
|
231
|
+
const base = {cwd, category: /** @type {const} */ ('docs_gap'), reason: 'x'};
|
|
232
|
+
/** @type {Array<[string, (value: string) => Promise<unknown>]>} */
|
|
233
|
+
const limits = [
|
|
234
|
+
[component, value => gapReport(value, base)],
|
|
235
|
+
[option('--reason'), value => gapReport('Button', {...base, reason: value})],
|
|
236
|
+
[
|
|
237
|
+
option('--additional-context'),
|
|
238
|
+
value => gapReport('Button', {...base, detail: value}),
|
|
239
|
+
],
|
|
240
|
+
];
|
|
241
|
+
for (const [text, call] of limits) {
|
|
242
|
+
const limit = Number(/up to (\d+) characters/.exec(text)?.[1]);
|
|
243
|
+
expect(limit, text).toBeGreaterThan(0);
|
|
244
|
+
await expect(call('x'.repeat(limit))).resolves.toMatchObject({
|
|
245
|
+
type: 'gap-report.file',
|
|
246
|
+
});
|
|
247
|
+
await expect(call('x'.repeat(limit + 1))).rejects.toMatchObject({
|
|
248
|
+
code: 'ERR_INVALID_ARGUMENT',
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
} finally {
|
|
252
|
+
fs.rmSync(cwd, {recursive: true, force: true});
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it('enforces the documented requirement', async () => {
|
|
257
|
+
for (const [component, options] of [
|
|
258
|
+
[undefined, {category: 'docs_gap', reason: 'x'}],
|
|
259
|
+
['Button', {reason: 'x'}],
|
|
260
|
+
['Button', {category: 'docs_gap'}],
|
|
261
|
+
]) {
|
|
262
|
+
await expect(gapReport(component, options)).rejects.toMatchObject({
|
|
263
|
+
code: 'ERR_MISSING_ARGUMENT',
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
await expect(
|
|
267
|
+
gapReport(undefined, {listCategories: true, category: 'not_real', package: 'nope'}),
|
|
268
|
+
).resolves.toMatchObject({type: 'gap-report.categories'});
|
|
269
|
+
});
|
|
270
|
+
});
|
|
@@ -20,7 +20,6 @@ import {defineCommand} from '../../lib/define-command.mjs';
|
|
|
20
20
|
import {resultSet} from '../../../../foundation/debug/index.mjs';
|
|
21
21
|
import {ERROR_CODES} from '../../../../foundation/response/error-codes.mjs';
|
|
22
22
|
import {hook as hookApi} from '../../../../api/hook/hook.mjs';
|
|
23
|
-
import {findRelatedBlocks} from '../../../../api/template/template.mjs';
|
|
24
23
|
import {doc as hookCommand} from '../hook.doc.mjs';
|
|
25
24
|
import {doc as hookFn} from '../../../../api/hook/hook.doc.mjs';
|
|
26
25
|
|
|
@@ -169,24 +168,15 @@ export function registerHook(program) {
|
|
|
169
168
|
)
|
|
170
169
|
: formatHookFull(result.data);
|
|
171
170
|
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const allBlocks = [];
|
|
176
|
-
for (const comp of relatedComps) {
|
|
177
|
-
const blocks = await findRelatedBlocks(comp);
|
|
178
|
-
for (const b of blocks) {
|
|
179
|
-
if (!allBlocks.some(existing => existing.dirName === b.dirName)) {
|
|
180
|
-
allBlocks.push(b);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
171
|
+
// Text projects the envelope only. Block templates are JSON-backed
|
|
172
|
+
// under `component <name> --blocks`.
|
|
173
|
+
const related = result.data.relatedComponents ?? [];
|
|
185
174
|
emit(
|
|
186
175
|
code(doc),
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
176
|
+
related.length > 0 &&
|
|
177
|
+
text(
|
|
178
|
+
`Block templates: ${run} component <name> --blocks for ${related.join(', ')}`,
|
|
179
|
+
),
|
|
190
180
|
);
|
|
191
181
|
break;
|
|
192
182
|
}
|
|
@@ -12,7 +12,7 @@ export const doc = {
|
|
|
12
12
|
type: 'command',
|
|
13
13
|
name: 'hook',
|
|
14
14
|
displayName: 'astryx hook',
|
|
15
|
-
namespace: 'cli',
|
|
15
|
+
namespace: 'cli/commands',
|
|
16
16
|
summary: 'List hooks or print hook docs',
|
|
17
17
|
description:
|
|
18
18
|
'Resolves a hook by name and prints its authored doc, or lists the catalog grouped ' +
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file `astryx hook <name>` text is a projection of `hook.detail`: it shows
|
|
5
|
+
* nothing the JSON envelope does not carry.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {describe, it, expect} from 'vitest';
|
|
9
|
+
import {runCli} from '../../../test-utils/run-cli.mjs';
|
|
10
|
+
import {findRelatedBlocks} from '../../../api/template/template.mjs';
|
|
11
|
+
|
|
12
|
+
const HOOK = 'useAnnounce';
|
|
13
|
+
|
|
14
|
+
describe('hook detail text projection', () => {
|
|
15
|
+
it('prints no block templates that the JSON envelope lacks', async () => {
|
|
16
|
+
const json = await runCli(['--json', 'hook', HOOK]);
|
|
17
|
+
expect(json.status).toBe(0);
|
|
18
|
+
const envelope = JSON.parse(json.stdout);
|
|
19
|
+
expect(envelope.type).toBe('hook.detail');
|
|
20
|
+
const related = envelope.data.relatedComponents;
|
|
21
|
+
expect(related.length).toBeGreaterThan(0);
|
|
22
|
+
|
|
23
|
+
const blockNames = [];
|
|
24
|
+
for (const component of related) {
|
|
25
|
+
for (const block of await findRelatedBlocks(component)) {
|
|
26
|
+
blockNames.push(block.dirName);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
expect(blockNames.length).toBeGreaterThan(0);
|
|
30
|
+
|
|
31
|
+
const text = await runCli(['hook', HOOK]);
|
|
32
|
+
expect(text.status).toBe(0);
|
|
33
|
+
const shownButNotInJson = blockNames.filter(
|
|
34
|
+
name => text.stdout.includes(name) && !json.stdout.includes(name),
|
|
35
|
+
);
|
|
36
|
+
expect(shownButNotInJson).toEqual([]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('points at the JSON-backed block lookup for each related component', async () => {
|
|
40
|
+
const text = await runCli(['hook', HOOK]);
|
|
41
|
+
expect(text.stdout).toMatch(/component <name> --blocks/);
|
|
42
|
+
expect(text.stdout).toContain('VisuallyHidden');
|
|
43
|
+
expect(text.stdout).toContain('Toast');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -12,43 +12,51 @@ export const doc = {
|
|
|
12
12
|
type: 'command',
|
|
13
13
|
name: 'init',
|
|
14
14
|
displayName: 'astryx init',
|
|
15
|
-
namespace: 'cli',
|
|
15
|
+
namespace: 'cli/commands',
|
|
16
16
|
summary: 'Initialize the design system in your project',
|
|
17
17
|
description:
|
|
18
18
|
'Non-interactive project setup (no prompts, so it behaves the same for humans, ' +
|
|
19
19
|
'agents, and CI). By default it installs the AGENTS.md/CLAUDE.md agent-docs, ' +
|
|
20
20
|
'including guidance from configured integrations, and prints getting-started ' +
|
|
21
21
|
'guidance; features/--all add theme and page-building ' +
|
|
22
|
-
'guidance and
|
|
22
|
+
'guidance and write an annotated theme template.',
|
|
23
23
|
fn: 'init',
|
|
24
24
|
options: [
|
|
25
25
|
{
|
|
26
26
|
flag: '--features <list>',
|
|
27
27
|
param: 'options.features',
|
|
28
28
|
description:
|
|
29
|
-
'Comma-separated features to install (agents, theme, template)'
|
|
29
|
+
'Comma-separated features to install (agents, theme, template). An unknown feature exits 1 with ERR_UNKNOWN_FEATURE. ' +
|
|
30
|
+
'Ignored with --all or --remove-agents',
|
|
30
31
|
},
|
|
31
32
|
{
|
|
32
33
|
flag: '--all',
|
|
33
34
|
param: 'options.all',
|
|
34
|
-
description: 'Install all features,
|
|
35
|
+
description: 'Install all features (agents, theme, template); overrides --features',
|
|
35
36
|
},
|
|
36
37
|
{
|
|
37
38
|
flag: '--remove-agents',
|
|
38
39
|
param: 'options.removeAgents',
|
|
39
|
-
description:
|
|
40
|
+
description:
|
|
41
|
+
'Remove the managed block from AGENTS.md, CLAUDE.md, .claude/CLAUDE.md, .cursorrules, .hermes.md and HERMES.md ' +
|
|
42
|
+
"(deleting AGENTS.md or .claude/CLAUDE.md when only init's heading is left) and do nothing else. " +
|
|
43
|
+
'--features, --all, --agent and --agent-docs-path are ignored; a file written with --agent-docs-path keeps its block',
|
|
40
44
|
},
|
|
41
45
|
{
|
|
42
46
|
flag: '--agent <tool>',
|
|
43
47
|
param: 'options.agent',
|
|
44
48
|
choices: ['claude', 'cursor', 'codex', 'hermes', 'muse', 'all'],
|
|
45
49
|
description:
|
|
46
|
-
'Target AI tool for agent docs: claude, cursor, codex, hermes, muse, all'
|
|
50
|
+
'Target AI tool for agent docs: claude, cursor, codex, hermes, muse, all. An unknown tool exits 1 with ERR_UNKNOWN_AGENT. ' +
|
|
51
|
+
'Used only when agent docs are installed (the default, --all, or --features agents); --agent-docs-path takes precedence',
|
|
47
52
|
},
|
|
48
53
|
{
|
|
49
54
|
flag: '--agent-docs-path <path...>',
|
|
50
55
|
param: 'options.agentDocsPath',
|
|
51
|
-
description:
|
|
56
|
+
description:
|
|
57
|
+
'Explicit file path(s) for agent docs, inside the project; takes precedence over --agent. ' +
|
|
58
|
+
'If any path is outside the project, no agent docs are written and the command exits 1. ' +
|
|
59
|
+
'Used only when agent docs are installed',
|
|
52
60
|
},
|
|
53
61
|
],
|
|
54
62
|
examples: [
|
|
@@ -57,10 +65,13 @@ export const doc = {
|
|
|
57
65
|
{label: 'Machine-readable receipt', cli: 'astryx init --json'},
|
|
58
66
|
],
|
|
59
67
|
exitCodes: [
|
|
60
|
-
{
|
|
68
|
+
{
|
|
69
|
+
code: 0,
|
|
70
|
+
when: 'success, including agent docs that could not be written for a reason other than a path escape (reported as docsError)',
|
|
71
|
+
},
|
|
61
72
|
{
|
|
62
73
|
code: 1,
|
|
63
|
-
when: 'unknown --agent
|
|
74
|
+
when: 'an unknown --agent or feature, or an --agent-docs-path outside the project',
|
|
64
75
|
},
|
|
65
76
|
],
|
|
66
77
|
related: ['doctor', 'upgrade', 'build', 'theme'],
|