@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.2
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 +119 -0
- package/README.md +175 -154
- package/api/build/_adapter.d.mts +8 -0
- package/api/build/_adapter.mjs +12 -1
- package/api/build/build.doc.mjs +4 -0
- package/api/build/help/help.mjs +1 -1
- package/api/build/kit/kit.mjs +3 -11
- package/api/component/_adapter.d.mts +72 -1
- package/api/component/_adapter.mjs +212 -18
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +82 -15
- package/api/component/component.test.mjs +80 -0
- package/api/component/doc-links.test.mjs +386 -0
- package/api/component/integration-export-name.test.mjs +644 -0
- package/api/component/list/list.mjs +42 -4
- package/api/discover/_adapter.d.mts +132 -12
- package/api/discover/_adapter.mjs +488 -27
- package/api/discover/_adapter.test.mjs +599 -17
- package/api/discover/_catalog-view.d.mts +16 -5
- package/api/discover/_catalog-view.mjs +32 -8
- package/api/discover/detail/doc/doc.mjs +9 -1
- package/api/discover/discover.d.mts +11 -0
- package/api/discover/discover.doc.mjs +9 -7
- package/api/discover/discover.mjs +121 -19
- package/api/discover/discover.type.d.mts +20 -7
- package/api/discover/discover.type.mjs +17 -7
- package/api/discover/list/list.d.mts +4 -3
- package/api/discover/list/list.mjs +17 -10
- package/api/docs/_adapter.d.mts +74 -0
- package/api/docs/_adapter.mjs +553 -16
- package/api/docs/docs.doc.mjs +2 -1
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.test.mjs +5 -2
- package/api/docs/integration-tree.test.mjs +22 -0
- package/api/docs/integrationDocs.test.mjs +124 -0
- package/api/docs/list/list.mjs +12 -2
- package/api/docs/reference-blocks.test.mjs +1 -3
- package/api/doctor/_adapter.d.mts +108 -0
- package/api/doctor/_adapter.mjs +223 -4
- package/api/doctor/doctor.d.mts +199 -0
- package/api/doctor/doctor.doc.mjs +3 -2
- package/api/doctor/doctor.mjs +530 -34
- package/api/doctor/doctor.test.mjs +180 -14
- package/api/doctor/release-checks.test.mjs +156 -0
- package/api/doctor/theme-checks.mjs +17 -4
- package/api/doctor/theme-checks.test.mjs +223 -7
- package/api/error.d.mts +10 -0
- package/api/error.mjs +25 -0
- package/api/gap-report/gap-report.d.mts +3 -0
- package/api/gap-report/gap-report.doc.mjs +11 -3
- package/api/gap-report/gap-report.mjs +219 -52
- package/api/gap-report/gap-report.test.mjs +233 -0
- package/api/gap-report/gap-report.type.d.mts +41 -0
- package/api/gap-report/gap-report.type.mjs +18 -0
- package/api/hook/_adapter.mjs +3 -11
- package/api/hook/hook.doc.mjs +4 -0
- package/api/hook/list/list.d.mts +1 -1
- package/api/index.d.mts +2 -0
- package/api/index.mjs +2 -0
- package/api/init/_adapter.d.mts +22 -0
- package/api/init/_adapter.mjs +59 -0
- package/api/init/init.d.mts +7 -5
- package/api/init/init.doc.mjs +28 -7
- package/api/init/init.mjs +28 -4
- package/api/init/init.type.d.mts +48 -3
- package/api/init/init.type.mjs +37 -3
- package/api/init/run/run.d.mts +1 -1
- package/api/init/run/run.mjs +17 -6
- package/api/init/user/user.d.mts +14 -0
- package/api/init/user/user.mjs +87 -0
- package/api/init/user/user.test.mjs +232 -0
- package/api/integration/_adapter.d.mts +45 -0
- package/api/integration/_adapter.mjs +112 -0
- package/api/integration/add-contribution.component-names.test.mjs +66 -0
- package/api/integration/add-contribution.mjs +8 -4
- package/api/integration/add-contribution.test.mjs +4 -2
- package/api/integration/authoring-checks.mjs +110 -6
- package/api/integration/authoring-checks.test.mjs +808 -0
- package/api/integration/authoring-checks.type.d.mts +143 -0
- package/api/integration/authoring-checks.type.mjs +74 -2
- package/api/integration/check/check.d.mts +96 -0
- package/api/integration/check/check.mjs +357 -0
- package/api/integration/check/check.test.mjs +489 -0
- package/api/integration/integration-check.type.d.mts +118 -0
- package/api/integration/integration-check.type.mjs +84 -0
- package/api/integration/integrationCheck.doc.d.mts +10 -0
- package/api/integration/integrationCheck.doc.mjs +73 -0
- package/api/integration/integrationComponentConflicts.doc.mjs +45 -6
- package/api/integration/integrationDocConflicts.doc.mjs +22 -5
- package/api/integration/pack-check.mjs +364 -120
- package/api/integration/pack-check.test.mjs +730 -10
- package/api/integration/validate-integration-fixes.test.mjs +67 -0
- package/api/integration/validate-integration.d.mts +8 -0
- package/api/integration/validate-integration.mjs +63 -9
- package/api/integration/validate-integration.test.mjs +88 -8
- package/api/integration/validate-integration.type.d.mts +16 -0
- package/api/integration/validate-integration.type.mjs +14 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +19 -3
- package/api/search/_adapter.d.mts +11 -0
- package/api/search/_adapter.mjs +25 -0
- package/api/search/search.d.mts +82 -13
- package/api/search/search.doc.mjs +8 -3
- package/api/search/search.domain-priority.test.mjs +108 -18
- package/api/search/search.integration-check.test.mjs +24 -0
- package/api/search/search.mjs +645 -64
- package/api/search/search.test.mjs +179 -1
- package/api/search/search.type.d.mts +14 -1
- package/api/search/search.type.mjs +6 -1
- package/api/swizzle/_adapter.mjs +2 -2
- package/api/swizzle/copy/copy.mjs +29 -15
- package/api/template/template-integration.test.mjs +1 -1
- package/api/template/template.test.mjs +120 -3
- package/api/theme/_adapter.d.mts +16 -0
- package/api/theme/_adapter.mjs +32 -5
- package/api/theme/build/build.d.mts +2 -1
- package/api/theme/build/build.family.test.mjs +64 -0
- package/api/theme/build/build.mjs +250 -38
- package/api/theme/build/build.packed-old-core.test.mjs +20 -3
- package/api/theme/build/font-warning.mjs +5 -3
- package/api/theme/build/font-warning.test.mjs +2 -1
- package/api/theme/remove/remove.test.mjs +2 -2
- package/api/theme/targets/targets.mjs +3 -10
- package/api/theme/themeBuild.doc.mjs +4 -4
- package/api/theme/themeTargets.doc.mjs +4 -0
- package/api/theme/use/use.test.mjs +1 -1
- package/api/upgrade/_adapter.d.mts +40 -2
- package/api/upgrade/_adapter.mjs +118 -5
- package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
- package/api/upgrade/run/run.mjs +35 -2
- package/api/upgrade/status/status.d.mts +21 -5
- package/api/upgrade/status/status.mjs +45 -8
- package/api/upgrade/upgrade.doc.mjs +6 -3
- package/api/upgrade/upgrade.mjs +5 -1
- package/api/upgrade/upgrade.type.d.mts +23 -0
- package/api/upgrade/upgrade.type.mjs +16 -1
- package/assets/codemods/__tests__/registry.test.mjs +1 -0
- package/assets/codemods/registry.mjs +1 -0
- package/assets/codemods/runner.mjs +7 -1
- package/assets/codemods/transforms/v0.7.2/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +120 -0
- package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
- package/assets/codemods/transforms/v0.7.2/migrate-list-edge-compensation-to-edge.mjs +198 -0
- package/assets/discover/official-packages.json +367 -0
- package/assets/docs/README.md +10 -0
- package/assets/docs/author-a-theme.doc.mjs +3 -3
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +26 -6
- package/assets/docs/styling-overview.doc.mjs +1 -1
- package/assets/docs/theme.doc.dense.mjs +1 -1
- package/assets/docs/theme.doc.mjs +2 -2
- package/assets/docs/theme.doc.zh.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +22 -2
- package/assets/docs/tree/add-a-theme.doc.mjs +13 -3
- package/assets/docs/tree/add-a-topic.doc.mjs +54 -9
- package/assets/docs/tree/agent-guidance.doc.mjs +19 -5
- package/assets/docs/tree/block-template.doc.mjs +8 -20
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +4 -0
- package/assets/docs/tree/check-the-props.doc.mjs +201 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +69 -11
- package/assets/docs/tree/checks.doc.mjs +32 -24
- package/assets/docs/tree/ci-and-containers.doc.mjs +88 -0
- package/assets/docs/tree/cli-command.doc.mjs +142 -0
- package/assets/docs/tree/cli.doc.mjs +6 -0
- package/assets/docs/tree/codemods.doc.mjs +17 -7
- package/assets/docs/tree/commands.doc.mjs +7 -1
- package/assets/docs/tree/component-family.doc.mjs +8 -6
- package/assets/docs/tree/component-imports.doc.mjs +21 -3
- package/assets/docs/tree/components.doc.mjs +7 -1
- package/assets/docs/tree/computer-agent-guide.doc.mjs +160 -0
- package/assets/docs/tree/computer-integrations.doc.mjs +93 -0
- package/assets/docs/tree/configuration.doc.mjs +7 -3
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
- package/assets/docs/tree/define-the-theme.doc.mjs +6 -5
- package/assets/docs/tree/describe-the-component.doc.mjs +3 -3
- package/assets/docs/tree/docs.doc.mjs +9 -3
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +3 -3
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +19 -9
- package/assets/docs/tree/fonts-and-assets.doc.mjs +2 -2
- package/assets/docs/tree/generate-a-palette.doc.mjs +7 -5
- package/assets/docs/tree/global-integrations.doc.mjs +124 -0
- package/assets/docs/tree/global.doc.mjs +131 -0
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +5 -5
- package/assets/docs/tree/install-once.doc.mjs +105 -0
- package/assets/docs/tree/integrations.doc.mjs +13 -1
- package/assets/docs/tree/layout-spacing.doc.mjs +2 -3
- package/assets/docs/tree/layout.doc.mjs +6 -6
- package/assets/docs/tree/links.doc.mjs +7 -6
- package/assets/docs/tree/migration-setup.doc.mjs +3 -2
- package/assets/docs/tree/migration-verification.doc.mjs +0 -1
- package/assets/docs/tree/migration.doc.mjs +0 -1
- package/assets/docs/tree/monorepos.doc.mjs +84 -0
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +4 -8
- package/assets/docs/tree/problems.doc.mjs +205 -0
- package/assets/docs/tree/project-global-or-both.doc.mjs +131 -0
- package/assets/docs/tree/publishing.doc.mjs +6 -6
- package/assets/docs/tree/quick-start.doc.mjs +53 -27
- package/assets/docs/tree/reference.doc.mjs +192 -0
- package/assets/docs/tree/replace-a-core-component.doc.mjs +15 -7
- package/assets/docs/tree/replace-a-core-template.doc.mjs +10 -12
- package/assets/docs/tree/scaffold.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +9 -11
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +17 -5
- package/assets/docs/tree/short-and-findable.doc.mjs +9 -8
- package/assets/docs/tree/single-component.doc.mjs +15 -6
- package/assets/docs/tree/start-a-template.doc.mjs +18 -8
- package/assets/docs/tree/subcomponent.doc.mjs +6 -6
- package/assets/docs/tree/template-assets.doc.mjs +2 -2
- package/assets/docs/tree/template-doc-overview.doc.mjs +6 -17
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-icons.doc.mjs +1 -1
- package/assets/docs/tree/template-images-media.doc.mjs +1 -1
- package/assets/docs/tree/template-styles.doc.mjs +2 -2
- package/assets/docs/tree/templates.doc.mjs +7 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +7 -7
- package/assets/docs/tree/test-template-in-app.doc.mjs +5 -5
- package/assets/docs/tree/themes.doc.mjs +4 -0
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/troubleshooting.doc.mjs +29 -13
- package/assets/docs/tree/type-scale.doc.mjs +3 -3
- package/assets/docs/tree/uninstall.doc.mjs +109 -0
- package/assets/docs/tree/updates.doc.mjs +92 -0
- package/assets/docs/tree/upgrading.doc.mjs +6 -6
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +14 -2
- package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +10 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +7 -6
- package/assets/docs/use-a-theme.doc.mjs +2 -2
- package/assets/docs/working-with-ai.doc.mjs +66 -13
- package/assets/theme.template.ts +1 -1
- package/authoring/codemod/codemod.doc.mjs +7 -3
- package/authoring/config/config.doc.mjs +9 -6
- package/authoring/config/type.ts +4 -2
- package/authoring/debug/parse.d.mts +5 -5
- package/authoring/discover/discover.doc.mjs +7 -1
- package/authoring/doctypes/_schema.d.mts +8 -3
- package/authoring/doctypes/_schema.mjs +1 -0
- package/authoring/doctypes/base/graph-fields.doc.mjs +6 -4
- package/authoring/doctypes/command/command.doc.mjs +20 -12
- package/authoring/doctypes/command/type.ts +14 -0
- package/authoring/doctypes/component/component.doc.mjs +30 -27
- package/authoring/doctypes/component/type.ts +21 -8
- package/authoring/doctypes/enum/enum.doc.mjs +7 -4
- package/authoring/doctypes/function/function.doc.mjs +9 -8
- package/authoring/doctypes/hook/hook.doc.mjs +5 -4
- package/authoring/doctypes/hook/type.ts +4 -0
- package/authoring/doctypes/namespace/namespace.doc.mjs +7 -6
- package/authoring/doctypes/reference/reference.doc.mjs +12 -11
- package/authoring/doctypes/schema/schema.doc.mjs +9 -9
- package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
- package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
- package/authoring/doctypes/template/parse.d.mts +6 -2
- package/authoring/doctypes/template/parse.mjs +3 -1
- package/authoring/doctypes/template/template.doc.mjs +3 -3
- package/authoring/doctypes/template/type.ts +22 -0
- package/authoring/doctypes/theme/theme.doc.mjs +2 -2
- package/authoring/gap-report/gap-report.doc.mjs +2 -2
- package/authoring/identity/identity.doc.mjs +3 -3
- package/authoring/index.d.ts +2 -0
- package/authoring/integration/integration.doc.mjs +30 -6
- package/authoring/integration/parse.test.mjs +21 -0
- package/authoring/integration/schema.d.mts +16 -3
- package/authoring/integration/schema.mjs +34 -2
- package/authoring/integration/type.ts +12 -0
- package/clients/cli/bin/astryx.mjs +20 -3
- package/clients/cli/cli-command.test.mjs +166 -0
- package/clients/cli/commands/blog.doc.mjs +1 -0
- package/clients/cli/commands/build-theme.batch-report.test.mjs +17 -3
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- package/clients/cli/commands/build-theme.mjs +26 -13
- package/clients/cli/commands/build-theme.path-safety.test.mjs +224 -6
- package/clients/cli/commands/build-theme.registry.test.mjs +5 -2
- package/clients/cli/commands/build.doc.mjs +1 -0
- package/clients/cli/commands/build.exit-codes-doc.test.mjs +4 -0
- package/clients/cli/commands/cli-postinstall.test.mjs +49 -1
- package/clients/cli/commands/component.doc.mjs +1 -0
- package/clients/cli/commands/discover.broken-integration.test.mjs +11 -7
- package/clients/cli/commands/discover.doc.mjs +9 -1
- package/clients/cli/commands/discover.mjs +144 -93
- package/clients/cli/commands/discover.no-source.test.mjs +448 -33
- package/clients/cli/commands/discover.sources.test.mjs +20 -1
- package/clients/cli/commands/docs.doc.mjs +1 -0
- package/clients/cli/commands/docs.mjs +49 -19
- package/clients/cli/commands/docs.test.mjs +2 -2
- package/clients/cli/commands/doctor-integration-components.doc.mjs +19 -4
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +20 -5
- package/clients/cli/commands/doctor-integration-templates.doc.mjs +1 -0
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +22 -2
- package/clients/cli/commands/doctor-integration.test.mjs +888 -3
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +292 -7
- package/clients/cli/commands/doctor.test.mjs +10 -4
- package/clients/cli/commands/gap-report.doc.mjs +15 -2
- package/clients/cli/commands/gap-report.mjs +24 -2
- package/clients/cli/commands/gap-report.test.mjs +79 -0
- package/clients/cli/commands/hook.doc.mjs +1 -0
- package/clients/cli/commands/init.behavior.test.mjs +5 -0
- package/clients/cli/commands/init.doc.mjs +29 -3
- package/clients/cli/commands/integration-add.doc.mjs +7 -0
- package/clients/cli/commands/integration-authoring.test.mjs +49 -3
- package/clients/cli/commands/integration-check.doc.mjs +93 -0
- package/clients/cli/commands/integration-check.test.mjs +441 -0
- package/clients/cli/commands/integration-pack.doc.mjs +8 -1
- package/clients/cli/commands/integration-verify.doc.mjs +8 -1
- package/clients/cli/commands/integration.doc.mjs +6 -2
- package/clients/cli/commands/integration.mjs +119 -7
- package/clients/cli/commands/json-contract.test.mjs +11 -2
- package/clients/cli/commands/manifest.doc.mjs +1 -0
- package/clients/cli/commands/outside-project.test.mjs +774 -0
- package/clients/cli/commands/search.doc.mjs +1 -0
- package/clients/cli/commands/search.mjs +16 -11
- package/clients/cli/commands/search.test.mjs +429 -296
- package/clients/cli/commands/setup-nudge.test.mjs +102 -2
- package/clients/cli/commands/swizzle.doc.mjs +7 -0
- package/clients/cli/commands/swizzle.mjs +5 -3
- package/clients/cli/commands/swizzle.routing.test.mjs +19 -2
- package/clients/cli/commands/template.doc.mjs +1 -0
- package/clients/cli/commands/text-json-parity.test.mjs +5 -0
- package/clients/cli/commands/theme-add-lifecycle.test.mjs +3 -3
- package/clients/cli/commands/theme-add.doc.mjs +8 -1
- package/clients/cli/commands/theme-build.doc.mjs +3 -2
- package/clients/cli/commands/theme-eject.doc.mjs +1 -0
- package/clients/cli/commands/theme-list.behavior.test.mjs +6 -0
- package/clients/cli/commands/theme-list.doc.mjs +1 -0
- package/clients/cli/commands/theme-palette-generate.doc.mjs +1 -0
- package/clients/cli/commands/theme-remove.doc.mjs +7 -0
- package/clients/cli/commands/theme-targets.doc.mjs +1 -0
- package/clients/cli/commands/theme-template.doc.mjs +1 -0
- package/clients/cli/commands/theme-use.doc.mjs +7 -0
- package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +22 -1
- package/clients/cli/commands/upgrade.file-protection.test.mjs +3 -2
- package/clients/cli/commands/upgrade.hook-output.test.mjs +2 -1
- package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
- package/clients/cli/index.mjs +112 -16
- package/clients/cli/lib/cli-error.mjs +4 -1
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +2 -2
- package/clients/cli/lib/json-shim.mjs +3 -1
- package/clients/cli/lib/manifest.d.ts +9 -0
- package/clients/cli/lib/manifest.mjs +17 -1
- package/clients/cli/lib/manifest.test.mjs +25 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +35 -6
- package/foundation/agent-docs/agent-doc-state.mjs +66 -6
- package/foundation/agent-docs/agent-docs.d.mts +4 -3
- package/foundation/agent-docs/agent-docs.mjs +11 -9
- package/foundation/agent-docs/computer-agent-text.d.mts +133 -0
- package/foundation/agent-docs/computer-agent-text.mjs +623 -0
- package/foundation/agent-docs/computer-agent-text.test.mjs +602 -0
- package/foundation/config/project.d.mts +35 -3
- package/foundation/config/project.mjs +226 -7
- package/foundation/config/project.test.mjs +66 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.mjs +2 -1
- package/foundation/discovery/cli-self-docs.mjs +20 -3
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-discovery.d.mts +190 -10
- package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
- package/foundation/discovery/component-discovery.mjs +864 -56
- package/foundation/discovery/component-discovery.test.mjs +96 -0
- package/foundation/discovery/component-replacement.mjs +20 -1
- package/foundation/discovery/component-replacement.test.mjs +40 -0
- package/foundation/discovery/copied-passages.d.mts +216 -0
- package/foundation/discovery/copied-passages.mjs +720 -0
- package/foundation/discovery/copied-passages.test.mjs +124 -0
- package/foundation/discovery/doc-consistency.d.mts +34 -0
- package/foundation/discovery/doc-consistency.mjs +513 -0
- package/foundation/discovery/doc-consistency.test.mjs +347 -0
- package/foundation/discovery/doc-fluff.d.mts +112 -0
- package/foundation/discovery/doc-fluff.mjs +328 -0
- package/foundation/discovery/doc-fluff.test.mjs +142 -0
- package/foundation/discovery/doc-types.d.mts +157 -0
- package/foundation/discovery/doc-types.mjs +1231 -0
- package/foundation/discovery/doc-types.test.mjs +744 -0
- package/foundation/discovery/docs-discovery.d.mts +88 -0
- package/foundation/discovery/docs-discovery.mjs +83 -2
- package/foundation/discovery/integration-doc-files.d.mts +22 -0
- package/foundation/discovery/integration-doc-files.mjs +231 -0
- package/foundation/discovery/integration-doc-files.test.mjs +246 -0
- package/foundation/discovery/module-exports.d.mts +27 -0
- package/foundation/discovery/module-exports.mjs +356 -31
- package/foundation/discovery/module-exports.test.mjs +172 -0
- package/foundation/discovery/package-tsconfig.d.mts +14 -0
- package/foundation/discovery/package-tsconfig.mjs +228 -0
- package/foundation/discovery/package-tsconfig.test.mjs +210 -0
- package/foundation/discovery/project-typescript.d.mts +32 -0
- package/foundation/discovery/project-typescript.mjs +89 -0
- package/foundation/discovery/prop-drift.d.mts +297 -0
- package/foundation/discovery/prop-drift.mjs +2428 -0
- package/foundation/discovery/prop-drift.test.mjs +2337 -0
- package/foundation/discovery/runner-allowlist.d.mts +40 -0
- package/foundation/discovery/runner-allowlist.mjs +53 -0
- package/foundation/discovery/stray-pointers.d.mts +52 -0
- package/foundation/discovery/stray-pointers.mjs +293 -0
- package/foundation/discovery/stray-pointers.test.mjs +86 -0
- package/foundation/discovery/template-adapter.mjs +74 -5
- package/foundation/discovery/template-needs.mjs +5 -2
- package/foundation/discovery/theme-imports.mjs +8 -4
- package/foundation/discovery/theme-imports.test.mjs +1 -1
- package/foundation/discovery/type-match.d.mts +53 -0
- package/foundation/discovery/type-match.mjs +660 -0
- package/foundation/discovery/type-match.test.mjs +169 -0
- package/foundation/discovery/type-text.d.mts +68 -0
- package/foundation/discovery/type-text.mjs +658 -0
- package/foundation/discovery/type-text.test.mjs +196 -0
- package/foundation/discovery/unresolved-references.d.mts +62 -0
- package/foundation/discovery/unresolved-references.mjs +790 -0
- package/foundation/discovery/unresolved-references.test.mjs +567 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +51 -1
- package/foundation/doc-compiler/inputs.mjs +27 -1
- package/foundation/doc-compiler/inputs.test.mjs +0 -1
- package/foundation/doc-compiler/links.d.mts +41 -5
- package/foundation/doc-compiler/links.mjs +167 -28
- package/foundation/doc-compiler/links.test.mjs +97 -4
- package/foundation/doc-compiler/read.d.mts +1 -1
- package/foundation/doc-compiler/tree.mjs +30 -1
- package/foundation/doc-compiler/tree.test.mjs +8 -1
- package/foundation/env/cli-command.d.mts +83 -0
- package/foundation/env/cli-command.mjs +152 -0
- package/foundation/env/cli-command.test.mjs +129 -0
- package/foundation/env/node-version.test.mjs +15 -3
- package/foundation/env/package-manager.d.mts +93 -9
- package/foundation/env/package-manager.global.test.mjs +66 -0
- package/foundation/env/package-manager.mjs +184 -13
- package/foundation/env/package-manager.test.mjs +341 -15
- package/foundation/env/project-scope.d.mts +9 -0
- package/foundation/env/project-scope.mjs +33 -0
- package/foundation/env/search-path.d.mts +42 -0
- package/foundation/env/search-path.mjs +205 -0
- package/foundation/env/search-path.test.mjs +122 -0
- package/foundation/env/user-dirs.d.mts +39 -0
- package/foundation/env/user-dirs.mjs +93 -0
- package/foundation/env/user-dirs.test.mjs +72 -0
- package/foundation/env/user-settings.d.mts +46 -0
- package/foundation/env/user-settings.mjs +106 -0
- package/foundation/env/user-settings.test.mjs +64 -0
- package/foundation/fs/file-protection.mjs +15 -1
- package/foundation/fs/module-loader.d.mts +2 -1
- package/foundation/fs/module-loader.mjs +60 -4
- package/foundation/fs/module-loader.stdout.test.mjs +3 -2
- package/foundation/fs/module-loader.test.mjs +194 -0
- package/foundation/fs/path-compare.d.mts +33 -0
- package/foundation/fs/path-compare.mjs +73 -0
- package/foundation/fs/paths.d.mts +57 -1
- package/foundation/fs/paths.mjs +131 -3
- package/foundation/fs/paths.test.mjs +10 -1
- package/foundation/integrations/computer-integrations.d.mts +78 -0
- package/foundation/integrations/computer-integrations.mjs +316 -0
- package/foundation/integrations/computer-integrations.test.mjs +292 -0
- package/foundation/integrations/contribution-inventory.d.mts +11 -0
- package/foundation/integrations/contribution-inventory.mjs +56 -3
- package/foundation/integrations/integration-warnings.mjs +3 -2
- package/foundation/integrations/integration-warnings.test.mjs +8 -9
- package/foundation/integrations/integrations.d.mts +25 -1
- package/foundation/integrations/integrations.mjs +46 -3
- package/foundation/integrations/issue.ts +6 -0
- package/foundation/integrations/validate-contributions.d.mts +2 -0
- package/foundation/integrations/validate-contributions.mjs +41 -1
- package/foundation/release/agent-text-worker.d.mts +4 -0
- package/foundation/release/agent-text-worker.mjs +52 -0
- package/foundation/release/cache.d.mts +310 -0
- package/foundation/release/cache.mjs +1216 -0
- package/foundation/release/cache.test.mjs +920 -0
- package/foundation/release/choose.d.mts +207 -0
- package/foundation/release/choose.mjs +677 -0
- package/foundation/release/choose.test.mjs +427 -0
- package/foundation/release/core-worker.d.mts +4 -0
- package/foundation/release/core-worker.mjs +38 -0
- package/foundation/release/global-state.d.mts +259 -0
- package/foundation/release/global-state.mjs +472 -0
- package/foundation/release/global-state.test.mjs +381 -0
- package/foundation/release/handoff.d.mts +60 -0
- package/foundation/release/handoff.e2e.test.mjs +278 -0
- package/foundation/release/handoff.mjs +357 -0
- package/foundation/release/lock-lease.d.mts +23 -0
- package/foundation/release/lock-lease.mjs +80 -0
- package/foundation/release/notices.d.mts +253 -0
- package/foundation/release/notices.mjs +596 -0
- package/foundation/release/notices.test.mjs +565 -0
- package/foundation/release/npm-guard.d.mts +4 -0
- package/foundation/release/npm-guard.mjs +126 -0
- package/foundation/release/project.d.mts +141 -0
- package/foundation/release/project.mjs +466 -0
- package/foundation/release/project.test.mjs +288 -0
- package/foundation/release/refresh-worker.d.mts +4 -0
- package/foundation/release/refresh-worker.mjs +27 -0
- package/foundation/release/run-context.d.mts +47 -0
- package/foundation/release/run-context.mjs +149 -0
- package/foundation/release/update-notice-env.d.mts +28 -0
- package/foundation/release/update-notice-env.mjs +39 -0
- package/foundation/response/base.d.ts +26 -3
- package/foundation/response/error-codes.d.mts +3 -1
- package/foundation/response/error-codes.doc.mjs +12 -0
- package/foundation/response/error-codes.mjs +17 -0
- package/foundation/response/error-codes.test.mjs +2 -0
- package/foundation/response/json-contract.test.mjs +7 -2
- package/foundation/response/json.mjs +4 -1
- package/foundation/response/response-types.doc.mjs +22 -11
- package/foundation/response/response-types.doc.test.mjs +46 -0
- package/foundation/response/response.doc.mjs +3 -3
- package/foundation/xle/browser-imports.test.mjs +74 -0
- package/foundation/xle/registry.mjs +4 -0
- package/foundation/xle/registry.test.mjs +28 -0
- package/package.json +11 -11
- package/scripts/postinstall.mjs +24 -5
|
@@ -21,6 +21,7 @@ import {docs} from '../docs/docs.mjs';
|
|
|
21
21
|
import {auditCliSelfDocs} from '../../foundation/discovery/cli-self-docs.mjs';
|
|
22
22
|
import {
|
|
23
23
|
doctor,
|
|
24
|
+
checkCliCommand,
|
|
24
25
|
checkAuthoringDocs,
|
|
25
26
|
checkCliDocs,
|
|
26
27
|
checkDocsTree,
|
|
@@ -31,6 +32,8 @@ import {
|
|
|
31
32
|
checkVersionAlignment,
|
|
32
33
|
checkPackageManager,
|
|
33
34
|
} from './doctor.mjs';
|
|
35
|
+
import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
|
|
36
|
+
import {Project} from '../../foundation/config/project.mjs';
|
|
34
37
|
|
|
35
38
|
const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
|
|
36
39
|
const cwd = REPO;
|
|
@@ -86,6 +89,30 @@ describe('doctor leaf', () => {
|
|
|
86
89
|
}, SLOW);
|
|
87
90
|
});
|
|
88
91
|
|
|
92
|
+
describe('doctor never reads the carried Core (spec AST-081 FR3)', () => {
|
|
93
|
+
it('loads the project to read only its installed Core, in a project with nothing installed', async () => {
|
|
94
|
+
const dir = mkProject({
|
|
95
|
+
'package.json': JSON.stringify({
|
|
96
|
+
name: 'fresh-clone',
|
|
97
|
+
dependencies: {'@astryxdesign/core': '^0.7.0'},
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
const load = vi.spyOn(Project, 'load');
|
|
101
|
+
const coreDir = vi.spyOn(Project.prototype, 'coreDir');
|
|
102
|
+
try {
|
|
103
|
+
await doctor({cwd: dir});
|
|
104
|
+
// Doctor's own project reads only the installed Core, and no Core a
|
|
105
|
+
// project read during the run is the carried one.
|
|
106
|
+
expect(load.mock.calls.some(([, options]) => options?.core === 'project')).toBe(true);
|
|
107
|
+
expect(coreDir).toHaveBeenCalled();
|
|
108
|
+
for (const result of coreDir.mock.results) expect(result.value).toBeNull();
|
|
109
|
+
} finally {
|
|
110
|
+
load.mockRestore();
|
|
111
|
+
coreDir.mockRestore();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
89
116
|
describe('integration issue check', () => {
|
|
90
117
|
it('surfaces cross-package replacement warnings', () => {
|
|
91
118
|
const check = checkIntegrationIssues({
|
|
@@ -110,7 +137,7 @@ describe('integration issue check', () => {
|
|
|
110
137
|
describe('doctor leaf — degradation & error paths', () => {
|
|
111
138
|
it('does not crash on multiple config files; reports a config FAIL', async () => {
|
|
112
139
|
const dir = mkProject({
|
|
113
|
-
'package.json': '{"name":"x"}',
|
|
140
|
+
'package.json': '{"name":"x","dependencies":{"@astryxdesign/core":"*"}}',
|
|
114
141
|
'astryx.config.mjs': 'export default {};',
|
|
115
142
|
'astryx.config.js': 'export default {};',
|
|
116
143
|
});
|
|
@@ -123,7 +150,7 @@ describe('doctor leaf — degradation & error paths', () => {
|
|
|
123
150
|
|
|
124
151
|
it('reports a config FAIL (not a crash) when astryx.config.mjs throws on import', async () => {
|
|
125
152
|
const dir = mkProject({
|
|
126
|
-
'package.json': '{"name":"x"}',
|
|
153
|
+
'package.json': '{"name":"x","dependencies":{"@astryxdesign/core":"*"}}',
|
|
127
154
|
'astryx.config.mjs': 'throw new Error("boom");\nexport default {};',
|
|
128
155
|
});
|
|
129
156
|
const r = await doctor({cwd: dir});
|
|
@@ -134,7 +161,7 @@ describe('doctor leaf — degradation & error paths', () => {
|
|
|
134
161
|
|
|
135
162
|
it('flags a non-object config default export as FAIL', async () => {
|
|
136
163
|
const dir = mkProject({
|
|
137
|
-
'package.json': '{"name":"x"}',
|
|
164
|
+
'package.json': '{"name":"x","dependencies":{"@astryxdesign/core":"*"}}',
|
|
138
165
|
'astryx.config.mjs': 'export default 42;',
|
|
139
166
|
});
|
|
140
167
|
const r = await doctor({cwd: dir});
|
|
@@ -190,6 +217,102 @@ describe('doctor — checkVersionAlignment', () => {
|
|
|
190
217
|
});
|
|
191
218
|
});
|
|
192
219
|
|
|
220
|
+
describe("doctor — the project's own CLI and Core on different releases", () => {
|
|
221
|
+
const cli = JSON.parse(
|
|
222
|
+
fs.readFileSync(new URL('../../package.json', import.meta.url), 'utf8'),
|
|
223
|
+
).version;
|
|
224
|
+
/** @param {string} core */
|
|
225
|
+
const at = core => {
|
|
226
|
+
const dir = mkProject({
|
|
227
|
+
'package-lock.json': '{}',
|
|
228
|
+
'node_modules/@astryxdesign/core/package.json': JSON.stringify({
|
|
229
|
+
name: '@astryxdesign/core',
|
|
230
|
+
version: core,
|
|
231
|
+
}),
|
|
232
|
+
});
|
|
233
|
+
return checkVersionAlignment({
|
|
234
|
+
cwd: dir,
|
|
235
|
+
coreDir: path.join(dir, 'node_modules/@astryxdesign/core'),
|
|
236
|
+
nodeVersion: '',
|
|
237
|
+
configPath: null,
|
|
238
|
+
configTheme: null,
|
|
239
|
+
});
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
it('warns on any difference, patch included, and names the align command', () => {
|
|
243
|
+
const older = at('0.0.1');
|
|
244
|
+
expect(older.status).toBe('warn');
|
|
245
|
+
expect(older.message).toContain(
|
|
246
|
+
`This project's CLI ${cli} answers it, but its Core is 0.0.1`,
|
|
247
|
+
);
|
|
248
|
+
expect(older.fix).toBe(
|
|
249
|
+
`To align them, run: npm install @astryxdesign/core@${cli}, then npx astryx upgrade --from 0.0.1 --apply.`,
|
|
250
|
+
);
|
|
251
|
+
const newer = at('99.0.0');
|
|
252
|
+
expect(newer.fix).toBe(
|
|
253
|
+
'To align them, run: npm install @astryxdesign/cli@99.0.0.',
|
|
254
|
+
);
|
|
255
|
+
expect(at(cli).status).toBe('pass');
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('in a project with no CLI of its own, warns that the started copy answered and names the command that adds the CLI at Core', () => {
|
|
259
|
+
const dir = mkProject({
|
|
260
|
+
'package-lock.json': '{}',
|
|
261
|
+
'node_modules/@astryxdesign/core/package.json': JSON.stringify({
|
|
262
|
+
name: '@astryxdesign/core',
|
|
263
|
+
version: '0.0.1',
|
|
264
|
+
}),
|
|
265
|
+
});
|
|
266
|
+
const c = checkVersionAlignment({
|
|
267
|
+
cwd: dir,
|
|
268
|
+
coreDir: path.join(dir, 'node_modules/@astryxdesign/core'),
|
|
269
|
+
nodeVersion: '',
|
|
270
|
+
configPath: null,
|
|
271
|
+
configTheme: null,
|
|
272
|
+
ownCli: false,
|
|
273
|
+
});
|
|
274
|
+
expect(c.status).toBe('warn');
|
|
275
|
+
expect(c.message).toBe(
|
|
276
|
+
`This project has no Astryx CLI installed; CLI ${cli}, the one you started, answered while its Core is 0.0.1.`,
|
|
277
|
+
);
|
|
278
|
+
expect(c.fix).toBe('To match, run: npm install @astryxdesign/cli@0.0.1.');
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
describe('checkCliCommand', () => {
|
|
283
|
+
it('is informational when no integration declares a command', () => {
|
|
284
|
+
const dir = mkProject({'pnpm-lock.yaml': ''});
|
|
285
|
+
const c = checkCliCommand({cwd: dir, integrations: [{name: '@acme/a'}]});
|
|
286
|
+
expect(c).toMatchObject({id: 'cli-command', status: 'info'});
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it('passes and names the command and who declared it', () => {
|
|
290
|
+
const c = checkCliCommand({
|
|
291
|
+
cwd: mkProject({}),
|
|
292
|
+
integrations: [{name: '@acme/a', cliCommand: 'acme astryx'}],
|
|
293
|
+
});
|
|
294
|
+
expect(c).toMatchObject({id: 'cli-command', status: 'pass'});
|
|
295
|
+
expect(c.message).toContain('`acme astryx`');
|
|
296
|
+
expect(c.message).toContain('@acme/a');
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it('warns when integrations declare different commands', () => {
|
|
300
|
+
const dir = mkProject({'pnpm-lock.yaml': ''});
|
|
301
|
+
const c = checkCliCommand({
|
|
302
|
+
cwd: dir,
|
|
303
|
+
integrations: [
|
|
304
|
+
{name: '@acme/a', cliCommand: 'acme astryx'},
|
|
305
|
+
{name: '@acme/b', cliCommand: 'other astryx'},
|
|
306
|
+
],
|
|
307
|
+
});
|
|
308
|
+
expect(c).toMatchObject({id: 'cli-command', status: 'warn'});
|
|
309
|
+
expect(c.message).toContain('@acme/a (`acme astryx`)');
|
|
310
|
+
expect(c.message).toContain('@acme/b (`other astryx`)');
|
|
311
|
+
expect(c.message).toContain('pnpm dlx @astryxdesign/cli');
|
|
312
|
+
expect(c.fix).toContain('cliCommand');
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
193
316
|
describe('checkPackageManager', () => {
|
|
194
317
|
it('is informational when one lockfile answers', () => {
|
|
195
318
|
const dir = mkProject({'pnpm-lock.yaml': ''});
|
|
@@ -353,6 +476,49 @@ describe('checkImplicitIntegrations', () => {
|
|
|
353
476
|
expect(c.message).toContain('named in astryx.config');
|
|
354
477
|
});
|
|
355
478
|
|
|
479
|
+
// A package with no astryx.config that loads its own manifest: there is no
|
|
480
|
+
// config file, so the message must not say anything is named in one.
|
|
481
|
+
it("names the package's own manifest instead of a config that does not exist", () => {
|
|
482
|
+
const c = checkImplicitIntegrations({
|
|
483
|
+
integrations: [autolinked({__autolinked: false, __local: true, name: '@acme/kit'})],
|
|
484
|
+
});
|
|
485
|
+
expect(c.status).toBe('info');
|
|
486
|
+
expect(c.message).toBe(
|
|
487
|
+
"None — the only loaded integration is this package's own manifest (@acme/kit).",
|
|
488
|
+
);
|
|
489
|
+
expect(c.message).not.toContain('astryx.config');
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
// An own manifest that failed to load keeps a `__local` record carrying
|
|
493
|
+
// `__loadError`; it loaded nothing, so it is never named as loaded.
|
|
494
|
+
it("does not name the package's own manifest as loaded when it failed to load", () => {
|
|
495
|
+
const failed = autolinked({
|
|
496
|
+
__autolinked: false,
|
|
497
|
+
__local: true,
|
|
498
|
+
name: '@acme/kit',
|
|
499
|
+
__loadError: 'astryx.integration.mjs threw: boom',
|
|
500
|
+
});
|
|
501
|
+
const alone = checkImplicitIntegrations({integrations: [failed]});
|
|
502
|
+
expect(alone.status).toBe('info');
|
|
503
|
+
expect(alone.message).toBe('None loaded.');
|
|
504
|
+
const beside = checkImplicitIntegrations({
|
|
505
|
+
integrations: [autolinked({__autolinked: false}), failed],
|
|
506
|
+
});
|
|
507
|
+
expect(beside.message).toBe('None — every loaded integration is named in astryx.config.');
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
it('names both when configured integrations load beside the own manifest', () => {
|
|
511
|
+
const c = checkImplicitIntegrations({
|
|
512
|
+
integrations: [
|
|
513
|
+
autolinked({__autolinked: false}),
|
|
514
|
+
autolinked({__autolinked: false, __local: true, name: '@acme/kit'}),
|
|
515
|
+
],
|
|
516
|
+
});
|
|
517
|
+
expect(c.message).toBe(
|
|
518
|
+
"None — every loaded integration is named in astryx.config or is this package's own manifest (@acme/kit).",
|
|
519
|
+
);
|
|
520
|
+
});
|
|
521
|
+
|
|
356
522
|
it('names the package, the field, and what it contributes', () => {
|
|
357
523
|
// Roots count only when they exist, so this one gives them real folders.
|
|
358
524
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-implicit-'));
|
|
@@ -486,7 +652,7 @@ describe('checkAuthoringDocs', () => {
|
|
|
486
652
|
it('passes when every authoring self-doc is reachable and fits one read', async () => {
|
|
487
653
|
const c = await checkAuthoringDocs();
|
|
488
654
|
expect(c).toMatchObject({id: 'authoring-docs', status: 'pass'});
|
|
489
|
-
expect(c.message).toContain('
|
|
655
|
+
expect(c.message).toContain(formatCliCommand('docs authoring'));
|
|
490
656
|
}, SLOW);
|
|
491
657
|
});
|
|
492
658
|
|
|
@@ -514,7 +680,7 @@ describe('checkCliDocs', () => {
|
|
|
514
680
|
id: 'cli-docs',
|
|
515
681
|
label: 'CLI docs',
|
|
516
682
|
status: 'pass',
|
|
517
|
-
message: `All ${audit.docs} CLI docs are readable: ${audit.tree} in the
|
|
683
|
+
message: `All ${audit.docs} CLI docs are readable: ${audit.tree} in the \`${formatCliCommand('docs cli')}\` tree and ${audit.authoring} in \`${formatCliCommand('docs authoring')}\`.`,
|
|
518
684
|
});
|
|
519
685
|
},
|
|
520
686
|
SLOW,
|
|
@@ -548,7 +714,7 @@ describe('checkCliDocs', () => {
|
|
|
548
714
|
label: 'CLI docs',
|
|
549
715
|
status: 'fail',
|
|
550
716
|
message:
|
|
551
|
-
|
|
717
|
+
`2 problems: api/alpha/alpha.doc.mjs has no namespace, so no \`${formatCliCommand('docs')}\` topic reads it; clients/cli/commands/beta.doc.mjs has namespace "cli", which no \`${formatCliCommand('docs')}\` topic reads`,
|
|
552
718
|
fix: CLI_DOCS_FIX,
|
|
553
719
|
});
|
|
554
720
|
},
|
|
@@ -624,7 +790,7 @@ describe('checkDocsTree', () => {
|
|
|
624
790
|
describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
625
791
|
const NAMESPACE = 'doctypes/namespace/namespace.doc.mjs';
|
|
626
792
|
const NAMESPACE_TYPES =
|
|
627
|
-
|
|
793
|
+
`NamespaceDoc, NamespaceProviderScope, NamespaceSlotAcceptance, NamespaceSlot, NamespaceAdoptionSource, NamespaceAdoptionRule from doctypes/namespace/type.ts have no doc in \`${formatCliCommand('docs authoring')}\``;
|
|
628
794
|
const SURFACE_FIX =
|
|
629
795
|
'Put a self-doc beside each module whose types @astryxdesign/cli/authoring exports and list it in AUTHORING_SELF_DOCS; export what each listed self-doc documents, or remove that self-doc.';
|
|
630
796
|
|
|
@@ -654,7 +820,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
654
820
|
id: 'authoring-docs',
|
|
655
821
|
label: 'Authoring docs',
|
|
656
822
|
status: 'pass',
|
|
657
|
-
message: `All ${AUTHORING_SELF_DOCS.length} authoring schemas are readable in
|
|
823
|
+
message: `All ${AUTHORING_SELF_DOCS.length} authoring schemas are readable in \`${formatCliCommand('docs authoring')}\`.`,
|
|
658
824
|
});
|
|
659
825
|
},
|
|
660
826
|
SLOW,
|
|
@@ -683,7 +849,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
683
849
|
});
|
|
684
850
|
expect(c.status).toBe('fail');
|
|
685
851
|
expect(c.message).toBe(
|
|
686
|
-
`2 problems: ${NAMESPACE} is not in
|
|
852
|
+
`2 problems: ${NAMESPACE} is not in \`${formatCliCommand('docs authoring')}\`; ${NAMESPACE_TYPES}: ${NAMESPACE} is not listed in AUTHORING_SELF_DOCS`,
|
|
687
853
|
);
|
|
688
854
|
},
|
|
689
855
|
SLOW,
|
|
@@ -781,7 +947,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
781
947
|
expect(c.fix).toBe(SURFACE_FIX);
|
|
782
948
|
expect(c.message).toMatch(
|
|
783
949
|
new RegExp(
|
|
784
|
-
`^[A-Za-z, ]+ from ${escape(module)} have no doc in
|
|
950
|
+
`^[A-Za-z, ]+ from ${escape(module)} have no doc in \`${escape(formatCliCommand('docs authoring'))}\`: no self-doc sits beside ${escape(module)}$`,
|
|
785
951
|
),
|
|
786
952
|
);
|
|
787
953
|
for (const name of names) {
|
|
@@ -824,7 +990,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
824
990
|
expect(await checkAuthoringDocs()).toMatchObject({
|
|
825
991
|
status: 'fail',
|
|
826
992
|
message:
|
|
827
|
-
'
|
|
993
|
+
`\`${formatCliCommand('docs authoring')}\` could not be read: no built-in docs`,
|
|
828
994
|
fix: SURFACE_FIX,
|
|
829
995
|
});
|
|
830
996
|
} finally {
|
|
@@ -845,7 +1011,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
845
1011
|
const c = await checkAuthoringDocs(undefined, {root});
|
|
846
1012
|
expect(c.status).toBe('fail');
|
|
847
1013
|
expect(c.message).toContain(
|
|
848
|
-
|
|
1014
|
+
`@astryxdesign/cli/authoring exports no types, so nothing was compared with \`${formatCliCommand('docs authoring')}\``,
|
|
849
1015
|
);
|
|
850
1016
|
},
|
|
851
1017
|
SLOW,
|
|
@@ -1055,7 +1221,7 @@ describe('doctor says why it skipped and what it checked', () => {
|
|
|
1055
1221
|
expect(by.config.message).toMatch(
|
|
1056
1222
|
/^astryx\.config\.mjs loads, but the CLI could not load the project from it: .*integrations/,
|
|
1057
1223
|
);
|
|
1058
|
-
expect(by.config.fix).toContain('
|
|
1224
|
+
expect(by.config.fix).toContain(' docs authoring config`');
|
|
1059
1225
|
for (const id of ['implicit-integrations', 'provider-identity']) {
|
|
1060
1226
|
expect(by[id].message).toMatch(
|
|
1061
1227
|
/^Skipped — the project configuration could not be read: .*integrations/,
|
|
@@ -1182,7 +1348,7 @@ describe('a configured integration that cannot load fails the gate', () => {
|
|
|
1182
1348
|
/^1 of 1 integration named in astryx\.config could not be loaded, so it contributes nothing: @acme\/widgets \(/,
|
|
1183
1349
|
);
|
|
1184
1350
|
expect(check.message).toMatch(reason);
|
|
1185
|
-
expect(check.fix).toContain('
|
|
1351
|
+
expect(check.fix).toContain(' doctor integration validate <package>`');
|
|
1186
1352
|
expect(summary.fail).toBe(1);
|
|
1187
1353
|
},
|
|
1188
1354
|
SLOW,
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file doctor's release checks (spec AST-081 FR10, FR11): the newest
|
|
5
|
+
* release beside a project's or the global copy's, with the fix, and the
|
|
6
|
+
* `astryx` commands on the search path.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {describe, expect, it} from 'vitest';
|
|
10
|
+
import {checkCliOnPath, checkNewestRelease} from './doctor.mjs';
|
|
11
|
+
|
|
12
|
+
const answeredBy = {cli: '0.7.1', core: '0.7.1', copy: 'project'};
|
|
13
|
+
|
|
14
|
+
/** @param {Partial<import('../../foundation/env/search-path.mjs').SearchPathCommand>} row */
|
|
15
|
+
const row = row => ({
|
|
16
|
+
file: '/bin/astryx',
|
|
17
|
+
astryx: true,
|
|
18
|
+
cliRoot: '/lib/cli',
|
|
19
|
+
version: '0.8.0',
|
|
20
|
+
handsOff: true,
|
|
21
|
+
...row,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('checkNewestRelease', () => {
|
|
25
|
+
it("names a project's install and upgrade commands", () => {
|
|
26
|
+
const check = checkNewestRelease({
|
|
27
|
+
nodeVersion: '24.0.0',
|
|
28
|
+
answeredBy,
|
|
29
|
+
latest: '0.7.3',
|
|
30
|
+
projectLag: {
|
|
31
|
+
root: '/app',
|
|
32
|
+
current: '0.7.1',
|
|
33
|
+
newest: '0.7.3',
|
|
34
|
+
install: 'npm install @astryxdesign/core@0.7.3 @astryxdesign/cli@0.7.3',
|
|
35
|
+
upgrade: 'npx astryx upgrade --from 0.7.1 --apply',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
expect(check).toEqual({
|
|
39
|
+
id: 'newest-release',
|
|
40
|
+
label: 'Newest release',
|
|
41
|
+
status: 'info',
|
|
42
|
+
message: 'This project uses Astryx 0.7.1; 0.7.3 is the newest.',
|
|
43
|
+
fix: 'To upgrade, run: npm install @astryxdesign/core@0.7.3 @astryxdesign/cli@0.7.3, then npx astryx upgrade --from 0.7.1 --apply.',
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('adds the last notice skip and a held state lock, for diagnosis', () => {
|
|
48
|
+
const check = checkNewestRelease({
|
|
49
|
+
nodeVersion: '24.0.0',
|
|
50
|
+
answeredBy,
|
|
51
|
+
latest: '0.7.1',
|
|
52
|
+
lastNoticeSkip: {
|
|
53
|
+
key: 'global',
|
|
54
|
+
reason: 'already-shown',
|
|
55
|
+
at: Date.UTC(2026, 9, 20, 18),
|
|
56
|
+
},
|
|
57
|
+
stateLock: {pid: 42, host: 'mac', since: Date.UTC(2026, 9, 20, 17)},
|
|
58
|
+
});
|
|
59
|
+
expect(check.message).toBe(
|
|
60
|
+
'No newer release is known: the newest is 0.7.1. ' +
|
|
61
|
+
'Last update notice skipped 2026-10-20T18:00:00.000Z (global): it had already printed that day. ' +
|
|
62
|
+
"The state file's lock is held by process 42 on mac since 2026-10-20T17:00:00.000Z.",
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('says when the last update check did not reach the registry, and why', () => {
|
|
67
|
+
const check = checkNewestRelease({
|
|
68
|
+
nodeVersion: '24.0.0',
|
|
69
|
+
answeredBy,
|
|
70
|
+
latest: null,
|
|
71
|
+
lastCheckFailure: {
|
|
72
|
+
at: Date.UTC(2026, 9, 20, 18),
|
|
73
|
+
reason: 'npm-failed: ECONNREFUSED',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
expect(check.message).toContain(
|
|
77
|
+
'The last update check, 2026-10-20T18:00:00.000Z, did not reach the registry: npm failed (ECONNREFUSED); its registry and proxy settings decide where it asks.',
|
|
78
|
+
);
|
|
79
|
+
expect(
|
|
80
|
+
checkNewestRelease({
|
|
81
|
+
nodeVersion: '24.0.0',
|
|
82
|
+
answeredBy,
|
|
83
|
+
latest: null,
|
|
84
|
+
lastCheckFailure: {at: 0, reason: 'npm-missing'},
|
|
85
|
+
}).message,
|
|
86
|
+
).toContain('did not reach the registry: npm could not be started.');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("names the global copy's upgrade, after the Node the newest release needs", () => {
|
|
90
|
+
const check = checkNewestRelease({
|
|
91
|
+
nodeVersion: '22.13.0',
|
|
92
|
+
answeredBy: {...answeredBy, copy: 'carried'},
|
|
93
|
+
latest: '0.8.0',
|
|
94
|
+
globalBehind: {
|
|
95
|
+
current: '0.7.1',
|
|
96
|
+
newest: '0.8.0',
|
|
97
|
+
node: '>=99',
|
|
98
|
+
command: 'pnpm add -g @astryxdesign/cli@latest',
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
expect(check).toEqual({
|
|
102
|
+
id: 'newest-release',
|
|
103
|
+
label: 'Newest release',
|
|
104
|
+
status: 'info',
|
|
105
|
+
message:
|
|
106
|
+
'A new release of Astryx is available: 0.7.1 → 0.8.0. The CLI installed for the computer stays on its release until you upgrade it.',
|
|
107
|
+
fix: `To upgrade, install Node >=99 (this computer runs Node ${process.versions.node}), then run: pnpm add -g @astryxdesign/cli@latest.`,
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('checkCliOnPath', () => {
|
|
113
|
+
const base = {nodeVersion: '24.0.0', answeredBy, latest: null};
|
|
114
|
+
|
|
115
|
+
it('passes for a release that hands off, and lists the later ones', () => {
|
|
116
|
+
const check = checkCliOnPath({
|
|
117
|
+
...base,
|
|
118
|
+
searchPathCommands: [
|
|
119
|
+
row({}),
|
|
120
|
+
row({file: '/other/astryx', version: '0.7.1', handsOff: false}),
|
|
121
|
+
],
|
|
122
|
+
});
|
|
123
|
+
expect(check).toMatchObject({
|
|
124
|
+
status: 'pass',
|
|
125
|
+
message:
|
|
126
|
+
'`astryx` runs /bin/astryx (CLI 0.8.0). Later on the search path: /other/astryx (CLI 0.7.1).',
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('warns about a first release that predates the hand-off, naming the replacement', () => {
|
|
131
|
+
expect(
|
|
132
|
+
checkCliOnPath({
|
|
133
|
+
...base,
|
|
134
|
+
searchPathCommands: [row({version: '0.7.1', handsOff: false})],
|
|
135
|
+
}),
|
|
136
|
+
).toMatchObject({
|
|
137
|
+
status: 'warn',
|
|
138
|
+
fix: 'To upgrade, run: `npm i -g @astryxdesign/cli@latest`.',
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('warns about another program first, and informs when there is none', () => {
|
|
143
|
+
expect(
|
|
144
|
+
checkCliOnPath({
|
|
145
|
+
...base,
|
|
146
|
+
searchPathCommands: [
|
|
147
|
+
row({astryx: false, cliRoot: null, version: null, handsOff: null}),
|
|
148
|
+
],
|
|
149
|
+
}),
|
|
150
|
+
).toMatchObject({status: 'warn'});
|
|
151
|
+
expect(checkCliOnPath({...base, searchPathCommands: []})).toMatchObject({
|
|
152
|
+
status: 'info',
|
|
153
|
+
fix: 'To run the CLI in any folder, install it for the computer: `npm i -g @astryxdesign/cli`.',
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
@@ -32,7 +32,10 @@ import {
|
|
|
32
32
|
themeRecordOwner,
|
|
33
33
|
validateThemePrivateInputs,
|
|
34
34
|
} from './_adapter.mjs';
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
getCliInvocation,
|
|
37
|
+
formatCliCommand,
|
|
38
|
+
} from '../../foundation/env/package-manager.mjs';
|
|
36
39
|
import {satisfiesRange} from '../../foundation/env/semver.mjs';
|
|
37
40
|
import {logger} from '../logger.mjs';
|
|
38
41
|
|
|
@@ -69,7 +72,7 @@ function unavailableChecks(message, moduleError = null) {
|
|
|
69
72
|
moduleError && id === 'theme-module' ? moduleError.message : message,
|
|
70
73
|
...(moduleError && id === 'theme-module'
|
|
71
74
|
? {
|
|
72
|
-
fix:
|
|
75
|
+
fix: `Keep one CLI-generated astryx-themes.ts or astryx-themes.js file, then run \`${formatCliCommand('theme add <slug>')}\`.`,
|
|
73
76
|
}
|
|
74
77
|
: {}),
|
|
75
78
|
}));
|
|
@@ -736,7 +739,7 @@ export async function checkAppThemes(cwd) {
|
|
|
736
739
|
label: 'App imports the theme module',
|
|
737
740
|
status: 'warn',
|
|
738
741
|
message: `Could not prove that project source imports ${state.module.path}${importEvidence.parseFailures ? `; ${importEvidence.parseFailures} source file(s) could not be parsed` : ''}.`,
|
|
739
|
-
fix: `Import {themes, defaultThemeSlug} from the generated module and {Theme} from '@astryxdesign/core', then render <Theme theme={themes[defaultThemeSlug]}>.`,
|
|
742
|
+
fix: `Import {themes, defaultThemeSlug} from the generated module and {Theme} from '@astryxdesign/core/theme', then render <Theme theme={themes[defaultThemeSlug]}>.`,
|
|
740
743
|
});
|
|
741
744
|
}
|
|
742
745
|
|
|
@@ -794,6 +797,16 @@ export async function checkAppThemes(cwd) {
|
|
|
794
797
|
message:
|
|
795
798
|
'Could not check local build freshness until every local output resolves.',
|
|
796
799
|
});
|
|
800
|
+
} else if (localThemes.length > 0 && !findDoctorCoreDir(state.projectDir)) {
|
|
801
|
+
// A build reads Core, and doctor reads only the Core the project
|
|
802
|
+
// installed, never the one the answering copy carries (spec AST-081 FR3).
|
|
803
|
+
checks.push({
|
|
804
|
+
id: 'theme-local-builds',
|
|
805
|
+
label: 'Local theme build freshness',
|
|
806
|
+
status: 'info',
|
|
807
|
+
message:
|
|
808
|
+
"The project's Core isn't installed, so local theme builds were not checked. Install the project's dependencies, then run doctor again.",
|
|
809
|
+
});
|
|
797
810
|
} else if (localThemes.length === 0) {
|
|
798
811
|
checks.push({
|
|
799
812
|
id: 'theme-local-builds',
|
|
@@ -817,7 +830,7 @@ export async function checkAppThemes(cwd) {
|
|
|
817
830
|
const receipt = await themeBuild(
|
|
818
831
|
path.join(availableTheme.sourceDir, availableTheme.entry),
|
|
819
832
|
{check: true},
|
|
820
|
-
{cwd: state.projectDir},
|
|
833
|
+
{cwd: state.projectDir, projectCore: true},
|
|
821
834
|
);
|
|
822
835
|
if (
|
|
823
836
|
receipt == null ||
|