@astryxdesign/cli 0.7.2-canary.fe2c655 → 0.7.3-canary.02f5fe4
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 +216 -162
- package/api/build/_adapter.d.mts +66 -0
- package/api/build/_adapter.mjs +139 -4
- package/api/build/blocks/blocks.d.mts +92 -0
- package/api/build/blocks/blocks.mjs +528 -0
- package/api/build/blocks/blocks.test.mjs +238 -0
- package/api/build/blocks/blocks.weights.json +1 -0
- package/api/build/build.doc.mjs +4 -0
- package/api/build/build.mjs +25 -6
- package/api/build/build.type.mjs +1 -1
- package/api/build/help/help.mjs +1 -1
- package/api/build/kit/answer.d.mts +18 -0
- package/api/build/kit/answer.mjs +195 -0
- package/api/build/kit/answer.test.mjs +108 -0
- package/api/build/kit/kind.d.mts +25 -0
- package/api/build/kit/kind.mjs +170 -0
- package/api/build/kit/kit.d.mts +2 -4
- package/api/build/kit/kit.mjs +8 -406
- package/api/build/kit/rank.d.mts +3 -32
- package/api/build/kit/rank.mjs +25 -342
- package/api/build/kit/rank.test.mjs +2 -1
- package/api/build/kit/signals.d.mts +79 -0
- package/api/build/kit/signals.mjs +295 -0
- package/api/build/kit/start.d.mts +32 -0
- package/api/build/kit/start.mjs +163 -0
- package/api/build/kit/words.d.mts +72 -0
- package/api/build/kit/words.mjs +202 -0
- package/api/build/tree.d.mts +20 -0
- package/api/build/tree.mjs +53 -0
- package/api/build/tree.test.mjs +185 -0
- package/api/build/tree.weights.json +1 -0
- package/api/component/_adapter.d.mts +72 -1
- package/api/component/_adapter.mjs +251 -23
- package/api/component/component-replacement.test.mjs +1 -0
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +97 -16
- package/api/component/component.test.mjs +95 -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 +131 -12
- package/api/discover/_adapter.mjs +520 -34
- package/api/discover/_adapter.test.mjs +641 -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 +120 -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 +76 -2
- package/api/docs/_adapter.mjs +630 -34
- package/api/docs/docs-homes.test.mjs +127 -0
- package/api/docs/docs.doc.mjs +5 -4
- package/api/docs/docs.mjs +2 -1
- package/api/docs/docs.test.mjs +39 -20
- package/api/docs/integration-tree.test.mjs +42 -20
- package/api/docs/integrationDocs.test.mjs +125 -1
- package/api/docs/list/list.mjs +12 -2
- package/api/docs/namespace-section.test.mjs +6 -6
- package/api/docs/reference-blocks.test.mjs +3 -5
- package/api/doctor/_adapter.d.mts +128 -0
- package/api/doctor/_adapter.mjs +253 -4
- package/api/doctor/doctor.d.mts +217 -0
- package/api/doctor/doctor.doc.mjs +3 -2
- package/api/doctor/doctor.mjs +691 -52
- package/api/doctor/doctor.test.mjs +267 -18
- 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/hook.mjs +1 -1
- 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 +45 -10
- package/api/init/init.mjs +28 -4
- package/api/init/init.test.mjs +18 -2
- package/api/init/init.type.d.mts +50 -5
- package/api/init/init.type.mjs +39 -5
- package/api/init/remove/remove.mjs +17 -4
- package/api/init/remove/remove.test.mjs +114 -2
- package/api/init/run/run.d.mts +1 -1
- package/api/init/run/run.mjs +86 -12
- 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 +53 -0
- package/api/integration/_adapter.mjs +132 -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 +192 -14
- package/api/integration/authoring-checks.test.mjs +1028 -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 +486 -123
- package/api/integration/pack-check.test.mjs +817 -10
- package/api/integration/validate-integration-case-disk.test.mjs +111 -0
- package/api/integration/validate-integration-fixes.test.mjs +73 -5
- package/api/integration/validate-integration-gaps.test.mjs +1975 -0
- package/api/integration/validate-integration.d.mts +23 -2
- package/api/integration/validate-integration.mjs +358 -45
- package/api/integration/validate-integration.test.mjs +88 -8
- package/api/integration/validate-integration.type.d.mts +105 -0
- package/api/integration/validate-integration.type.mjs +79 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +19 -3
- package/api/search/ORDERING.md +28 -0
- package/api/search/_adapter.d.mts +91 -0
- package/api/search/_adapter.mjs +172 -0
- package/api/search/_adapter.test.mjs +173 -0
- package/api/search/_candidate-score.d.mts +40 -0
- package/api/search/_candidate-score.mjs +238 -0
- package/api/search/_cards.json +6098 -0
- package/api/search/_compound.d.mts +50 -0
- package/api/search/_compound.mjs +170 -0
- package/api/search/_doc-searcher.d.mts +4 -0
- package/api/search/_doc-searcher.mjs +23 -0
- package/api/search/_doc-searcher.test.mjs +36 -0
- package/api/search/_doc-searcher.weights.json +1 -0
- package/api/search/_doc-text.d.mts +30 -0
- package/api/search/_doc-text.mjs +87 -0
- package/api/search/_entries.d.mts +63 -0
- package/api/search/_entries.mjs +232 -0
- package/api/search/_entries.test.mjs +48 -0
- package/api/search/_features.d.mts +35 -0
- package/api/search/_features.mjs +155 -0
- package/api/search/_gather-components.d.mts +26 -0
- package/api/search/_gather-components.mjs +284 -0
- package/api/search/_gather-docs.d.mts +20 -0
- package/api/search/_gather-docs.mjs +254 -0
- package/api/search/_gather-hooks.d.mts +12 -0
- package/api/search/_gather-hooks.mjs +52 -0
- package/api/search/_gather-templates.d.mts +25 -0
- package/api/search/_gather-templates.mjs +107 -0
- package/api/search/_lexical.d.mts +135 -0
- package/api/search/_lexical.mjs +351 -0
- package/api/search/_main-searcher.d.mts +19 -0
- package/api/search/_main-searcher.mjs +115 -0
- package/api/search/_main-searcher.test.mjs +106 -0
- package/api/search/_main-searcher.weights.json +1 -0
- package/api/search/_module-doc.d.mts +32 -0
- package/api/search/_module-doc.mjs +78 -0
- package/api/search/_order.d.mts +32 -0
- package/api/search/_order.mjs +162 -0
- package/api/search/_order.test.mjs +72 -0
- package/api/search/_priority.d.mts +50 -0
- package/api/search/_priority.mjs +139 -0
- package/api/search/_query-words.d.mts +25 -0
- package/api/search/_query-words.mjs +92 -0
- package/api/search/_query.d.mts +65 -0
- package/api/search/_query.mjs +176 -0
- package/api/search/_result.d.mts +97 -0
- package/api/search/_result.mjs +150 -0
- package/api/search/_score.d.mts +60 -0
- package/api/search/_score.mjs +283 -0
- package/api/search/_synonyms.d.mts +21 -0
- package/api/search/_synonyms.mjs +67 -0
- package/api/search/_template-searcher.d.mts +4 -0
- package/api/search/_template-searcher.mjs +23 -0
- package/api/search/_template-searcher.test.mjs +40 -0
- package/api/search/_template-searcher.weights.json +1 -0
- package/api/search/_titles.d.mts +33 -0
- package/api/search/_titles.mjs +65 -0
- package/api/search/_words.d.mts +64 -0
- package/api/search/_words.mjs +157 -0
- package/api/search/search.d.mts +22 -236
- package/api/search/search.doc.mjs +14 -7
- 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 +59 -1904
- package/api/search/search.test.mjs +193 -15
- package/api/search/search.type.d.mts +20 -2
- package/api/search/search.type.mjs +12 -2
- package/api/search/tree.d.mts +15 -0
- package/api/search/tree.mjs +40 -0
- package/api/search/tree.test.mjs +66 -0
- package/api/search/tree.weights.json +1 -0
- 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.mjs +5 -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 +21 -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 +97 -11
- package/api/upgrade/_adapter.mjs +315 -32
- package/api/upgrade/registry/registry.d.mts +10 -4
- package/api/upgrade/registry/registry.mjs +33 -16
- package/api/upgrade/registry/registry.test.mjs +85 -0
- package/api/upgrade/run/cli-behind-core.test.mjs +438 -0
- package/api/upgrade/run/run.d.mts +4 -2
- package/api/upgrade/run/run.mjs +48 -4
- package/api/upgrade/run/run.test.mjs +417 -3
- package/api/upgrade/status/status.d.mts +21 -5
- package/api/upgrade/status/status.mjs +45 -8
- package/api/upgrade/upgrade.doc.mjs +16 -8
- package/api/upgrade/upgrade.mjs +18 -3
- package/api/upgrade/upgrade.test.mjs +194 -0
- package/api/upgrade/upgrade.type.d.mts +28 -3
- package/api/upgrade/upgrade.type.mjs +24 -7
- 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.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
- package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
- 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 +5 -5
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +26 -6
- package/assets/docs/is-my-code-good.doc.mjs +287 -0
- 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 +14 -4
- 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/api.doc.mjs +6 -0
- package/assets/docs/tree/authoring.doc.mjs +61 -0
- 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 +6 -2
- 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 +101 -0
- package/assets/docs/tree/cli-command.doc.mjs +142 -0
- package/assets/docs/tree/cli.doc.mjs +7 -1
- 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 +8 -4
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +41 -22
- package/assets/docs/tree/define-the-theme.doc.mjs +7 -6
- 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 +4 -4
- 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/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
- package/assets/docs/tree/fonts-and-assets.doc.mjs +3 -3
- package/assets/docs/tree/generate-a-palette.doc.mjs +8 -6
- 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/help.doc.mjs +2 -2
- package/assets/docs/tree/host-entry.doc.mjs +128 -0
- package/assets/docs/tree/install-once.doc.mjs +105 -0
- 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 +54 -28
- 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/ship.doc.mjs +2 -2
- 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-grading-rubric.doc.mjs +17 -38
- 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 +5 -1
- package/assets/docs/tree/tokens-and-setup.doc.mjs +19 -15
- package/assets/docs/tree/tokens-data.doc.mjs +2 -2
- 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 +15 -3
- package/assets/docs/tree/verify-packed-template.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +14 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
- 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/use-integrations.doc.mjs +120 -0
- package/assets/docs/working-with-ai.doc.mjs +70 -13
- package/assets/templates/themes/butter/butterTheme.ts +4 -2
- package/assets/templates/themes/stone/stoneTheme.ts +4 -2
- package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
- 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 +10 -10
- 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 +13 -1
- package/clients/cli/bin/astryx.mjs +11 -65
- package/clients/cli/cli-command.test.mjs +166 -0
- package/clients/cli/command-result-coverage.test.mjs +6 -5
- 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.color-scheme.test.mjs +1 -1
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- 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/{component/index.mjs → component.mjs} +37 -37
- package/clients/cli/commands/component.test.mjs +6 -6
- 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 +3 -2
- package/clients/cli/commands/docs.mjs +50 -20
- package/clients/cli/commands/docs.test.mjs +16 -16
- 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 +936 -3
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +332 -7
- package/clients/cli/commands/doctor.test.mjs +75 -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/{hook/index.mjs → hook.mjs} +22 -22
- package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
- package/clients/cli/commands/init.behavior.test.mjs +235 -1
- package/clients/cli/commands/init.doc.mjs +55 -10
- package/clients/cli/commands/init.flag-help.test.mjs +1 -0
- package/clients/cli/commands/init.mjs +2 -2
- 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 +489 -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 +2 -1
- package/clients/cli/commands/manifest.mjs +67 -0
- package/clients/cli/commands/outside-project.test.mjs +874 -0
- package/clients/cli/commands/postinstall.doc.mjs +23 -0
- package/clients/cli/commands/postinstall.mjs +31 -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 +180 -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/{build-theme.mjs → theme.mjs} +27 -14
- package/clients/cli/commands/upgrade.config-ordering.test.mjs +2 -1
- package/clients/cli/commands/upgrade.doc.mjs +26 -3
- 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.mjs +9 -2
- package/clients/cli/commands/upgrade.older-cli.test.mjs +160 -0
- package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
- package/clients/cli/index.mjs +156 -100
- package/clients/cli/lib/cli-error.mjs +4 -1
- package/clients/cli/lib/component-format.mjs +1 -1
- package/clients/cli/lib/component-format.test.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +14 -9
- package/clients/cli/lib/exit-codes.test.mjs +5 -0
- 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 +37 -0
- package/clients/cli/lib/welcome-box.mjs +50 -0
- package/clients/cli/run.mjs +108 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +67 -13
- package/foundation/agent-docs/agent-doc-state.mjs +123 -14
- package/foundation/agent-docs/agent-docs.d.mts +104 -15
- package/foundation/agent-docs/agent-docs.mjs +1028 -114
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
- package/foundation/agent-docs/agent-docs.test.mjs +683 -39
- package/foundation/agent-docs/computer-agent-text.d.mts +170 -0
- package/foundation/agent-docs/computer-agent-text.mjs +750 -0
- package/foundation/agent-docs/computer-agent-text.test.mjs +699 -0
- package/foundation/config/project.d.mts +35 -3
- package/foundation/config/project.mjs +243 -26
- package/foundation/config/project.test.mjs +122 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.d.mts +7 -0
- package/foundation/discovery/authoring-self-docs.mjs +17 -4
- package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
- package/foundation/discovery/authoring-surface.d.mts +1 -1
- package/foundation/discovery/authoring-surface.mjs +2 -2
- package/foundation/discovery/authoring-surface.test.mjs +1 -1
- package/foundation/discovery/cli-self-docs.d.mts +2 -1
- package/foundation/discovery/cli-self-docs.mjs +22 -4
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-discovery.d.mts +227 -10
- package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
- package/foundation/discovery/component-discovery.mjs +940 -57
- package/foundation/discovery/component-discovery.test.mjs +96 -0
- package/foundation/discovery/component-loader.d.mts +1 -1
- 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 +97 -3
- 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 +68 -0
- package/foundation/discovery/module-exports.mjs +609 -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 +38 -0
- package/foundation/discovery/runner-allowlist.mjs +51 -0
- package/foundation/discovery/runner-commands.d.mts +77 -0
- package/foundation/discovery/runner-commands.mjs +294 -0
- package/foundation/discovery/runner-commands.test.mjs +128 -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 +92 -6
- package/foundation/discovery/template-needs.mjs +6 -46
- package/foundation/discovery/theme-discovery.mjs +147 -3
- 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 +84 -10
- 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/read.mjs +59 -1
- package/foundation/doc-compiler/read.test.mjs +11 -2
- package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
- package/foundation/doc-compiler/tree.d.mts +32 -6
- package/foundation/doc-compiler/tree.mjs +107 -44
- package/foundation/doc-compiler/tree.test.mjs +14 -7
- 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 +122 -4
- package/foundation/fs/paths.mjs +675 -29
- package/foundation/fs/paths.test.mjs +439 -54
- package/foundation/fs/read-record.d.mts +18 -0
- package/foundation/fs/read-record.mjs +131 -0
- package/foundation/fs/read-record.test.mjs +77 -0
- package/foundation/integrations/autolink.d.mts +2 -1
- package/foundation/integrations/autolink.mjs +4 -13
- package/foundation/integrations/cli-peer-version.d.mts +36 -0
- package/foundation/integrations/cli-peer-version.mjs +132 -0
- package/foundation/integrations/cli-peer-version.test.mjs +354 -0
- package/foundation/integrations/computer-integrations.d.mts +81 -0
- package/foundation/integrations/computer-integrations.mjs +345 -0
- package/foundation/integrations/computer-integrations.test.mjs +292 -0
- package/foundation/integrations/contribution-inventory.d.mts +26 -20
- package/foundation/integrations/contribution-inventory.mjs +97 -8
- package/foundation/integrations/exports-subpaths.d.mts +57 -0
- package/foundation/integrations/exports-subpaths.mjs +113 -0
- package/foundation/integrations/integration-warnings.mjs +3 -2
- package/foundation/integrations/integration-warnings.test.mjs +8 -9
- package/foundation/integrations/integrations.d.mts +51 -1
- package/foundation/integrations/integrations.mjs +106 -4
- package/foundation/integrations/issue.ts +6 -0
- package/foundation/integrations/public-imports.d.mts +118 -0
- package/foundation/integrations/public-imports.mjs +1769 -0
- package/foundation/integrations/public-imports.test.mjs +1793 -0
- package/foundation/integrations/validate-contributions.d.mts +117 -0
- package/foundation/integrations/validate-contributions.mjs +1209 -14
- 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 +923 -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 +263 -0
- package/foundation/release/global-state.mjs +474 -0
- package/foundation/release/global-state.test.mjs +381 -0
- package/foundation/release/handoff.d.mts +79 -0
- package/foundation/release/handoff.e2e.test.mjs +278 -0
- package/foundation/release/handoff.mjs +524 -0
- package/foundation/release/lock-lease.d.mts +23 -0
- package/foundation/release/lock-lease.mjs +80 -0
- package/foundation/release/notices.d.mts +307 -0
- package/foundation/release/notices.mjs +707 -0
- package/foundation/release/notices.test.mjs +586 -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 +163 -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/route/route.d.mts +285 -0
- package/foundation/route/route.mjs +324 -0
- package/foundation/route/route.test.mjs +153 -0
- package/foundation/runtime/hosted-runtime.test.mjs +403 -0
- package/foundation/runtime/locked-versions.d.mts +32 -0
- package/foundation/runtime/locked-versions.mjs +65 -0
- package/foundation/runtime/package-root.d.mts +91 -0
- package/foundation/runtime/package-root.mjs +174 -0
- package/foundation/runtime/package-set.d.mts +62 -0
- package/foundation/runtime/package-set.mjs +130 -0
- package/foundation/runtime/package-set.test.mjs +432 -0
- package/foundation/text/string-utils.d.mts +2 -1
- package/foundation/text/string-utils.mjs +16 -5
- package/foundation/text/suggest-order.d.mts +72 -0
- package/foundation/text/suggest-order.mjs +363 -0
- package/foundation/text/suggest-order.test.mjs +259 -0
- 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/host/door-conformance.test.mjs +274 -0
- package/host/index.d.ts +116 -0
- package/host/index.mjs +295 -0
- package/host/index.test.mjs +302 -0
- package/package.json +16 -11
- package/scripts/postinstall.mjs +24 -5
- package/assets/docs/tree/integrations.doc.mjs +0 -40
|
@@ -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,
|
|
@@ -30,7 +31,11 @@ import {
|
|
|
30
31
|
checkIntegrationIssues,
|
|
31
32
|
checkVersionAlignment,
|
|
32
33
|
checkPackageManager,
|
|
34
|
+
checkComputerIntegrationsAvailable,
|
|
33
35
|
} from './doctor.mjs';
|
|
36
|
+
import {installCommandFor} from './_adapter.mjs';
|
|
37
|
+
import {formatCliCommand} from '../../foundation/env/package-manager.mjs';
|
|
38
|
+
import {Project} from '../../foundation/config/project.mjs';
|
|
34
39
|
|
|
35
40
|
const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../..');
|
|
36
41
|
const cwd = REPO;
|
|
@@ -86,6 +91,30 @@ describe('doctor leaf', () => {
|
|
|
86
91
|
}, SLOW);
|
|
87
92
|
});
|
|
88
93
|
|
|
94
|
+
describe('doctor never reads the carried Core (spec AST-081 FR3)', () => {
|
|
95
|
+
it('loads the project to read only its installed Core, in a project with nothing installed', async () => {
|
|
96
|
+
const dir = mkProject({
|
|
97
|
+
'package.json': JSON.stringify({
|
|
98
|
+
name: 'fresh-clone',
|
|
99
|
+
dependencies: {'@astryxdesign/core': '^0.7.0'},
|
|
100
|
+
}),
|
|
101
|
+
});
|
|
102
|
+
const load = vi.spyOn(Project, 'load');
|
|
103
|
+
const coreDir = vi.spyOn(Project.prototype, 'coreDir');
|
|
104
|
+
try {
|
|
105
|
+
await doctor({cwd: dir});
|
|
106
|
+
// Doctor's own project reads only the installed Core, and no Core a
|
|
107
|
+
// project read during the run is the carried one.
|
|
108
|
+
expect(load.mock.calls.some(([, options]) => options?.core === 'project')).toBe(true);
|
|
109
|
+
expect(coreDir).toHaveBeenCalled();
|
|
110
|
+
for (const result of coreDir.mock.results) expect(result.value).toBeNull();
|
|
111
|
+
} finally {
|
|
112
|
+
load.mockRestore();
|
|
113
|
+
coreDir.mockRestore();
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
89
118
|
describe('integration issue check', () => {
|
|
90
119
|
it('surfaces cross-package replacement warnings', () => {
|
|
91
120
|
const check = checkIntegrationIssues({
|
|
@@ -110,7 +139,7 @@ describe('integration issue check', () => {
|
|
|
110
139
|
describe('doctor leaf — degradation & error paths', () => {
|
|
111
140
|
it('does not crash on multiple config files; reports a config FAIL', async () => {
|
|
112
141
|
const dir = mkProject({
|
|
113
|
-
'package.json': '{"name":"x"}',
|
|
142
|
+
'package.json': '{"name":"x","dependencies":{"@astryxdesign/core":"*"}}',
|
|
114
143
|
'astryx.config.mjs': 'export default {};',
|
|
115
144
|
'astryx.config.js': 'export default {};',
|
|
116
145
|
});
|
|
@@ -123,7 +152,7 @@ describe('doctor leaf — degradation & error paths', () => {
|
|
|
123
152
|
|
|
124
153
|
it('reports a config FAIL (not a crash) when astryx.config.mjs throws on import', async () => {
|
|
125
154
|
const dir = mkProject({
|
|
126
|
-
'package.json': '{"name":"x"}',
|
|
155
|
+
'package.json': '{"name":"x","dependencies":{"@astryxdesign/core":"*"}}',
|
|
127
156
|
'astryx.config.mjs': 'throw new Error("boom");\nexport default {};',
|
|
128
157
|
});
|
|
129
158
|
const r = await doctor({cwd: dir});
|
|
@@ -134,7 +163,7 @@ describe('doctor leaf — degradation & error paths', () => {
|
|
|
134
163
|
|
|
135
164
|
it('flags a non-object config default export as FAIL', async () => {
|
|
136
165
|
const dir = mkProject({
|
|
137
|
-
'package.json': '{"name":"x"}',
|
|
166
|
+
'package.json': '{"name":"x","dependencies":{"@astryxdesign/core":"*"}}',
|
|
138
167
|
'astryx.config.mjs': 'export default 42;',
|
|
139
168
|
});
|
|
140
169
|
const r = await doctor({cwd: dir});
|
|
@@ -190,6 +219,158 @@ describe('doctor — checkVersionAlignment', () => {
|
|
|
190
219
|
});
|
|
191
220
|
});
|
|
192
221
|
|
|
222
|
+
describe("doctor — the project's own CLI and Core on different releases", () => {
|
|
223
|
+
const cli = JSON.parse(
|
|
224
|
+
fs.readFileSync(new URL('../../package.json', import.meta.url), 'utf8'),
|
|
225
|
+
).version;
|
|
226
|
+
/** @param {string} core */
|
|
227
|
+
const at = core => {
|
|
228
|
+
// A project as spec:AST-040 FR9 defines it: its package.json declares
|
|
229
|
+
// an Astryx package.
|
|
230
|
+
const dir = mkProject({
|
|
231
|
+
'package.json': JSON.stringify({
|
|
232
|
+
name: 'app',
|
|
233
|
+
dependencies: {'@astryxdesign/core': core},
|
|
234
|
+
}),
|
|
235
|
+
'package-lock.json': '{}',
|
|
236
|
+
'node_modules/@astryxdesign/core/package.json': JSON.stringify({
|
|
237
|
+
name: '@astryxdesign/core',
|
|
238
|
+
version: core,
|
|
239
|
+
}),
|
|
240
|
+
});
|
|
241
|
+
return checkVersionAlignment({
|
|
242
|
+
cwd: dir,
|
|
243
|
+
coreDir: path.join(dir, 'node_modules/@astryxdesign/core'),
|
|
244
|
+
nodeVersion: '',
|
|
245
|
+
configPath: null,
|
|
246
|
+
configTheme: null,
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
it('warns on any difference, patch included, and names the align command', () => {
|
|
251
|
+
const older = at('0.0.1');
|
|
252
|
+
expect(older.status).toBe('warn');
|
|
253
|
+
expect(older.message).toContain(
|
|
254
|
+
`This project's CLI ${cli} answers it, but its Core is 0.0.1`,
|
|
255
|
+
);
|
|
256
|
+
expect(older.fix).toBe(
|
|
257
|
+
`To align them, run: npm install @astryxdesign/core@${cli}, then npx astryx upgrade --from 0.0.1 --apply.`,
|
|
258
|
+
);
|
|
259
|
+
const newer = at('99.0.0');
|
|
260
|
+
expect(newer.fix).toBe(
|
|
261
|
+
'To align them, run: npm install @astryxdesign/cli@99.0.0.',
|
|
262
|
+
);
|
|
263
|
+
expect(at(cli).status).toBe('pass');
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
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', () => {
|
|
267
|
+
const dir = mkProject({
|
|
268
|
+
'package.json': JSON.stringify({
|
|
269
|
+
name: 'app',
|
|
270
|
+
dependencies: {'@astryxdesign/core': '0.0.1'},
|
|
271
|
+
}),
|
|
272
|
+
'package-lock.json': '{}',
|
|
273
|
+
'node_modules/@astryxdesign/core/package.json': JSON.stringify({
|
|
274
|
+
name: '@astryxdesign/core',
|
|
275
|
+
version: '0.0.1',
|
|
276
|
+
}),
|
|
277
|
+
});
|
|
278
|
+
const c = checkVersionAlignment({
|
|
279
|
+
cwd: dir,
|
|
280
|
+
coreDir: path.join(dir, 'node_modules/@astryxdesign/core'),
|
|
281
|
+
nodeVersion: '',
|
|
282
|
+
configPath: null,
|
|
283
|
+
configTheme: null,
|
|
284
|
+
ownCli: false,
|
|
285
|
+
});
|
|
286
|
+
expect(c.status).toBe('warn');
|
|
287
|
+
expect(c.message).toBe(
|
|
288
|
+
`This project has no Astryx CLI installed; CLI ${cli}, the one you started, answered while its Core is 0.0.1.`,
|
|
289
|
+
);
|
|
290
|
+
expect(c.fix).toBe('To match, run: npm install @astryxdesign/cli@0.0.1.');
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe('the command that adds an integration installed for the computer', () => {
|
|
295
|
+
const app = () =>
|
|
296
|
+
mkProject({
|
|
297
|
+
'package.json': JSON.stringify({
|
|
298
|
+
name: 'app',
|
|
299
|
+
dependencies: {'@astryxdesign/core': '0.7.0'},
|
|
300
|
+
}),
|
|
301
|
+
'pnpm-lock.yaml': '',
|
|
302
|
+
'tools/codegen/package.json': JSON.stringify({name: 'codegen'}),
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('adds it in the project, with its package manager', () => {
|
|
306
|
+
const dir = app();
|
|
307
|
+
expect(installCommandFor(dir)?.('@acme/a')).toBe('pnpm add @acme/a');
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// A package.json that is not the project's (spec AST-040 FR9): a run
|
|
311
|
+
// there loads integrations from it, so a package added to the project
|
|
312
|
+
// stays unused there. No command; the fix points at the project.
|
|
313
|
+
it("from a tool folder inside the project, names no command and points at the project's folder", () => {
|
|
314
|
+
const dir = app();
|
|
315
|
+
expect(installCommandFor(path.join(dir, 'tools', 'codegen'))).toBeNull();
|
|
316
|
+
const c = checkComputerIntegrationsAvailable({
|
|
317
|
+
installed: new Set(),
|
|
318
|
+
candidates: [/** @type {any} */ ({name: '@acme/a'})],
|
|
319
|
+
install: null,
|
|
320
|
+
elsewhere: true,
|
|
321
|
+
});
|
|
322
|
+
expect(c.fix).toBe(
|
|
323
|
+
"Run this from the Astryx project's folder, or declare an Astryx package in this folder's package.json to make it a project of its own.",
|
|
324
|
+
);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it('in a folder that belongs to no project, names no command', () => {
|
|
328
|
+
const dir = mkProject({'package.json': JSON.stringify({name: 'tool'})});
|
|
329
|
+
expect(installCommandFor(dir)).toBeNull();
|
|
330
|
+
const c = checkComputerIntegrationsAvailable({
|
|
331
|
+
installed: new Set(),
|
|
332
|
+
candidates: [/** @type {any} */ ({name: '@acme/a'})],
|
|
333
|
+
install: null,
|
|
334
|
+
});
|
|
335
|
+
expect(c.status).toBe('info');
|
|
336
|
+
expect(c).not.toHaveProperty('fix');
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
describe('checkCliCommand', () => {
|
|
341
|
+
it('is informational when no integration declares a command', () => {
|
|
342
|
+
const dir = mkProject({'pnpm-lock.yaml': ''});
|
|
343
|
+
const c = checkCliCommand({cwd: dir, integrations: [{name: '@acme/a'}]});
|
|
344
|
+
expect(c).toMatchObject({id: 'cli-command', status: 'info'});
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('passes and names the command and who declared it', () => {
|
|
348
|
+
const c = checkCliCommand({
|
|
349
|
+
cwd: mkProject({}),
|
|
350
|
+
integrations: [{name: '@acme/a', cliCommand: 'acme astryx'}],
|
|
351
|
+
});
|
|
352
|
+
expect(c).toMatchObject({id: 'cli-command', status: 'pass'});
|
|
353
|
+
expect(c.message).toContain('`acme astryx`');
|
|
354
|
+
expect(c.message).toContain('@acme/a');
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it('warns when integrations declare different commands', () => {
|
|
358
|
+
const dir = mkProject({'pnpm-lock.yaml': ''});
|
|
359
|
+
const c = checkCliCommand({
|
|
360
|
+
cwd: dir,
|
|
361
|
+
integrations: [
|
|
362
|
+
{name: '@acme/a', cliCommand: 'acme astryx'},
|
|
363
|
+
{name: '@acme/b', cliCommand: 'other astryx'},
|
|
364
|
+
],
|
|
365
|
+
});
|
|
366
|
+
expect(c).toMatchObject({id: 'cli-command', status: 'warn'});
|
|
367
|
+
expect(c.message).toContain('@acme/a (`acme astryx`)');
|
|
368
|
+
expect(c.message).toContain('@acme/b (`other astryx`)');
|
|
369
|
+
expect(c.message).toContain('pnpm dlx @astryxdesign/cli');
|
|
370
|
+
expect(c.fix).toContain('cliCommand');
|
|
371
|
+
});
|
|
372
|
+
});
|
|
373
|
+
|
|
193
374
|
describe('checkPackageManager', () => {
|
|
194
375
|
it('is informational when one lockfile answers', () => {
|
|
195
376
|
const dir = mkProject({'pnpm-lock.yaml': ''});
|
|
@@ -353,6 +534,49 @@ describe('checkImplicitIntegrations', () => {
|
|
|
353
534
|
expect(c.message).toContain('named in astryx.config');
|
|
354
535
|
});
|
|
355
536
|
|
|
537
|
+
// A package with no astryx.config that loads its own manifest: there is no
|
|
538
|
+
// config file, so the message must not say anything is named in one.
|
|
539
|
+
it("names the package's own manifest instead of a config that does not exist", () => {
|
|
540
|
+
const c = checkImplicitIntegrations({
|
|
541
|
+
integrations: [autolinked({__autolinked: false, __local: true, name: '@acme/kit'})],
|
|
542
|
+
});
|
|
543
|
+
expect(c.status).toBe('info');
|
|
544
|
+
expect(c.message).toBe(
|
|
545
|
+
"None — the only loaded integration is this package's own manifest (@acme/kit).",
|
|
546
|
+
);
|
|
547
|
+
expect(c.message).not.toContain('astryx.config');
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// An own manifest that failed to load keeps a `__local` record carrying
|
|
551
|
+
// `__loadError`; it loaded nothing, so it is never named as loaded.
|
|
552
|
+
it("does not name the package's own manifest as loaded when it failed to load", () => {
|
|
553
|
+
const failed = autolinked({
|
|
554
|
+
__autolinked: false,
|
|
555
|
+
__local: true,
|
|
556
|
+
name: '@acme/kit',
|
|
557
|
+
__loadError: 'astryx.integration.mjs threw: boom',
|
|
558
|
+
});
|
|
559
|
+
const alone = checkImplicitIntegrations({integrations: [failed]});
|
|
560
|
+
expect(alone.status).toBe('info');
|
|
561
|
+
expect(alone.message).toBe('None loaded.');
|
|
562
|
+
const beside = checkImplicitIntegrations({
|
|
563
|
+
integrations: [autolinked({__autolinked: false}), failed],
|
|
564
|
+
});
|
|
565
|
+
expect(beside.message).toBe('None — every loaded integration is named in astryx.config.');
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
it('names both when configured integrations load beside the own manifest', () => {
|
|
569
|
+
const c = checkImplicitIntegrations({
|
|
570
|
+
integrations: [
|
|
571
|
+
autolinked({__autolinked: false}),
|
|
572
|
+
autolinked({__autolinked: false, __local: true, name: '@acme/kit'}),
|
|
573
|
+
],
|
|
574
|
+
});
|
|
575
|
+
expect(c.message).toBe(
|
|
576
|
+
"None — every loaded integration is named in astryx.config or is this package's own manifest (@acme/kit).",
|
|
577
|
+
);
|
|
578
|
+
});
|
|
579
|
+
|
|
356
580
|
it('names the package, the field, and what it contributes', () => {
|
|
357
581
|
// Roots count only when they exist, so this one gives them real folders.
|
|
358
582
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-implicit-'));
|
|
@@ -486,7 +710,7 @@ describe('checkAuthoringDocs', () => {
|
|
|
486
710
|
it('passes when every authoring self-doc is reachable and fits one read', async () => {
|
|
487
711
|
const c = await checkAuthoringDocs();
|
|
488
712
|
expect(c).toMatchObject({id: 'authoring-docs', status: 'pass'});
|
|
489
|
-
expect(c.message).toContain('
|
|
713
|
+
expect(c.message).toContain(formatCliCommand('docs authoring/field-reference'));
|
|
490
714
|
}, SLOW);
|
|
491
715
|
});
|
|
492
716
|
|
|
@@ -514,7 +738,7 @@ describe('checkCliDocs', () => {
|
|
|
514
738
|
id: 'cli-docs',
|
|
515
739
|
label: 'CLI docs',
|
|
516
740
|
status: 'pass',
|
|
517
|
-
message: `All ${audit.docs} CLI docs are readable: ${audit.tree} in the
|
|
741
|
+
message: `All ${audit.docs} CLI docs are readable: ${audit.tree} in the \`${formatCliCommand('docs cli')}\` tree and ${audit.authoring} in \`${formatCliCommand('docs authoring/field-reference')}\`.`,
|
|
518
742
|
});
|
|
519
743
|
},
|
|
520
744
|
SLOW,
|
|
@@ -548,7 +772,7 @@ describe('checkCliDocs', () => {
|
|
|
548
772
|
label: 'CLI docs',
|
|
549
773
|
status: 'fail',
|
|
550
774
|
message:
|
|
551
|
-
|
|
775
|
+
`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
776
|
fix: CLI_DOCS_FIX,
|
|
553
777
|
});
|
|
554
778
|
},
|
|
@@ -624,7 +848,7 @@ describe('checkDocsTree', () => {
|
|
|
624
848
|
describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
625
849
|
const NAMESPACE = 'doctypes/namespace/namespace.doc.mjs';
|
|
626
850
|
const NAMESPACE_TYPES =
|
|
627
|
-
|
|
851
|
+
`NamespaceDoc, NamespaceProviderScope, NamespaceSlotAcceptance, NamespaceSlot, NamespaceAdoptionSource, NamespaceAdoptionRule from doctypes/namespace/type.ts have no doc in \`${formatCliCommand('docs authoring/field-reference')}\``;
|
|
628
852
|
const SURFACE_FIX =
|
|
629
853
|
'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
854
|
|
|
@@ -654,7 +878,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
654
878
|
id: 'authoring-docs',
|
|
655
879
|
label: 'Authoring docs',
|
|
656
880
|
status: 'pass',
|
|
657
|
-
message: `All ${AUTHORING_SELF_DOCS.length} authoring schemas are readable in
|
|
881
|
+
message: `All ${AUTHORING_SELF_DOCS.length} authoring schemas are readable in \`${formatCliCommand('docs authoring/field-reference')}\`.`,
|
|
658
882
|
});
|
|
659
883
|
},
|
|
660
884
|
SLOW,
|
|
@@ -683,7 +907,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
683
907
|
});
|
|
684
908
|
expect(c.status).toBe('fail');
|
|
685
909
|
expect(c.message).toBe(
|
|
686
|
-
`2 problems: ${NAMESPACE} is not in
|
|
910
|
+
`2 problems: ${NAMESPACE} is not in \`${formatCliCommand('docs authoring/field-reference')}\`; ${NAMESPACE_TYPES}: ${NAMESPACE} is not listed in AUTHORING_SELF_DOCS`,
|
|
687
911
|
);
|
|
688
912
|
},
|
|
689
913
|
SLOW,
|
|
@@ -692,7 +916,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
692
916
|
it(
|
|
693
917
|
"fails when the topic's index no longer exposes the NamespaceDoc section",
|
|
694
918
|
async () => {
|
|
695
|
-
const index = await docs('authoring', undefined, {index: true});
|
|
919
|
+
const index = await docs('authoring/field-reference', undefined, {index: true});
|
|
696
920
|
const topicKeys = new Set(
|
|
697
921
|
index.data.sections
|
|
698
922
|
.map((/** @type {any} */ s) => s.id)
|
|
@@ -781,7 +1005,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
781
1005
|
expect(c.fix).toBe(SURFACE_FIX);
|
|
782
1006
|
expect(c.message).toMatch(
|
|
783
1007
|
new RegExp(
|
|
784
|
-
`^[A-Za-z, ]+ from ${escape(module)} have no doc in
|
|
1008
|
+
`^[A-Za-z, ]+ from ${escape(module)} have no doc in \`${escape(formatCliCommand('docs authoring/field-reference'))}\`: no self-doc sits beside ${escape(module)}$`,
|
|
785
1009
|
),
|
|
786
1010
|
);
|
|
787
1011
|
for (const name of names) {
|
|
@@ -824,7 +1048,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
824
1048
|
expect(await checkAuthoringDocs()).toMatchObject({
|
|
825
1049
|
status: 'fail',
|
|
826
1050
|
message:
|
|
827
|
-
'
|
|
1051
|
+
`\`${formatCliCommand('docs authoring/field-reference')}\` could not be read: no built-in docs`,
|
|
828
1052
|
fix: SURFACE_FIX,
|
|
829
1053
|
});
|
|
830
1054
|
} finally {
|
|
@@ -845,7 +1069,7 @@ describe('checkAuthoringDocs against the public authoring surface', () => {
|
|
|
845
1069
|
const c = await checkAuthoringDocs(undefined, {root});
|
|
846
1070
|
expect(c.status).toBe('fail');
|
|
847
1071
|
expect(c.message).toContain(
|
|
848
|
-
|
|
1072
|
+
`@astryxdesign/cli/authoring exports no types, so nothing was compared with \`${formatCliCommand('docs authoring/field-reference')}\``,
|
|
849
1073
|
);
|
|
850
1074
|
},
|
|
851
1075
|
SLOW,
|
|
@@ -1055,7 +1279,7 @@ describe('doctor says why it skipped and what it checked', () => {
|
|
|
1055
1279
|
expect(by.config.message).toMatch(
|
|
1056
1280
|
/^astryx\.config\.mjs loads, but the CLI could not load the project from it: .*integrations/,
|
|
1057
1281
|
);
|
|
1058
|
-
expect(by.config.fix).toContain('
|
|
1282
|
+
expect(by.config.fix).toContain(' docs authoring config`');
|
|
1059
1283
|
for (const id of ['implicit-integrations', 'provider-identity']) {
|
|
1060
1284
|
expect(by[id].message).toMatch(
|
|
1061
1285
|
/^Skipped — the project configuration could not be read: .*integrations/,
|
|
@@ -1151,8 +1375,12 @@ describe('a configured integration that cannot load fails the gate', () => {
|
|
|
1151
1375
|
'astryx.config.mjs': "export default { integrations: ['@acme/widgets'] };\n",
|
|
1152
1376
|
};
|
|
1153
1377
|
|
|
1154
|
-
/**
|
|
1155
|
-
|
|
1378
|
+
/**
|
|
1379
|
+
* Run doctor on a project under the working directory, in its folder `at`.
|
|
1380
|
+
* @param {Record<string, string>} files
|
|
1381
|
+
* @param {string} [at]
|
|
1382
|
+
*/
|
|
1383
|
+
async function report(files, at = '.') {
|
|
1156
1384
|
const dir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-doctor-gate-'));
|
|
1157
1385
|
tmpDirs.push(dir);
|
|
1158
1386
|
for (const [rel, content] of Object.entries(files)) {
|
|
@@ -1160,7 +1388,7 @@ describe('a configured integration that cannot load fails the gate', () => {
|
|
|
1160
1388
|
fs.mkdirSync(path.dirname(abs), {recursive: true});
|
|
1161
1389
|
fs.writeFileSync(abs, content);
|
|
1162
1390
|
}
|
|
1163
|
-
const {checks, summary} = (await doctor({cwd: dir})).data;
|
|
1391
|
+
const {checks, summary} = (await doctor({cwd: path.join(dir, at)})).data;
|
|
1164
1392
|
return {by: Object.fromEntries(checks.map(c => [c.id, c])), summary};
|
|
1165
1393
|
}
|
|
1166
1394
|
|
|
@@ -1182,12 +1410,33 @@ describe('a configured integration that cannot load fails the gate', () => {
|
|
|
1182
1410
|
/^1 of 1 integration named in astryx\.config could not be loaded, so it contributes nothing: @acme\/widgets \(/,
|
|
1183
1411
|
);
|
|
1184
1412
|
expect(check.message).toMatch(reason);
|
|
1185
|
-
expect(check.fix).toContain('
|
|
1413
|
+
expect(check.fix).toContain(' doctor integration validate <package>`');
|
|
1186
1414
|
expect(summary.fail).toBe(1);
|
|
1187
1415
|
},
|
|
1188
1416
|
SLOW,
|
|
1189
1417
|
);
|
|
1190
1418
|
|
|
1419
|
+
it(
|
|
1420
|
+
'passes in a workspace member whose configured integration is hoisted to the root',
|
|
1421
|
+
async () => {
|
|
1422
|
+
const {by} = await report(
|
|
1423
|
+
{
|
|
1424
|
+
'package.json': JSON.stringify({name: 'root', private: true, workspaces: ['apps/*']}),
|
|
1425
|
+
...CORE_STUB,
|
|
1426
|
+
...widgets(),
|
|
1427
|
+
'apps/web/package.json': '{"name":"web"}',
|
|
1428
|
+
'apps/web/astryx.config.mjs': "export default { integrations: ['@acme/widgets'] };\n",
|
|
1429
|
+
},
|
|
1430
|
+
'apps/web',
|
|
1431
|
+
);
|
|
1432
|
+
expect(by['configured-integrations'].status).toBe('pass');
|
|
1433
|
+
expect(by['configured-integrations'].message).toBe(
|
|
1434
|
+
'1 integration named in astryx.config loaded: @acme/widgets.',
|
|
1435
|
+
);
|
|
1436
|
+
},
|
|
1437
|
+
SLOW,
|
|
1438
|
+
);
|
|
1439
|
+
|
|
1191
1440
|
it(
|
|
1192
1441
|
'counts the package being authored when its own config names it',
|
|
1193
1442
|
async () => {
|
|
@@ -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 ||
|