@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
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Computer-level integrations (spec AST-081 FR12): which install root
|
|
5
|
+
* counts, which packages in it are integrations, and the peer-range check.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {afterEach, describe, expect, it} from 'vitest';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import {
|
|
12
|
+
computerInstallRoot,
|
|
13
|
+
computerInstallRoots,
|
|
14
|
+
loadComputerIntegrations,
|
|
15
|
+
peerProblem,
|
|
16
|
+
scanComputerIntegrations,
|
|
17
|
+
} from './computer-integrations.mjs';
|
|
18
|
+
import {
|
|
19
|
+
cleanupFixtures,
|
|
20
|
+
tempDir,
|
|
21
|
+
writeJson,
|
|
22
|
+
} from '../../test-utils/release-fixtures.mjs';
|
|
23
|
+
|
|
24
|
+
afterEach(cleanupFixtures);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A package at `dir`, with a manifest when `manifest` is set.
|
|
28
|
+
* @param {string} dir
|
|
29
|
+
* @param {Record<string, unknown>} pkg
|
|
30
|
+
* @param {string | null} [manifest]
|
|
31
|
+
*/
|
|
32
|
+
function pkgAt(dir, pkg, manifest = 'export default {};\n') {
|
|
33
|
+
writeJson(path.join(dir, 'package.json'), pkg);
|
|
34
|
+
if (manifest != null) {
|
|
35
|
+
fs.writeFileSync(path.join(dir, 'astryx.integration.mjs'), manifest);
|
|
36
|
+
}
|
|
37
|
+
return dir;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** An npm-style global folder (no package.json) holding the CLI and others. */
|
|
41
|
+
function npmGlobal() {
|
|
42
|
+
const root = path.join(tempDir('prefix'), 'lib');
|
|
43
|
+
const modules = path.join(root, 'node_modules');
|
|
44
|
+
const cli = pkgAt(
|
|
45
|
+
path.join(modules, '@astryxdesign', 'cli'),
|
|
46
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
47
|
+
null,
|
|
48
|
+
);
|
|
49
|
+
pkgAt(path.join(modules, '@astryxdesign', 'core'), {
|
|
50
|
+
name: '@astryxdesign/core',
|
|
51
|
+
version: '0.8.0',
|
|
52
|
+
});
|
|
53
|
+
pkgAt(path.join(modules, '@acme', 'widgets'), {
|
|
54
|
+
name: '@acme/widgets',
|
|
55
|
+
version: '1.2.0',
|
|
56
|
+
description: 'Acme widgets',
|
|
57
|
+
});
|
|
58
|
+
pkgAt(path.join(modules, 'plain-tool'), {name: 'plain-tool'}, null);
|
|
59
|
+
pkgAt(path.join(modules, 'zeta-kit'), {
|
|
60
|
+
name: 'zeta-kit',
|
|
61
|
+
version: '2.0.0',
|
|
62
|
+
peerDependencies: {'@astryxdesign/core': '>=9.0.0'},
|
|
63
|
+
});
|
|
64
|
+
return {root, cli};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
describe('computerInstallRoot', () => {
|
|
68
|
+
it('is the folder whose node_modules holds the CLI; none for a runner cache or a folder outside node_modules', () => {
|
|
69
|
+
const {root, cli} = npmGlobal();
|
|
70
|
+
expect(computerInstallRoot(cli)).toBe(fs.realpathSync(root));
|
|
71
|
+
const runner = pkgAt(
|
|
72
|
+
path.join(
|
|
73
|
+
tempDir('npx'),
|
|
74
|
+
'_npx',
|
|
75
|
+
'ab12',
|
|
76
|
+
'node_modules',
|
|
77
|
+
'@astryxdesign',
|
|
78
|
+
'cli',
|
|
79
|
+
),
|
|
80
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
81
|
+
null,
|
|
82
|
+
);
|
|
83
|
+
expect(computerInstallRoot(runner)).toBeNull();
|
|
84
|
+
expect(computerInstallRoot(tempDir('checkout'))).toBeNull();
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('is none for a release in the per-user release cache', () => {
|
|
88
|
+
const cacheDir = tempDir('cache');
|
|
89
|
+
const cli = pkgAt(
|
|
90
|
+
path.join(
|
|
91
|
+
cacheDir,
|
|
92
|
+
'releases',
|
|
93
|
+
'0.8.0',
|
|
94
|
+
'node_modules',
|
|
95
|
+
'@astryxdesign',
|
|
96
|
+
'cli',
|
|
97
|
+
),
|
|
98
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
99
|
+
null,
|
|
100
|
+
);
|
|
101
|
+
expect(computerInstallRoot(cli, {cacheDir})).toBeNull();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
describe('computerInstallRoots', () => {
|
|
106
|
+
it("is pnpm's shared global folder before pnpm 11", () => {
|
|
107
|
+
const g5 = path.join(tempDir('pnpm'), 'global', '5');
|
|
108
|
+
const cli = pkgAt(
|
|
109
|
+
path.join(
|
|
110
|
+
g5,
|
|
111
|
+
'.pnpm',
|
|
112
|
+
'@astryxdesign+cli@0.8.0',
|
|
113
|
+
'node_modules',
|
|
114
|
+
'@astryxdesign',
|
|
115
|
+
'cli',
|
|
116
|
+
),
|
|
117
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
118
|
+
null,
|
|
119
|
+
);
|
|
120
|
+
expect(computerInstallRoots(cli)).toEqual([fs.realpathSync(g5)]);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('is every pnpm global folder since pnpm 11, when one of them installs this CLI', () => {
|
|
124
|
+
const home = tempDir('pnpm-home');
|
|
125
|
+
const cli = pkgAt(
|
|
126
|
+
path.join(
|
|
127
|
+
home,
|
|
128
|
+
'store',
|
|
129
|
+
'v11',
|
|
130
|
+
'links',
|
|
131
|
+
'@astryxdesign',
|
|
132
|
+
'cli',
|
|
133
|
+
'0.8.0',
|
|
134
|
+
'h',
|
|
135
|
+
'node_modules',
|
|
136
|
+
'@astryxdesign',
|
|
137
|
+
'cli',
|
|
138
|
+
),
|
|
139
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
140
|
+
null,
|
|
141
|
+
);
|
|
142
|
+
const a = path.join(home, 'global', 'v11', 'a');
|
|
143
|
+
const b = path.join(home, 'global', 'v11', 'b');
|
|
144
|
+
writeJson(path.join(b, 'package.json'), {
|
|
145
|
+
dependencies: {'@acme/widgets': '1.0.0'},
|
|
146
|
+
});
|
|
147
|
+
// No global folder installs this CLI yet: only its own install root.
|
|
148
|
+
expect(computerInstallRoots(cli)).toHaveLength(1);
|
|
149
|
+
writeJson(path.join(a, 'package.json'), {
|
|
150
|
+
dependencies: {'@astryxdesign/cli': '0.8.0'},
|
|
151
|
+
});
|
|
152
|
+
fs.mkdirSync(path.join(a, 'node_modules', '@astryxdesign'), {
|
|
153
|
+
recursive: true,
|
|
154
|
+
});
|
|
155
|
+
fs.symlinkSync(cli, path.join(a, 'node_modules', '@astryxdesign', 'cli'));
|
|
156
|
+
expect(computerInstallRoots(cli)).toEqual([a, b]);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("is every pnpm global folder when the CLI's files sit inside its own global folder (pnpm 12)", () => {
|
|
160
|
+
const globalDir = path.join(tempDir('pnpm12'), 'global', 'v11');
|
|
161
|
+
const a = path.join(globalDir, 'a');
|
|
162
|
+
const b = path.join(globalDir, 'b');
|
|
163
|
+
writeJson(path.join(a, 'package.json'), {
|
|
164
|
+
dependencies: {'@astryxdesign/cli': '0.8.0'},
|
|
165
|
+
});
|
|
166
|
+
const cli = pkgAt(
|
|
167
|
+
path.join(
|
|
168
|
+
a,
|
|
169
|
+
'node_modules',
|
|
170
|
+
'.pnpm',
|
|
171
|
+
'@astryxdesign+cli@0.8.0',
|
|
172
|
+
'node_modules',
|
|
173
|
+
'@astryxdesign',
|
|
174
|
+
'cli',
|
|
175
|
+
),
|
|
176
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
177
|
+
null,
|
|
178
|
+
);
|
|
179
|
+
fs.mkdirSync(path.join(a, 'node_modules', '@astryxdesign'), {
|
|
180
|
+
recursive: true,
|
|
181
|
+
});
|
|
182
|
+
fs.symlinkSync(cli, path.join(a, 'node_modules', '@astryxdesign', 'cli'));
|
|
183
|
+
writeJson(path.join(b, 'package.json'), {
|
|
184
|
+
dependencies: {'@acme/widgets': '1.0.0'},
|
|
185
|
+
});
|
|
186
|
+
pkgAt(path.join(b, 'node_modules', '@acme', 'widgets'), {
|
|
187
|
+
name: '@acme/widgets',
|
|
188
|
+
version: '1.0.0',
|
|
189
|
+
});
|
|
190
|
+
expect(computerInstallRoots(cli)).toEqual([
|
|
191
|
+
fs.realpathSync(a),
|
|
192
|
+
fs.realpathSync(b),
|
|
193
|
+
]);
|
|
194
|
+
expect(
|
|
195
|
+
scanComputerIntegrations({cliRoot: cli, release: '0.8.0'}).map(
|
|
196
|
+
c => c.name,
|
|
197
|
+
),
|
|
198
|
+
).toEqual(['@acme/widgets']);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
describe('scanComputerIntegrations', () => {
|
|
203
|
+
it('lists every package beside the CLI that ships a manifest, never the CLI or Core, and marks an incompatible one', () => {
|
|
204
|
+
const {cli} = npmGlobal();
|
|
205
|
+
const found = scanComputerIntegrations({cliRoot: cli, release: '0.8.0'});
|
|
206
|
+
expect(found.map(c => [c.name, c.version, c.incompatible])).toEqual([
|
|
207
|
+
['@acme/widgets', '1.2.0', null],
|
|
208
|
+
[
|
|
209
|
+
'zeta-kit',
|
|
210
|
+
'2.0.0',
|
|
211
|
+
"it needs @astryxdesign/core >=9.0.0, and this computer's CLI is 0.8.0",
|
|
212
|
+
],
|
|
213
|
+
]);
|
|
214
|
+
expect(found[0].description).toBe('Acme widgets');
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("reads a door's package set from the root's declared dependencies", () => {
|
|
218
|
+
const root = tempDir('runtime');
|
|
219
|
+
writeJson(path.join(root, 'package.json'), {
|
|
220
|
+
name: 'runtime',
|
|
221
|
+
private: true,
|
|
222
|
+
dependencies: {
|
|
223
|
+
'@astryxdesign/cli': '0.8.0',
|
|
224
|
+
'@astryxdesign/core': '0.8.0',
|
|
225
|
+
'@acme/meta-kit': '3.0.0',
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
const modules = path.join(root, 'node_modules');
|
|
229
|
+
const cli = pkgAt(
|
|
230
|
+
path.join(modules, '@astryxdesign', 'cli'),
|
|
231
|
+
{name: '@astryxdesign/cli', version: '0.8.0'},
|
|
232
|
+
null,
|
|
233
|
+
);
|
|
234
|
+
pkgAt(path.join(modules, '@acme', 'meta-kit'), {
|
|
235
|
+
name: '@acme/meta-kit',
|
|
236
|
+
version: '3.0.0',
|
|
237
|
+
});
|
|
238
|
+
// Installed but not declared: not part of the set.
|
|
239
|
+
pkgAt(path.join(modules, 'stray-kit'), {name: 'stray-kit'});
|
|
240
|
+
expect(
|
|
241
|
+
scanComputerIntegrations({cliRoot: cli, release: '0.8.0'}).map(
|
|
242
|
+
c => c.name,
|
|
243
|
+
),
|
|
244
|
+
).toEqual(['@acme/meta-kit']);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('lists nothing for a copy with no install root', () => {
|
|
248
|
+
expect(
|
|
249
|
+
scanComputerIntegrations({
|
|
250
|
+
cliRoot: tempDir('checkout'),
|
|
251
|
+
release: '0.8.0',
|
|
252
|
+
}),
|
|
253
|
+
).toEqual([]);
|
|
254
|
+
});
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
describe('peerProblem', () => {
|
|
258
|
+
it('checks the Core and CLI peer ranges against the answering release', () => {
|
|
259
|
+
expect(peerProblem({}, '0.8.0')).toBeNull();
|
|
260
|
+
expect(
|
|
261
|
+
peerProblem(
|
|
262
|
+
{peerDependencies: {'@astryxdesign/core': '^0.8.0'}},
|
|
263
|
+
'0.8.2',
|
|
264
|
+
),
|
|
265
|
+
).toBeNull();
|
|
266
|
+
expect(
|
|
267
|
+
peerProblem(
|
|
268
|
+
{peerDependencies: {'@astryxdesign/cli': '>=0.9.0'}},
|
|
269
|
+
'0.8.2',
|
|
270
|
+
),
|
|
271
|
+
).toBe(
|
|
272
|
+
"it needs @astryxdesign/cli >=0.9.0, and this computer's CLI is 0.8.2",
|
|
273
|
+
);
|
|
274
|
+
expect(
|
|
275
|
+
peerProblem({peerDependencies: {react: '>=99'}}, '0.8.2'),
|
|
276
|
+
).toBeNull();
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
describe('loadComputerIntegrations', () => {
|
|
281
|
+
it("loads the compatible ones, marked as the computer's, and leaves out excluded and incompatible ones", async () => {
|
|
282
|
+
const {cli} = npmGlobal();
|
|
283
|
+
const found = scanComputerIntegrations({cliRoot: cli, release: '0.8.0'});
|
|
284
|
+
const loaded = await loadComputerIntegrations(found);
|
|
285
|
+
expect(loaded.map(c => [c.spec, c.integration?.__computer])).toEqual([
|
|
286
|
+
['@acme/widgets', true],
|
|
287
|
+
]);
|
|
288
|
+
expect(
|
|
289
|
+
await loadComputerIntegrations(found, {exclude: ['@acme/widgets']}),
|
|
290
|
+
).toEqual([]);
|
|
291
|
+
});
|
|
292
|
+
});
|
|
@@ -95,6 +95,17 @@ export function compareIdentities(local: ContributionIdentities, packed: Contrib
|
|
|
95
95
|
* @returns {string[]} unregistered PascalCase names
|
|
96
96
|
*/
|
|
97
97
|
export function findSourceOnlyCandidates(componentsRoot: string | undefined, registeredNames: string[]): string[];
|
|
98
|
+
/**
|
|
99
|
+
* Find `.tsx` files directly in a templates root that have no same-stem
|
|
100
|
+
* template metadata, so template discovery never lists them. Like the
|
|
101
|
+
* component check, it scans only direct children of the root: a file in a
|
|
102
|
+
* subfolder may be a helper a template imports. A file with a dotted stem (a
|
|
103
|
+
* test, story, or similar companion) is never a candidate.
|
|
104
|
+
*
|
|
105
|
+
* @param {string|undefined} templatesRoot absolute path
|
|
106
|
+
* @returns {string[]} basenames of the unpaired sources, sorted
|
|
107
|
+
*/
|
|
108
|
+
export function findTemplateSourceOnlyCandidates(templatesRoot: string | undefined): string[];
|
|
98
109
|
export type FileInventoryRoot = {
|
|
99
110
|
kind: "themes" | "components" | "templates" | "codemods" | "docs";
|
|
100
111
|
/**
|
|
@@ -248,11 +248,16 @@ export async function collectIdentities(loaded) {
|
|
|
248
248
|
if (loaded.components && fs.existsSync(loaded.components)) {
|
|
249
249
|
try {
|
|
250
250
|
const records = discoverIntegrationComponents(loaded) ?? [];
|
|
251
|
+
// A family doc backs several records: load it, and report it, once.
|
|
252
|
+
const loads = new Map();
|
|
251
253
|
for (const record of records) {
|
|
254
|
+
const first = !loads.has(record.docPath);
|
|
255
|
+
if (first) loads.set(record.docPath, loadComponentDoc(record.docPath));
|
|
252
256
|
try {
|
|
253
|
-
await
|
|
257
|
+
await loads.get(record.docPath);
|
|
254
258
|
identities.components.push(record.name);
|
|
255
259
|
} catch (err) {
|
|
260
|
+
if (!first) continue;
|
|
256
261
|
errors.push({
|
|
257
262
|
kind: 'components',
|
|
258
263
|
message: `${path.relative(loaded.components, record.docPath)}: ${
|
|
@@ -314,8 +319,11 @@ export async function collectIdentities(loaded) {
|
|
|
314
319
|
|
|
315
320
|
if (loaded.docs && fs.existsSync(loaded.docs)) {
|
|
316
321
|
try {
|
|
317
|
-
const {
|
|
318
|
-
|
|
322
|
+
const {
|
|
323
|
+
records,
|
|
324
|
+
guides,
|
|
325
|
+
errors: docErrors,
|
|
326
|
+
} = await discoverIntegrationDocs(loaded);
|
|
319
327
|
for (const docError of docErrors) {
|
|
320
328
|
errors.push({kind: 'docs', message: docError.message});
|
|
321
329
|
}
|
|
@@ -498,3 +506,48 @@ export function findSourceOnlyCandidates(componentsRoot, registeredNames) {
|
|
|
498
506
|
}
|
|
499
507
|
return candidates.sort();
|
|
500
508
|
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Metadata suffixes that pair a template source with its spec: the canonical
|
|
512
|
+
* `.doc.*` family and the released `.template.*` compatibility family.
|
|
513
|
+
*/
|
|
514
|
+
const TEMPLATE_DOC_SUFFIXES = [
|
|
515
|
+
'.doc.ts',
|
|
516
|
+
'.doc.mjs',
|
|
517
|
+
'.doc.js',
|
|
518
|
+
'.template.ts',
|
|
519
|
+
'.template.mjs',
|
|
520
|
+
'.template.js',
|
|
521
|
+
];
|
|
522
|
+
|
|
523
|
+
/** A `.tsx` source and its stem, which may hold a dot (`landing.page`). */
|
|
524
|
+
const TSX_SOURCE = /^(.+)\.tsx$/u;
|
|
525
|
+
|
|
526
|
+
/** A test, spec or story stem: never a template. */
|
|
527
|
+
const NOT_A_TEMPLATE = /\.(?:test|spec|stories)$/u;
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Find `.tsx` files directly in a templates root that have no same-stem
|
|
531
|
+
* template metadata, so template discovery never lists them. Like the
|
|
532
|
+
* component check, it scans only direct children of the root: a file in a
|
|
533
|
+
* subfolder may be a helper a template imports. A file with a dotted stem (a
|
|
534
|
+
* test, story, or similar companion) is never a candidate.
|
|
535
|
+
*
|
|
536
|
+
* @param {string|undefined} templatesRoot absolute path
|
|
537
|
+
* @returns {string[]} basenames of the unpaired sources, sorted
|
|
538
|
+
*/
|
|
539
|
+
export function findTemplateSourceOnlyCandidates(templatesRoot) {
|
|
540
|
+
if (!templatesRoot || !fs.existsSync(templatesRoot)) return [];
|
|
541
|
+
/** @type {string[]} */
|
|
542
|
+
const candidates = [];
|
|
543
|
+
for (const entry of fs.readdirSync(templatesRoot, {withFileTypes: true})) {
|
|
544
|
+
if (!entry.isFile() && !entry.isSymbolicLink()) continue;
|
|
545
|
+
const match = entry.name.match(TSX_SOURCE);
|
|
546
|
+
if (!match || NOT_A_TEMPLATE.test(match[1])) continue;
|
|
547
|
+
const paired = TEMPLATE_DOC_SUFFIXES.some(suffix =>
|
|
548
|
+
fs.existsSync(path.join(templatesRoot, `${match[1]}${suffix}`)),
|
|
549
|
+
);
|
|
550
|
+
if (!paired) candidates.push(entry.name);
|
|
551
|
+
}
|
|
552
|
+
return candidates.sort();
|
|
553
|
+
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import {validateLoadedIntegration} from './validate-contributions.mjs';
|
|
24
|
+
import {formatCliCommand} from '../env/package-manager.mjs';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* For each configured (already-loaded) integration, compute its issues using
|
|
@@ -81,8 +82,8 @@ export async function warnOnIntegrationIssues(source, {json = false} = {}) {
|
|
|
81
82
|
|
|
82
83
|
for (const [pkg, count] of issueCounts) {
|
|
83
84
|
const command = fromProject
|
|
84
|
-
? '
|
|
85
|
-
: `
|
|
85
|
+
? formatCliCommand('doctor')
|
|
86
|
+
: formatCliCommand(`doctor integration validate ${pkg}`);
|
|
86
87
|
console.error(
|
|
87
88
|
`Warning: ${pkg} has ${count} integration issue(s). Run: ${command}`,
|
|
88
89
|
);
|
|
@@ -61,9 +61,8 @@ describe('warnOnIntegrationIssues', () => {
|
|
|
61
61
|
await warnOnIntegrationIssues([integration], {json: false});
|
|
62
62
|
|
|
63
63
|
expect(errLines).toHaveLength(1);
|
|
64
|
-
expect(errLines[0]).
|
|
65
|
-
|
|
66
|
-
'Run: astryx doctor integration validate @acme/widgets',
|
|
64
|
+
expect(errLines[0]).toMatch(
|
|
65
|
+
/^Warning: @acme\/widgets has 1 integration issue\(s\)\. Run: .+ doctor integration validate @acme\/widgets$/,
|
|
67
66
|
);
|
|
68
67
|
});
|
|
69
68
|
|
|
@@ -81,9 +80,10 @@ describe('warnOnIntegrationIssues', () => {
|
|
|
81
80
|
|
|
82
81
|
await warnOnIntegrationIssues(project, {json: false});
|
|
83
82
|
|
|
84
|
-
expect(errLines).
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
expect(errLines).toHaveLength(1);
|
|
84
|
+
expect(errLines[0]).toMatch(
|
|
85
|
+
/^Warning: @acme\/later has 1 integration issue\(s\)\. Run: .+ doctor$/,
|
|
86
|
+
);
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
it('emits nothing in --json mode (keeps stdout/JSON clean)', async () => {
|
|
@@ -103,9 +103,8 @@ describe('warnOnIntegrationIssues', () => {
|
|
|
103
103
|
await warnOnIntegrationIssues([integration], {json: false});
|
|
104
104
|
|
|
105
105
|
expect(errLines).toHaveLength(1);
|
|
106
|
-
expect(errLines[0]).
|
|
107
|
-
|
|
108
|
-
'Run: astryx doctor integration validate @acme/stale',
|
|
106
|
+
expect(errLines[0]).toMatch(
|
|
107
|
+
/^Warning: @acme\/stale has 1 integration issue\(s\)\. Run: .+ doctor integration validate @acme\/stale$/,
|
|
109
108
|
);
|
|
110
109
|
});
|
|
111
110
|
|
|
@@ -45,7 +45,7 @@ export function findManifestPaths(dir: string): string[];
|
|
|
45
45
|
* @param {string} file absolute manifest path
|
|
46
46
|
* @param {string} [label] used in error messages
|
|
47
47
|
* @param {{fresh?: boolean}} [options]
|
|
48
|
-
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string}>}
|
|
48
|
+
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string, cliCommandError?: string}>}
|
|
49
49
|
*/
|
|
50
50
|
export function loadManifest(file: string, label?: string, { fresh }?: {
|
|
51
51
|
fresh?: boolean;
|
|
@@ -58,6 +58,7 @@ export function loadManifest(file: string, label?: string, { fresh }?: {
|
|
|
58
58
|
discover?: import("../../authoring/discover/type").DiscoverSource;
|
|
59
59
|
discoverError?: string;
|
|
60
60
|
agentDocsError?: string;
|
|
61
|
+
cliCommandError?: string;
|
|
61
62
|
}>;
|
|
62
63
|
/**
|
|
63
64
|
* Load and validate a manifest module's default export against the integration
|
|
@@ -126,6 +127,10 @@ export function loadIntegrations(specs?: string[], { cwd, fresh, resolveProvider
|
|
|
126
127
|
* @property {string} [themes]
|
|
127
128
|
* @property {string} [issuesUrl]
|
|
128
129
|
* @property {{append?: readonly string[]}} [agentDocs]
|
|
130
|
+
* @property {string} [cliCommand] the command this package's users run the
|
|
131
|
+
* CLI with; read by the picker in foundation/env (see cli-command.mjs)
|
|
132
|
+
* @property {string} [__cliCommandError] why a declared `cliCommand` was
|
|
133
|
+
* ignored; the rest of the manifest still contributes
|
|
129
134
|
* @property {string} [__agentDocsError] contribution-specific validation
|
|
130
135
|
* failure; other manifest contributions remain available
|
|
131
136
|
* @property {string} __spec
|
|
@@ -145,6 +150,9 @@ export function loadIntegrations(specs?: string[], { cwd, fresh, resolveProvider
|
|
|
145
150
|
* @property {boolean} [__autolinked] loaded because the project declares the
|
|
146
151
|
* package as a dependency and it ships a manifest, with no astryx.config
|
|
147
152
|
* entry naming it — see foundation/integrations/autolink.mjs
|
|
153
|
+
* @property {boolean} [__computer] loaded because it is installed beside the
|
|
154
|
+
* running CLI and the folder is outside a project (spec AST-081 FR12) — see
|
|
155
|
+
* foundation/integrations/computer-integrations.mjs
|
|
148
156
|
* @property {boolean} [__local] loaded from the package containing the current
|
|
149
157
|
* working directory, so an author sees the exact bytes they are editing
|
|
150
158
|
* @property {string} [__dependencyField] for an autolinked integration, the
|
|
@@ -186,6 +194,16 @@ export type LoadedIntegration = {
|
|
|
186
194
|
agentDocs?: {
|
|
187
195
|
append?: readonly string[];
|
|
188
196
|
} | undefined;
|
|
197
|
+
/**
|
|
198
|
+
* the command this package's users run the
|
|
199
|
+
* CLI with; read by the picker in foundation/env (see cli-command.mjs)
|
|
200
|
+
*/
|
|
201
|
+
cliCommand?: string | undefined;
|
|
202
|
+
/**
|
|
203
|
+
* why a declared `cliCommand` was
|
|
204
|
+
* ignored; the rest of the manifest still contributes
|
|
205
|
+
*/
|
|
206
|
+
__cliCommandError?: string | undefined;
|
|
189
207
|
/**
|
|
190
208
|
* contribution-specific validation
|
|
191
209
|
* failure; other manifest contributions remain available
|
|
@@ -226,6 +244,12 @@ export type LoadedIntegration = {
|
|
|
226
244
|
* entry naming it — see foundation/integrations/autolink.mjs
|
|
227
245
|
*/
|
|
228
246
|
__autolinked?: boolean | undefined;
|
|
247
|
+
/**
|
|
248
|
+
* loaded because it is installed beside the
|
|
249
|
+
* running CLI and the folder is outside a project (spec AST-081 FR12) — see
|
|
250
|
+
* foundation/integrations/computer-integrations.mjs
|
|
251
|
+
*/
|
|
252
|
+
__computer?: boolean | undefined;
|
|
229
253
|
/**
|
|
230
254
|
* loaded from the package containing the current
|
|
231
255
|
* working directory, so an author sees the exact bytes they are editing
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* Integrations are PACKAGE NAMES listed in astryx.config.{ts,mjs,js}. Each
|
|
7
7
|
* package declares a single conventional root manifest sibling to its
|
|
8
8
|
* package.json — astryx.integration.{ts,mjs,js} — which contributes
|
|
9
|
-
* components/templates/codemods/docs/themes roots
|
|
9
|
+
* components/templates/codemods/docs/themes roots, an optional issuesUrl, and
|
|
10
|
+
* an optional cliCommand.
|
|
10
11
|
* Stable provider identity and package metadata come from package.json, not the
|
|
11
12
|
* manifest.
|
|
12
13
|
*
|
|
@@ -24,6 +25,7 @@ import {normalizeProviderId} from '../identity/provider-identity.mjs';
|
|
|
24
25
|
// the loader can isolate an invalid optional contribution from valid roots.
|
|
25
26
|
import {
|
|
26
27
|
parseAgentDocsField,
|
|
28
|
+
parseCliCommandField,
|
|
27
29
|
parseIntegrationBase,
|
|
28
30
|
unknownIntegrationKeys,
|
|
29
31
|
} from '../../authoring/integration/schema.mjs';
|
|
@@ -51,6 +53,10 @@ import {resolveProviders} from './provider-resolution.mjs';
|
|
|
51
53
|
* @property {string} [themes]
|
|
52
54
|
* @property {string} [issuesUrl]
|
|
53
55
|
* @property {{append?: readonly string[]}} [agentDocs]
|
|
56
|
+
* @property {string} [cliCommand] the command this package's users run the
|
|
57
|
+
* CLI with; read by the picker in foundation/env (see cli-command.mjs)
|
|
58
|
+
* @property {string} [__cliCommandError] why a declared `cliCommand` was
|
|
59
|
+
* ignored; the rest of the manifest still contributes
|
|
54
60
|
* @property {string} [__agentDocsError] contribution-specific validation
|
|
55
61
|
* failure; other manifest contributions remain available
|
|
56
62
|
* @property {string} __spec
|
|
@@ -70,6 +76,9 @@ import {resolveProviders} from './provider-resolution.mjs';
|
|
|
70
76
|
* @property {boolean} [__autolinked] loaded because the project declares the
|
|
71
77
|
* package as a dependency and it ships a manifest, with no astryx.config
|
|
72
78
|
* entry naming it — see foundation/integrations/autolink.mjs
|
|
79
|
+
* @property {boolean} [__computer] loaded because it is installed beside the
|
|
80
|
+
* running CLI and the folder is outside a project (spec AST-081 FR12) — see
|
|
81
|
+
* foundation/integrations/computer-integrations.mjs
|
|
73
82
|
* @property {boolean} [__local] loaded from the package containing the current
|
|
74
83
|
* working directory, so an author sees the exact bytes they are editing
|
|
75
84
|
* @property {string} [__dependencyField] for an autolinked integration, the
|
|
@@ -204,7 +213,7 @@ function parseDiscoverSourceExport(value, label) {
|
|
|
204
213
|
* @param {string} file absolute manifest path
|
|
205
214
|
* @param {string} [label] used in error messages
|
|
206
215
|
* @param {{fresh?: boolean}} [options]
|
|
207
|
-
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string}>}
|
|
216
|
+
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string, cliCommandError?: string}>}
|
|
208
217
|
*/
|
|
209
218
|
export async function loadManifest(
|
|
210
219
|
file,
|
|
@@ -239,8 +248,31 @@ export async function loadManifest(
|
|
|
239
248
|
}
|
|
240
249
|
}
|
|
241
250
|
|
|
251
|
+
/** @type {string | undefined} */
|
|
252
|
+
let cliCommand;
|
|
253
|
+
/** @type {string | undefined} */
|
|
254
|
+
let cliCommandError;
|
|
255
|
+
const rawCliCommand =
|
|
256
|
+
raw != null && typeof raw === 'object' && !Array.isArray(raw)
|
|
257
|
+
? /** @type {{cliCommand?: unknown}} */ (raw).cliCommand
|
|
258
|
+
: undefined;
|
|
259
|
+
if (rawCliCommand !== undefined) {
|
|
260
|
+
try {
|
|
261
|
+
cliCommand = parseCliCommandField(
|
|
262
|
+
rawCliCommand,
|
|
263
|
+
`${label} field "cliCommand"`,
|
|
264
|
+
);
|
|
265
|
+
} catch (err) {
|
|
266
|
+
cliCommandError = err instanceof Error ? err.message : String(err);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
242
270
|
return {
|
|
243
|
-
manifest:
|
|
271
|
+
manifest: {
|
|
272
|
+
...baseManifest,
|
|
273
|
+
...(agentDocs == null ? {} : {agentDocs}),
|
|
274
|
+
...(cliCommand == null ? {} : {cliCommand}),
|
|
275
|
+
},
|
|
244
276
|
unknownKeys: unknownIntegrationKeys(raw),
|
|
245
277
|
debug:
|
|
246
278
|
typeof mod?.debug === 'function'
|
|
@@ -253,6 +285,7 @@ export async function loadManifest(
|
|
|
253
285
|
discover: discover.source,
|
|
254
286
|
discoverError: discover.error,
|
|
255
287
|
agentDocsError,
|
|
288
|
+
cliCommandError,
|
|
256
289
|
};
|
|
257
290
|
}
|
|
258
291
|
|
|
@@ -375,6 +408,8 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
375
408
|
let discoverError;
|
|
376
409
|
/** @type {string | undefined} */
|
|
377
410
|
let agentDocsError;
|
|
411
|
+
/** @type {string | undefined} */
|
|
412
|
+
let cliCommandError;
|
|
378
413
|
try {
|
|
379
414
|
({
|
|
380
415
|
manifest,
|
|
@@ -385,6 +420,7 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
385
420
|
discover: discoverSource,
|
|
386
421
|
discoverError,
|
|
387
422
|
agentDocsError,
|
|
423
|
+
cliCommandError,
|
|
388
424
|
} = await loadManifest(manifestFile, `Integration ${spec}`, {fresh}));
|
|
389
425
|
} catch (err) {
|
|
390
426
|
return {
|
|
@@ -422,6 +458,8 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
422
458
|
themes: resolveRoot(manifest.themes),
|
|
423
459
|
issuesUrl: manifest.issuesUrl,
|
|
424
460
|
agentDocs: manifest.agentDocs,
|
|
461
|
+
cliCommand: manifest.cliCommand,
|
|
462
|
+
__cliCommandError: cliCommandError,
|
|
425
463
|
__agentDocsError: agentDocsError,
|
|
426
464
|
__unknownKeys: unknownKeys,
|
|
427
465
|
__debug: debugHandler,
|
|
@@ -486,6 +524,8 @@ export async function loadIntegrations(
|
|
|
486
524
|
let discoverError;
|
|
487
525
|
/** @type {string | undefined} */
|
|
488
526
|
let agentDocsError;
|
|
527
|
+
/** @type {string | undefined} */
|
|
528
|
+
let cliCommandError;
|
|
489
529
|
try {
|
|
490
530
|
({
|
|
491
531
|
manifest,
|
|
@@ -496,6 +536,7 @@ export async function loadIntegrations(
|
|
|
496
536
|
discover: discoverSource,
|
|
497
537
|
discoverError,
|
|
498
538
|
agentDocsError,
|
|
539
|
+
cliCommandError,
|
|
499
540
|
} = await loadManifest(manifestFile, `Integration ${spec}`, {fresh}));
|
|
500
541
|
} catch (err) {
|
|
501
542
|
// A manifest that throws on import or fails schema validation must NOT take
|
|
@@ -540,6 +581,8 @@ export async function loadIntegrations(
|
|
|
540
581
|
themes: resolveRoot(manifest.themes),
|
|
541
582
|
issuesUrl: manifest.issuesUrl,
|
|
542
583
|
agentDocs: manifest.agentDocs,
|
|
584
|
+
cliCommand: manifest.cliCommand,
|
|
585
|
+
__cliCommandError: cliCommandError,
|
|
543
586
|
__agentDocsError: agentDocsError,
|
|
544
587
|
__unknownKeys: unknownKeys,
|
|
545
588
|
__debug: debugHandler,
|
|
@@ -15,4 +15,10 @@ export interface AstryxIntegrationIssue {
|
|
|
15
15
|
code: string;
|
|
16
16
|
severity: 'warning' | 'error';
|
|
17
17
|
message: string;
|
|
18
|
+
/** What to change, ready to paste, when the check knows it. */
|
|
19
|
+
fix?: string;
|
|
20
|
+
/** The file the issue is in, relative to the package. */
|
|
21
|
+
file?: string;
|
|
22
|
+
/** The 1-based line in `file`, when the check can locate it. */
|
|
23
|
+
line?: number;
|
|
18
24
|
}
|
|
@@ -38,6 +38,8 @@ export function validateLoadedIntegration(loaded: LoadedIntegration): Promise<Is
|
|
|
38
38
|
*/
|
|
39
39
|
/** Stable issue code for an invalid optional agent-doc contribution. */
|
|
40
40
|
export const INVALID_AGENT_DOCS: "invalid_agent_docs";
|
|
41
|
+
/** Stable issue code for a `cliCommand` that was ignored as invalid. */
|
|
42
|
+
export const INVALID_CLI_COMMAND: "invalid_cli_command";
|
|
41
43
|
/** Stable issue code for a package whose provider ID is already claimed. */
|
|
42
44
|
export const DUPLICATE_PROVIDER: "duplicate_provider";
|
|
43
45
|
export type Issue = import("./issue").AstryxIntegrationIssue;
|