@astryxdesign/cli 0.7.2-canary.fdd384f → 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 +169 -149
- 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/kit/kit.mjs +3 -11
- package/api/component/_adapter.d.mts +31 -0
- package/api/component/_adapter.mjs +119 -11
- package/api/component/component.doc.mjs +6 -1
- package/api/component/component.mjs +60 -10
- package/api/component/doc-links.test.mjs +386 -0
- 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 +63 -0
- package/api/docs/_adapter.mjs +312 -18
- 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/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 +16 -3
- 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 +152 -48
- 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/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 +15 -4
- 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 +33 -0
- package/api/integration/_adapter.mjs +58 -0
- package/api/integration/authoring-checks.mjs +100 -5
- package/api/integration/authoring-checks.test.mjs +769 -0
- package/api/integration/authoring-checks.type.d.mts +134 -0
- package/api/integration/authoring-checks.type.mjs +60 -1
- package/api/integration/integrationCheck.doc.mjs +1 -1
- package/api/integration/integrationComponentConflicts.doc.mjs +11 -3
- package/api/integration/integrationDocConflicts.doc.mjs +22 -5
- package/api/integration/pack-check.mjs +303 -13
- package/api/integration/pack-check.test.mjs +371 -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 +55 -9
- package/api/integration/validate-integration.test.mjs +77 -8
- package/api/integration/validate-integration.type.d.mts +8 -0
- package/api/integration/validate-integration.type.mjs +3 -1
- package/api/integration/validate-unread-theme-folders.test.mjs +3 -2
- package/api/integration/validateIntegration.doc.mjs +4 -2
- package/api/search/_adapter.d.mts +11 -0
- package/api/search/_adapter.mjs +25 -0
- package/api/search/search.d.mts +73 -13
- package/api/search/search.doc.mjs +8 -3
- package/api/search/search.domain-priority.test.mjs +108 -18
- package/api/search/search.mjs +541 -52
- package/api/search/search.test.mjs +143 -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 +1 -1
- package/api/template/template-integration.test.mjs +1 -1
- 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.mjs +70 -14
- 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/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/next/index.mjs +1 -11
- package/assets/codemods/transforms/v0.7.2/index.mjs +20 -0
- package/assets/discover/official-packages.json +367 -0
- package/assets/docs/author-a-theme.doc.mjs +2 -2
- package/assets/docs/browser-support.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +23 -3
- package/assets/docs/styling-overview.doc.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +12 -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 +6 -18
- 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 +8 -3
- package/assets/docs/tree/check-your-docs.doc.mjs +30 -13
- package/assets/docs/tree/checks.doc.mjs +17 -17
- 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 +3 -5
- package/assets/docs/tree/component-imports.doc.mjs +13 -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 +2 -2
- 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 +6 -5
- 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 +3 -7
- 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 +52 -26
- 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 +9 -11
- 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 +14 -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 +22 -14
- 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 +9 -9
- package/assets/docs/tree/who-answers.doc.mjs +119 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +5 -5
- package/assets/docs/working-with-ai.doc.mjs +23 -9
- 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 +29 -26
- package/authoring/doctypes/component/type.ts +15 -5
- 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/template.doc.mjs +2 -2
- 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 +1 -0
- package/authoring/integration/integration.doc.mjs +22 -5
- package/authoring/integration/parse.test.mjs +11 -0
- package/authoring/integration/schema.d.mts +14 -3
- package/authoring/integration/schema.mjs +33 -2
- package/authoring/integration/type.ts +8 -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 +14 -2
- package/clients/cli/commands/build-theme.font-warning.test.mjs +3 -3
- package/clients/cli/commands/build-theme.mjs +25 -12
- 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 +7 -3
- 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 +13 -2
- package/clients/cli/commands/doctor-integration.test.mjs +52 -4
- package/clients/cli/commands/doctor.doc.mjs +12 -2
- package/clients/cli/commands/doctor.mjs +102 -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 +10 -2
- package/clients/cli/commands/integration-check.test.mjs +175 -1
- 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.mjs +15 -9
- 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/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 +1 -0
- 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 +111 -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 +145 -8
- package/foundation/config/project.test.mjs +66 -0
- package/foundation/config/theme-state.mjs +5 -4
- package/foundation/discovery/authoring-self-docs.mjs +1 -1
- package/foundation/discovery/cli-self-docs.mjs +20 -3
- package/foundation/discovery/cli-self-docs.test.mjs +3 -2
- package/foundation/discovery/component-replacement.mjs +2 -1
- 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 +1 -1
- package/foundation/discovery/doc-types.mjs +15 -8
- package/foundation/discovery/doc-types.test.mjs +94 -2
- package/foundation/discovery/docs-discovery.d.mts +7 -0
- package/foundation/discovery/docs-discovery.mjs +26 -2
- package/foundation/discovery/project-typescript.d.mts +11 -2
- package/foundation/discovery/project-typescript.mjs +32 -4
- package/foundation/discovery/prop-drift.d.mts +26 -7
- package/foundation/discovery/prop-drift.mjs +173 -8
- package/foundation/discovery/prop-drift.test.mjs +120 -2
- 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-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-text.mjs +1 -1
- package/foundation/discovery/type-text.test.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +42 -2
- package/foundation/doc-compiler/inputs.mjs +4 -1
- package/foundation/doc-compiler/links.d.mts +32 -0
- package/foundation/doc-compiler/links.mjs +163 -26
- 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 +50 -2
- 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 +17 -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/package.json +11 -11
- package/scripts/postinstall.mjs +24 -5
- /package/assets/codemods/transforms/{next → v0.7.2}/__tests__/migrate-list-edge-compensation-to-edge.test.mjs +0 -0
- /package/assets/codemods/transforms/{next → v0.7.2}/migrate-list-edge-compensation-to-edge.mjs +0 -0
package/clients/cli/index.mjs
CHANGED
|
@@ -16,8 +16,14 @@ import {Command, Option} from 'commander';
|
|
|
16
16
|
import {fileURLToPath} from 'node:url';
|
|
17
17
|
import * as fs from 'node:fs';
|
|
18
18
|
import * as path from 'node:path';
|
|
19
|
-
import {getCliInvocation} from '../../foundation/env/package-manager.mjs';
|
|
19
|
+
import {formatCliCommand, getCliInvocation} from '../../foundation/env/package-manager.mjs';
|
|
20
|
+
import {hasRecordedProject} from '../../foundation/env/cli-command.mjs';
|
|
21
|
+
import {isOutsideProject} from '../../foundation/env/project-scope.mjs';
|
|
20
22
|
import {API_VERSION, setJsonMode} from '../../foundation/response/json.mjs';
|
|
23
|
+
import {answeredBy, runChoice} from '../../foundation/release/run-context.mjs';
|
|
24
|
+
import {addCliCommand} from '../../foundation/release/notices.mjs';
|
|
25
|
+
import {projectRootOf} from '../../foundation/release/choose.mjs';
|
|
26
|
+
import {readReleaseFacts} from '../../foundation/release/project.mjs';
|
|
21
27
|
import {buildManifest} from './lib/manifest.mjs';
|
|
22
28
|
import {cliError} from './lib/cli-error.mjs';
|
|
23
29
|
import {emit, section, text, records} from './formatters/index.mjs';
|
|
@@ -26,7 +32,9 @@ import {levenshteinDistance} from '../../foundation/text/string-utils.mjs';
|
|
|
26
32
|
import {installJsonShim} from './lib/json-shim.mjs';
|
|
27
33
|
import {addDocHelp, markReportsResult} from './lib/define-command.mjs';
|
|
28
34
|
import {doc as manifestDoc} from './commands/manifest.doc.mjs';
|
|
29
|
-
import {isAstryxInitialized} from '../../foundation/agent-docs/agent-docs.mjs';
|
|
35
|
+
import {isAstryxInitialized, isAstryxPromptInReach} from '../../foundation/agent-docs/agent-docs.mjs';
|
|
36
|
+
import {CLI_ROOT} from '../../foundation/fs/paths.mjs';
|
|
37
|
+
import {setupNudge} from '../../foundation/agent-docs/agent-doc-state.mjs';
|
|
30
38
|
import * as debug from '../../foundation/debug/index.mjs';
|
|
31
39
|
|
|
32
40
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -63,7 +71,7 @@ export function handleVersionJsonPreflight(argv = process.argv.slice(2)) {
|
|
|
63
71
|
// reports the same shape Commander's own `--version` path does.
|
|
64
72
|
debug.recordCommandResult(debug.NO_RESULT_SET);
|
|
65
73
|
debug.setOutcome('ok', {exitCode: 0});
|
|
66
|
-
console.log(JSON.stringify({apiVersion: API_VERSION, type: 'version', data: {version: pkg.version}}, null, 2));
|
|
74
|
+
console.log(JSON.stringify({apiVersion: API_VERSION, type: 'version', data: {version: pkg.version}, meta: {answeredBy: answeredBy()}}, null, 2));
|
|
67
75
|
process.exit(0);
|
|
68
76
|
}
|
|
69
77
|
|
|
@@ -185,6 +193,31 @@ export async function loadProjectDebugHandler() {
|
|
|
185
193
|
}
|
|
186
194
|
}
|
|
187
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Load the project's integrations before a help run, so help prints commands
|
|
198
|
+
* with the `cliCommand` they declare (spec:AST-081 FR5). Help is printed while
|
|
199
|
+
* Commander parses, before any hook, so the preAction load cannot reach it.
|
|
200
|
+
* `Project.load` reads astryx.config and each integration's manifest; it does
|
|
201
|
+
* no discovery. Skipped when the debug preload already loaded the project, and
|
|
202
|
+
* outside a package. Called from the bin before Commander parses.
|
|
203
|
+
*
|
|
204
|
+
* @param {string[]} [argv] arguments after the binary.
|
|
205
|
+
* @returns {Promise<void>}
|
|
206
|
+
*/
|
|
207
|
+
export async function loadProjectForHelp(argv = process.argv.slice(2)) {
|
|
208
|
+
const help =
|
|
209
|
+
argv.includes('--help') || argv.includes('-h') || argv[0] === 'help';
|
|
210
|
+
if (!help) return;
|
|
211
|
+
try {
|
|
212
|
+
const cwd = process.cwd();
|
|
213
|
+
if (hasRecordedProject(cwd)) return;
|
|
214
|
+
const {Project} = await import('../../foundation/config/project.mjs');
|
|
215
|
+
await Project.load(cwd);
|
|
216
|
+
} catch {
|
|
217
|
+
// Help prints with the package-manager guess.
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
188
221
|
/**
|
|
189
222
|
* Hand the whole invocation to the debug recorder: which command ran, its
|
|
190
223
|
* positional arguments by name, its options and where each value came from,
|
|
@@ -277,6 +310,26 @@ const commands = [
|
|
|
277
310
|
];
|
|
278
311
|
|
|
279
312
|
const SETUP_NUDGE_EXEMPT = new Set(['init', 'agent-docs']);
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Is `cwd` inside the CLI's own source checkout while the CLI runs from it?
|
|
316
|
+
* An installed CLI always lives under `node_modules`; a CLI running from source
|
|
317
|
+
* does not, and its checkout is the pnpm workspace that holds it. Developing
|
|
318
|
+
* Astryx is not an app to set up, so the setup nudge stays quiet there.
|
|
319
|
+
* @param {string} cwd
|
|
320
|
+
* @returns {boolean}
|
|
321
|
+
*/
|
|
322
|
+
function inOwnSourceCheckout(cwd) {
|
|
323
|
+
if (CLI_ROOT.split(path.sep).includes('node_modules')) return false;
|
|
324
|
+
let checkout = CLI_ROOT;
|
|
325
|
+
while (!fs.existsSync(path.join(checkout, 'pnpm-workspace.yaml'))) {
|
|
326
|
+
const parent = path.dirname(checkout);
|
|
327
|
+
if (parent === checkout) return false;
|
|
328
|
+
checkout = parent;
|
|
329
|
+
}
|
|
330
|
+
const rel = path.relative(checkout, path.resolve(cwd));
|
|
331
|
+
return rel !== '..' && !rel.startsWith(`..${path.sep}`) && !path.isAbsolute(rel);
|
|
332
|
+
}
|
|
280
333
|
/** An integration package's manifest: the package is not an app to set up. */
|
|
281
334
|
const INTEGRATION_MANIFEST_FILES = [
|
|
282
335
|
'astryx.integration.ts',
|
|
@@ -308,7 +361,8 @@ export async function createProgram() {
|
|
|
308
361
|
// kit in clients/cli/formatters.
|
|
309
362
|
program.addHelpText(
|
|
310
363
|
'after',
|
|
311
|
-
|
|
364
|
+
// A function, so the example names the invocation when help is printed.
|
|
365
|
+
() => '\n' +
|
|
312
366
|
[
|
|
313
367
|
section(
|
|
314
368
|
'Output format',
|
|
@@ -331,9 +385,13 @@ export async function createProgram() {
|
|
|
331
385
|
{fields: ['block', 'shape']},
|
|
332
386
|
),
|
|
333
387
|
text(
|
|
334
|
-
|
|
388
|
+
`Grep a field across records, e.g. ${formatCliCommand('search button')} | grep "^command:". ` +
|
|
335
389
|
'Errors/warnings go to stderr; use --json for structured parsing.',
|
|
336
390
|
),
|
|
391
|
+
text(
|
|
392
|
+
"Global mode: in a project, the project's own CLI answers (this copy hands the run to it); a copy installed for the computer checks for updates once a day and keeps an agent skill in your home folder. " +
|
|
393
|
+
`See ${formatCliCommand('docs global')}.`,
|
|
394
|
+
),
|
|
337
395
|
]
|
|
338
396
|
.map(block => block.toString())
|
|
339
397
|
.join('\n\n'),
|
|
@@ -430,6 +488,7 @@ export async function createProgram() {
|
|
|
430
488
|
// Enriched, self-describing surface (the full manifest payload).
|
|
431
489
|
manifest,
|
|
432
490
|
},
|
|
491
|
+
meta: {answeredBy: answeredBy()},
|
|
433
492
|
}, null, 2));
|
|
434
493
|
debug.recordCommandResult(
|
|
435
494
|
debug.resultSet({
|
|
@@ -526,10 +585,29 @@ export async function createProgram() {
|
|
|
526
585
|
process.exit(1);
|
|
527
586
|
});
|
|
528
587
|
|
|
588
|
+
/**
|
|
589
|
+
* Load the project's integrations before any command runs, so every command
|
|
590
|
+
* it prints starts with the `cliCommand` they declare (the picker reads them
|
|
591
|
+
* synchronously; see foundation/env/cli-command.mjs). Skipped when this
|
|
592
|
+
* process already loaded the project, such as the bin's debug preload. A
|
|
593
|
+
* project that cannot load is the command's to report, never this hook's.
|
|
594
|
+
*/
|
|
595
|
+
program.hook('preAction', async () => {
|
|
596
|
+
try {
|
|
597
|
+
const cwd = process.cwd();
|
|
598
|
+
if (hasRecordedProject(cwd)) return;
|
|
599
|
+
const {Project} = await import('../../foundation/config/project.mjs');
|
|
600
|
+
await Project.load(cwd);
|
|
601
|
+
} catch {
|
|
602
|
+
// Best-effort: the picker falls back to its package-manager guess.
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
|
|
529
606
|
/**
|
|
530
607
|
* Enforcement layer 3 — setup nudge. If this project hasn't run `astryx init`
|
|
531
|
-
* yet (no Astryx marker in any agent-doc file
|
|
532
|
-
* the user/agent that
|
|
608
|
+
* yet (no Astryx marker in any agent-doc file between the project and its
|
|
609
|
+
* repository root — see isAstryxPromptInReach), remind the user/agent that
|
|
610
|
+
* setup is missing.
|
|
533
611
|
*
|
|
534
612
|
* Uses `preAction` (not postAction) so it fires for EVERY valid command — even
|
|
535
613
|
* ones whose action errors or calls process.exit (postAction is skipped then).
|
|
@@ -539,7 +617,9 @@ export async function createProgram() {
|
|
|
539
617
|
* consumers parse stdout, not stderr — a stderr nudge would not reach them anyway.
|
|
540
618
|
* The core/cli postinstall layers already nudge at install time regardless of
|
|
541
619
|
* --json; a machine-readable nudge could later be an envelope field. Also skipped
|
|
542
|
-
* for the installer commands themselves
|
|
620
|
+
* for the installer commands themselves, outside a project (no package.json,
|
|
621
|
+
* or one that neither installs nor declares Astryx), and inside the CLI's own
|
|
622
|
+
* source checkout when it runs from there.
|
|
543
623
|
*/
|
|
544
624
|
program.hook('preAction', (thisCommand, actionCommand) => {
|
|
545
625
|
try {
|
|
@@ -547,15 +627,30 @@ export async function createProgram() {
|
|
|
547
627
|
if (SETUP_NUDGE_EXEMPT.has(actionCommand.name())) return;
|
|
548
628
|
const cwd = process.cwd();
|
|
549
629
|
if (!fs.existsSync(path.join(cwd, 'package.json'))) return; // not a project
|
|
630
|
+
// A package.json that neither installs nor declares Astryx is outside a
|
|
631
|
+
// project: `init` would set up a project the folder does not have
|
|
632
|
+
// (spec AST-081 FR3).
|
|
633
|
+
if (isOutsideProject(cwd)) return;
|
|
550
634
|
// An integration package is not an app: `init` is not its next step.
|
|
551
635
|
if (INTEGRATION_MANIFEST_FILES.some(file => fs.existsSync(path.join(cwd, file)))) return;
|
|
552
|
-
if (
|
|
553
|
-
|
|
554
|
-
//
|
|
555
|
-
//
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
636
|
+
if (inOwnSourceCheckout(cwd)) return; // developing Astryx itself, not an app
|
|
637
|
+
if (isAstryxPromptInReach(cwd)) return; // already set up — stay quiet
|
|
638
|
+
// Same wording as the core/cli postinstall nudges. getCliInvocation()
|
|
639
|
+
// renders the correct form for THIS project — an integration's cliCommand,
|
|
640
|
+
// scoped `npx @astryxdesign/cli` one-off, or `<pm> astryx` when installed —
|
|
641
|
+
// never npx with the unscoped name, which fetches an unrelated package.
|
|
642
|
+
// A project with no CLI of its own, answered by another release than its
|
|
643
|
+
// Core's: add the CLI at Core's version first, as the daily hint says,
|
|
644
|
+
// then run that CLI's init (spec AST-081 FR2).
|
|
645
|
+
const choice = runChoice(cwd);
|
|
646
|
+
if (choice.copy === 'starting' && choice.coreVersion && choice.coreVersion !== choice.version) {
|
|
647
|
+
const root = projectRootOf(readReleaseFacts(cwd)) ?? cwd;
|
|
648
|
+
console.error(
|
|
649
|
+
setupNudge(getCliInvocation(root, {installed: true}), {before: addCliCommand(root, choice.coreVersion)}).trimEnd(),
|
|
650
|
+
);
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
console.error(setupNudge(getCliInvocation(cwd)).trimEnd());
|
|
559
654
|
} catch {
|
|
560
655
|
// Never let the nudge break a command.
|
|
561
656
|
}
|
|
@@ -608,7 +703,7 @@ export async function createProgram() {
|
|
|
608
703
|
);
|
|
609
704
|
if (program.opts().json) {
|
|
610
705
|
process.__xdsJsonHandled = true;
|
|
611
|
-
console.log(JSON.stringify({apiVersion: API_VERSION, type: 'manifest', data: manifest}, null, 2));
|
|
706
|
+
console.log(JSON.stringify({apiVersion: API_VERSION, type: 'manifest', data: manifest, meta: {answeredBy: answeredBy()}}, null, 2));
|
|
612
707
|
return;
|
|
613
708
|
}
|
|
614
709
|
// Human-readable summary as greppable records (agents should use --json).
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
import {isJsonMode, jsonError as _jsonError, humanWarn} from '../../../foundation/response/json.mjs';
|
|
54
54
|
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
55
55
|
import {setOutcome} from '../../../foundation/debug/index.mjs';
|
|
56
|
+
import {formatCliCommand} from '../../../foundation/env/package-manager.mjs';
|
|
56
57
|
|
|
57
58
|
/**
|
|
58
59
|
* Suggestion object — matches the shape used by API errors and the JSON
|
|
@@ -122,7 +123,9 @@ export function cliError(message, options = {}) {
|
|
|
122
123
|
if (suggestions?.length) {
|
|
123
124
|
console.error('');
|
|
124
125
|
for (const s of suggestions) {
|
|
125
|
-
|
|
126
|
+
// A suggested command stays bare in JSON and is prefixed here.
|
|
127
|
+
const name = /^astryx(\s|$)/.test(s.name) ? formatCliCommand(s.name) : s.name;
|
|
128
|
+
const tag = s.reason ? ` ${name} (${s.reason})` : ` ${name}`;
|
|
126
129
|
console.error(tag);
|
|
127
130
|
}
|
|
128
131
|
}
|
|
@@ -67,7 +67,7 @@ describe('formatFull sub-component rendering', () => {
|
|
|
67
67
|
expect(out).not.toContain('undefined');
|
|
68
68
|
// Points the reader at the sub-component's own docs instead of a blank.
|
|
69
69
|
expect(out).toMatch(
|
|
70
|
-
/(?:astryx|@astryxdesign\/cli) component XDSRadioListItem/,
|
|
70
|
+
/(?:astryx|@astryxdesign\/cli(?:@\S+)?) component XDSRadioListItem/,
|
|
71
71
|
);
|
|
72
72
|
});
|
|
73
73
|
|
|
@@ -180,8 +180,8 @@ export function defineCommand(parent, doc, {fn, action} = {}) {
|
|
|
180
180
|
*/
|
|
181
181
|
export function addDocHelp(cmd, doc) {
|
|
182
182
|
addExitCodesHelp(cmd, doc.exitCodes);
|
|
183
|
-
// Rendered when help is shown, so the run prefix (
|
|
184
|
-
// ...) is looked up then, not on every start.
|
|
183
|
+
// Rendered when help is shown, so the run prefix (pnpm exec astryx, yarn
|
|
184
|
+
// astryx, ...) is looked up then, not on every start.
|
|
185
185
|
cmd.addHelpText('after', () => {
|
|
186
186
|
const examples = (doc.examples ?? []).flatMap(({label, cli}) => [
|
|
187
187
|
...(label ? [` # ${label}`] : []),
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
44
|
import {API_VERSION, isJsonMode, toErrorEnvelope} from '../../../foundation/response/json.mjs';
|
|
45
|
+
import {answeredBy} from '../../../foundation/release/run-context.mjs';
|
|
45
46
|
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
46
47
|
import {setCommand, setOutcome, recordHelp} from '../../../foundation/debug/index.mjs';
|
|
47
48
|
|
|
@@ -84,7 +85,7 @@ function jsonActive() {
|
|
|
84
85
|
* subcommand (e.g. `astryx component --help --json`).
|
|
85
86
|
*
|
|
86
87
|
* @param {import('commander').Command} cmd
|
|
87
|
-
* @returns {{apiVersion: number, type: 'help', data: object}}
|
|
88
|
+
* @returns {{apiVersion: number, type: 'help', data: object, meta: {answeredBy: {cli: string, core: string | null, copy: 'project' | 'starting' | 'matched' | 'carried' | 'fallback'}}}}
|
|
88
89
|
*/
|
|
89
90
|
export function buildHelpEnvelope(cmd) {
|
|
90
91
|
// Reconstruct the fully-qualified command name (e.g. "astryx theme build").
|
|
@@ -119,6 +120,7 @@ export function buildHelpEnvelope(cmd) {
|
|
|
119
120
|
options,
|
|
120
121
|
subcommands,
|
|
121
122
|
},
|
|
123
|
+
meta: {answeredBy: answeredBy()},
|
|
122
124
|
};
|
|
123
125
|
}
|
|
124
126
|
|
|
@@ -50,6 +50,13 @@ export interface ManifestCommand {
|
|
|
50
50
|
examples?: string[];
|
|
51
51
|
/** Documented exit codes: the process exit status and when it occurs. */
|
|
52
52
|
exitCodes?: {code: number; when: string}[];
|
|
53
|
+
/**
|
|
54
|
+
* What the command does in a folder outside any project: `same` gives the
|
|
55
|
+
* answer it gives in a new project; `refuse` writes nothing and fails, naming
|
|
56
|
+
* the app project or integration package it needs; `own` does something
|
|
57
|
+
* else, which its docs state. Absent on a group that only holds subcommands.
|
|
58
|
+
*/
|
|
59
|
+
outsideProject?: 'same' | 'refuse' | 'own';
|
|
53
60
|
/** Nested subcommands (e.g. `theme build` under `theme`). */
|
|
54
61
|
subcommands?: ManifestCommand[];
|
|
55
62
|
}
|
|
@@ -64,6 +71,8 @@ export interface CLIManifest {
|
|
|
64
71
|
commands: ManifestCommand[];
|
|
65
72
|
/** Sorted list of fully-qualified command names that support `--json`. */
|
|
66
73
|
jsonSupported: string[];
|
|
74
|
+
/** What a run may do beyond its command (the hand-off, the daily update check, the agent skill), and the docs topic that explains it. */
|
|
75
|
+
globalMode: {docs: string; summary: string};
|
|
67
76
|
/** Flat index of response `type` discriminators keyed by command name. */
|
|
68
77
|
responseTypes: Record<string, string[]>;
|
|
69
78
|
}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Its per-command facts come from the command's own definitions: names,
|
|
11
11
|
* arguments and options from Commander metadata (program.commands, cmd.options,
|
|
12
|
-
* cmd.registeredArguments, cmd.description()); examples
|
|
12
|
+
* cmd.registeredArguments, cmd.description()); examples, exit codes, and what
|
|
13
|
+
* it does outside a project from its CommandDoc;
|
|
13
14
|
* response `type` discriminators from the returns of the FunctionDoc it wraps
|
|
14
15
|
* (both attached by `defineCommand`); `--json` support from the JSON_SUPPORTED
|
|
15
16
|
* allowlist in index.mjs. The hand-kept lists are CLI_LAYER_RESPONSE_TYPES,
|
|
@@ -39,6 +40,16 @@ import {API_VERSION} from '../../../foundation/response/json.mjs';
|
|
|
39
40
|
import {commandDocsOf} from './define-command.mjs';
|
|
40
41
|
import {doc as manifestDoc} from '../commands/manifest.doc.mjs';
|
|
41
42
|
|
|
43
|
+
/**
|
|
44
|
+
* What a run may do beyond the command it was asked for (spec AST-081;
|
|
45
|
+
* `spec:AST-017` FR14), and where it is explained.
|
|
46
|
+
*/
|
|
47
|
+
export const GLOBAL_MODE = Object.freeze({
|
|
48
|
+
docs: 'astryx docs global',
|
|
49
|
+
summary:
|
|
50
|
+
"In a folder that belongs to a project, the project's own CLI answers: this copy hands the run to it. In a project with no CLI of its own, and outside any project, this copy answers. A copy installed for the computer checks the registry for a newer release once a day in the background, and keeps one agent skill file in the home folder.",
|
|
51
|
+
});
|
|
52
|
+
|
|
42
53
|
/**
|
|
43
54
|
* Envelopes the CLI layer builds itself, so the wrapped FunctionDoc cannot
|
|
44
55
|
* declare them: `manifest` wraps no API function, `theme build` batches several
|
|
@@ -194,6 +205,10 @@ function describeCommand(cmd, root, jsonSupported) {
|
|
|
194
205
|
}));
|
|
195
206
|
if (exitCodes.length > 0) entry.exitCodes = exitCodes;
|
|
196
207
|
|
|
208
|
+
// What the command does outside a project (spec AST-081 FR4). Every command
|
|
209
|
+
// declares it in its CommandDoc; a group that only holds subcommands does not.
|
|
210
|
+
if (docs?.doc.outsideProject) entry.outsideProject = docs.doc.outsideProject;
|
|
211
|
+
|
|
197
212
|
// Sort subcommands by name for a stable, agent-facing contract — the same
|
|
198
213
|
// guarantee the top-level command list makes. Otherwise Commander
|
|
199
214
|
// registration order leaks into the manifest and a pure reorder of
|
|
@@ -265,6 +280,7 @@ export function buildManifest(program, opts = {}) {
|
|
|
265
280
|
globalOptions: describeGlobalOptions(program),
|
|
266
281
|
commands,
|
|
267
282
|
jsonSupported: [...jsonSupported].sort(),
|
|
283
|
+
globalMode: GLOBAL_MODE,
|
|
268
284
|
// Flat index of every response `type` discriminator the CLI can emit,
|
|
269
285
|
// keyed by command — lets an agent know what to expect back per call.
|
|
270
286
|
responseTypes: Object.fromEntries(
|
|
@@ -307,3 +307,28 @@ describe('manifest: text projection', () => {
|
|
|
307
307
|
for (const key of textKeys) expect(jsonKeys).toContain(key);
|
|
308
308
|
});
|
|
309
309
|
});
|
|
310
|
+
|
|
311
|
+
describe('global mode is discoverable (spec:AST-017 FR14)', () => {
|
|
312
|
+
it('the manifest names what a run may do beyond its command, and the docs topic that explains it', () => {
|
|
313
|
+
expect(manifest.globalMode.docs).toBe('astryx docs global');
|
|
314
|
+
for (const word of ['hands the run', 'once a day', 'agent skill']) {
|
|
315
|
+
expect(manifest.globalMode.summary).toContain(word);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('--help carries one line pointing to the global mode docs', () => {
|
|
320
|
+
const help = program.helpInformation() + '';
|
|
321
|
+
let after = '';
|
|
322
|
+
program.emit('afterHelp', {
|
|
323
|
+
error: false,
|
|
324
|
+
write: (/** @type {string} */ s) => {
|
|
325
|
+
after += s;
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
const lines = `${help}${after}`
|
|
329
|
+
.split('\n')
|
|
330
|
+
.filter(line => line.startsWith('Global mode:'));
|
|
331
|
+
expect(lines).toHaveLength(1);
|
|
332
|
+
expect(lines[0]).toMatch(/docs global\.$/u);
|
|
333
|
+
});
|
|
334
|
+
});
|
|
@@ -20,6 +20,34 @@ export function discoverAgentDocs(targetDir: string): string[];
|
|
|
20
20
|
* @returns {boolean}
|
|
21
21
|
*/
|
|
22
22
|
export function isAstryxInitialized(targetDir?: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Does an agent working in `startDir` already have the Astryx prompt in reach?
|
|
25
|
+
*
|
|
26
|
+
* Coding agents read the agent docs between the repository root and the folder
|
|
27
|
+
* they work in. So inside a git repository, init's block in any folder from
|
|
28
|
+
* `startDir` up to the repository root counts: a workspace package of a
|
|
29
|
+
* monorepo initialized at its root is set up. Outside a repository only
|
|
30
|
+
* `startDir` itself is checked, as {@link isAstryxInitialized} does. Both the
|
|
31
|
+
* per-command nudge and the postinstall nudges ask this.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} [startDir=process.cwd()]
|
|
34
|
+
* @returns {boolean}
|
|
35
|
+
*/
|
|
36
|
+
export function isAstryxPromptInReach(startDir?: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The one-line next-step every setup layer prints. Kept here so layer 1
|
|
39
|
+
* (core), layer 2 (cli postinstall) and layer 3 (each command) can never word
|
|
40
|
+
* it differently. Each layer passes the stem from the CLI's picker when it can
|
|
41
|
+
* load it.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} [invocation] the CLI invocation stem, e.g. `pnpm exec astryx`
|
|
44
|
+
* @param {{before?: string | null}} [options] `before`: a command to run
|
|
45
|
+
* first, such as the one that adds the CLI to a project that has none
|
|
46
|
+
* @returns {string}
|
|
47
|
+
*/
|
|
48
|
+
export function setupNudge(invocation?: string, { before }?: {
|
|
49
|
+
before?: string | null;
|
|
50
|
+
}): string;
|
|
23
51
|
/**
|
|
24
52
|
* Pure decision: should a postinstall print the setup nudge? Shared by BOTH
|
|
25
53
|
* postinstall layers, so the matrix cannot drift between them, and unit-testable
|
|
@@ -61,11 +89,12 @@ export const AGENT_DOC_PATHS: string[];
|
|
|
61
89
|
*/
|
|
62
90
|
export const INIT_MARKERS: string[];
|
|
63
91
|
/**
|
|
64
|
-
* The
|
|
65
|
-
* (
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* the CLI is installed. Bare `npx astryx` would fetch an unrelated look-alike
|
|
92
|
+
* The invocation the setup nudge falls back to when the CLI's picker
|
|
93
|
+
* (`getCliInvocation`) cannot be loaded. Scoped package form
|
|
94
|
+
* (`@astryxdesign/cli`) — always resolves to us, even before the CLI is
|
|
95
|
+
* installed. npx with the unscoped name would fetch an unrelated look-alike
|
|
69
96
|
* package (see PR #4151).
|
|
70
97
|
*/
|
|
71
|
-
export const
|
|
98
|
+
export const SETUP_INVOCATION: "npx @astryxdesign/cli";
|
|
99
|
+
/** The nudge with the fallback invocation. */
|
|
100
|
+
export const SETUP_NUDGE: string;
|
|
@@ -97,15 +97,75 @@ export function isAstryxInitialized(targetDir = process.cwd()) {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
*
|
|
101
|
-
* (core) and layer 2 (cli) can never word it differently.
|
|
100
|
+
* Does an agent working in `startDir` already have the Astryx prompt in reach?
|
|
102
101
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
102
|
+
* Coding agents read the agent docs between the repository root and the folder
|
|
103
|
+
* they work in. So inside a git repository, init's block in any folder from
|
|
104
|
+
* `startDir` up to the repository root counts: a workspace package of a
|
|
105
|
+
* monorepo initialized at its root is set up. Outside a repository only
|
|
106
|
+
* `startDir` itself is checked, as {@link isAstryxInitialized} does. Both the
|
|
107
|
+
* per-command nudge and the postinstall nudges ask this.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} [startDir=process.cwd()]
|
|
110
|
+
* @returns {boolean}
|
|
111
|
+
*/
|
|
112
|
+
export function isAstryxPromptInReach(startDir = process.cwd()) {
|
|
113
|
+
const start = path.resolve(startDir);
|
|
114
|
+
const repositoryRoot = findRepositoryRoot(start);
|
|
115
|
+
if (!repositoryRoot) return isAstryxInitialized(start);
|
|
116
|
+
for (let dir = start; ; dir = path.dirname(dir)) {
|
|
117
|
+
if (isAstryxInitialized(dir)) return true;
|
|
118
|
+
if (dir === repositoryRoot) return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The nearest folder at or above `start` that holds `.git` (a folder, or the
|
|
124
|
+
* file a worktree uses), or null outside a repository.
|
|
125
|
+
* @param {string} start
|
|
126
|
+
* @returns {string | null}
|
|
127
|
+
*/
|
|
128
|
+
function findRepositoryRoot(start) {
|
|
129
|
+
for (let dir = start; ; ) {
|
|
130
|
+
if (fs.existsSync(path.join(dir, '.git'))) return dir;
|
|
131
|
+
const parent = path.dirname(dir);
|
|
132
|
+
if (parent === dir) return null;
|
|
133
|
+
dir = parent;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The invocation the setup nudge falls back to when the CLI's picker
|
|
139
|
+
* (`getCliInvocation`) cannot be loaded. Scoped package form
|
|
140
|
+
* (`@astryxdesign/cli`) — always resolves to us, even before the CLI is
|
|
141
|
+
* installed. npx with the unscoped name would fetch an unrelated look-alike
|
|
105
142
|
* package (see PR #4151).
|
|
106
143
|
*/
|
|
107
|
-
export const
|
|
108
|
-
|
|
144
|
+
export const SETUP_INVOCATION = 'npx @astryxdesign/cli';
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The one-line next-step every setup layer prints. Kept here so layer 1
|
|
148
|
+
* (core), layer 2 (cli postinstall) and layer 3 (each command) can never word
|
|
149
|
+
* it differently. Each layer passes the stem from the CLI's picker when it can
|
|
150
|
+
* load it.
|
|
151
|
+
*
|
|
152
|
+
* @param {string} [invocation] the CLI invocation stem, e.g. `pnpm exec astryx`
|
|
153
|
+
* @param {{before?: string | null}} [options] `before`: a command to run
|
|
154
|
+
* first, such as the one that adds the CLI to a project that has none
|
|
155
|
+
* @returns {string}
|
|
156
|
+
*/
|
|
157
|
+
export function setupNudge(
|
|
158
|
+
invocation = SETUP_INVOCATION,
|
|
159
|
+
{before = null} = {},
|
|
160
|
+
) {
|
|
161
|
+
const run = before
|
|
162
|
+
? `\`${before}\`, then \`${invocation} init\``
|
|
163
|
+
: `\`${invocation} init\``;
|
|
164
|
+
return `\nNext step: run ${run} to finish setup and install the Astryx agent prompt.\n\n`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** The nudge with the fallback invocation. */
|
|
168
|
+
export const SETUP_NUDGE = setupNudge();
|
|
109
169
|
|
|
110
170
|
/**
|
|
111
171
|
* Pure decision: should a postinstall print the setup nudge? Shared by BOTH
|
|
@@ -97,11 +97,11 @@ export function detectStylingSystem(targetDir: string): "stylex" | "tailwind" |
|
|
|
97
97
|
* among them. An agent cannot ask for a topic it was never told about, and
|
|
98
98
|
* `getting-started` is the one it should reach for first.
|
|
99
99
|
*
|
|
100
|
-
* @param {string} version
|
|
100
|
+
* @param {string | null} version the Core version
|
|
101
101
|
* @param {{coreDir?: string|null, invocation?: string, stylingSystem?: 'stylex'|'tailwind'|'css', zh?: boolean, lang?: string, topics?: string[], agentDocs?: Array<{package: string, append: readonly string[]}>}} [options]
|
|
102
102
|
* @returns {string}
|
|
103
103
|
*/
|
|
104
|
-
export function generateCompressedIndex(version: string, { coreDir, invocation, stylingSystem, topics, agentDocs, }?: {
|
|
104
|
+
export function generateCompressedIndex(version: string | null, { coreDir, invocation, stylingSystem, topics, agentDocs, }?: {
|
|
105
105
|
coreDir?: string | null;
|
|
106
106
|
invocation?: string;
|
|
107
107
|
stylingSystem?: "stylex" | "tailwind" | "css";
|
|
@@ -226,4 +226,5 @@ export function installAgentDocs(targetDir: string, { zh, lang, agent, paths, on
|
|
|
226
226
|
}): string[];
|
|
227
227
|
import { discoverAgentDocs } from './agent-doc-state.mjs';
|
|
228
228
|
import { isAstryxInitialized } from './agent-doc-state.mjs';
|
|
229
|
-
|
|
229
|
+
import { isAstryxPromptInReach } from './agent-doc-state.mjs';
|
|
230
|
+
export { discoverAgentDocs, isAstryxInitialized, isAstryxPromptInReach };
|
|
@@ -42,15 +42,17 @@ import {
|
|
|
42
42
|
LEGACY_MARKER_END,
|
|
43
43
|
discoverAgentDocs,
|
|
44
44
|
isAstryxInitialized,
|
|
45
|
+
isAstryxPromptInReach,
|
|
45
46
|
} from './agent-doc-state.mjs';
|
|
46
47
|
|
|
47
48
|
// The agent-doc locations, markers, and the setup-state predicates
|
|
48
|
-
// (discoverAgentDocs, isAstryxInitialized) are the ONE
|
|
49
|
-
// live in the dependency-free leaf
|
|
50
|
-
// nudge (enforcement layer 2) can load
|
|
51
|
-
//
|
|
52
|
-
// clients/cli/index.mjs, tests)
|
|
53
|
-
|
|
49
|
+
// (discoverAgentDocs, isAstryxInitialized, isAstryxPromptInReach) are the ONE
|
|
50
|
+
// canonical contract. They live in the dependency-free leaf
|
|
51
|
+
// ./agent-doc-state.mjs so the postinstall nudge (enforcement layer 2) can load
|
|
52
|
+
// them safely at install time. Re-exported here so existing importers
|
|
53
|
+
// (init/upgrade commands, the layer-3 nudge in clients/cli/index.mjs, tests)
|
|
54
|
+
// keep their `from './agent-docs.mjs'` paths.
|
|
55
|
+
export {discoverAgentDocs, isAstryxInitialized, isAstryxPromptInReach};
|
|
54
56
|
|
|
55
57
|
const MAX_PROJECT_AGENT_DOC_LINES = 32;
|
|
56
58
|
const MANAGED_MARKER_TEXT = /(?:ASTRYX|XDS):(START|END)/u;
|
|
@@ -377,7 +379,7 @@ export function detectStylingSystem(targetDir) {
|
|
|
377
379
|
* among them. An agent cannot ask for a topic it was never told about, and
|
|
378
380
|
* `getting-started` is the one it should reach for first.
|
|
379
381
|
*
|
|
380
|
-
* @param {string} version
|
|
382
|
+
* @param {string | null} version the Core version
|
|
381
383
|
* @param {{coreDir?: string|null, invocation?: string, stylingSystem?: 'stylex'|'tailwind'|'css', zh?: boolean, lang?: string, topics?: string[], agentDocs?: Array<{package: string, append: readonly string[]}>}} [options]
|
|
382
384
|
* @returns {string}
|
|
383
385
|
*/
|
|
@@ -418,9 +420,9 @@ export function generateCompressedIndex(
|
|
|
418
420
|
// Best-effort: component count is cosmetic; fall back to the default.
|
|
419
421
|
}
|
|
420
422
|
}
|
|
421
|
-
|
|
422
|
-
// Header — state the CLI prefix once; commands below are shown as `astryx <cmd>`.
|
|
423
423
|
lines.push(`Astryx v${version} · ${componentCount} components`);
|
|
424
|
+
|
|
425
|
+
// State the CLI prefix once; commands below are shown as `astryx <cmd>`.
|
|
424
426
|
lines.push(
|
|
425
427
|
`CLI: run every command as \`${run} <cmd>\` (shown below as \`astryx ...\`).`,
|
|
426
428
|
);
|