@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/api/init/init.type.d.mts
CHANGED
|
@@ -42,7 +42,7 @@ export type InitRunData = {
|
|
|
42
42
|
*/
|
|
43
43
|
templatePath: string | null;
|
|
44
44
|
/**
|
|
45
|
-
* Whether the getting-started "Next steps" were emitted (default mode).
|
|
45
|
+
* Whether the getting-started "Next steps" were emitted (default mode inside a project; false outside one).
|
|
46
46
|
*/
|
|
47
47
|
nextSteps: boolean;
|
|
48
48
|
};
|
|
@@ -59,6 +59,47 @@ export type InitRemoveResponse = {
|
|
|
59
59
|
removed: boolean;
|
|
60
60
|
};
|
|
61
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* What `init --user` did with one file of the computer-level agent text.
|
|
64
|
+
* `written`: created or refreshed. `unchanged`: already this release's text.
|
|
65
|
+
* `removed`: deleted (with `--remove-agents`). `absent`: nothing to remove.
|
|
66
|
+
* `kept`: a file left as it is, because a person edited it or Astryx did not
|
|
67
|
+
* write it (see `reason`).
|
|
68
|
+
*/
|
|
69
|
+
export type InitUserAction = "written" | "linked" | "unchanged" | "removed" | "absent" | "kept";
|
|
70
|
+
export type InitUserFile = {
|
|
71
|
+
/**
|
|
72
|
+
* Absolute path in the home folder: the skill file,
|
|
73
|
+
* or a link to its folder.
|
|
74
|
+
*/
|
|
75
|
+
path: string;
|
|
76
|
+
action: InitUserAction;
|
|
77
|
+
/**
|
|
78
|
+
* Only on `kept`: `edited`, the
|
|
79
|
+
* text no longer matches the hash Astryx recorded in it; `not-astryx`, it
|
|
80
|
+
* has no Astryx markers or is a symlink, or a link target holds something
|
|
81
|
+
* Astryx did not create.
|
|
82
|
+
*/
|
|
83
|
+
reason?: "edited" | "not-astryx" | undefined;
|
|
84
|
+
};
|
|
85
|
+
export type InitUserData = {
|
|
86
|
+
/**
|
|
87
|
+
* One row per path acted on: `~/.agents/skills/astryx/SKILL.md` first, then each link to its folder: `~/.claude/skills/astryx` always, and another agent's skills folder when that agent's folder exists (`linked`, or `unchanged` when the link is already there). Removal removes the file and the links Astryx made.
|
|
88
|
+
*/
|
|
89
|
+
files: InitUserFile[];
|
|
90
|
+
/**
|
|
91
|
+
* The command the text tells agents to run: `astryx`, or the host's command when a host started the run.
|
|
92
|
+
*/
|
|
93
|
+
command: string;
|
|
94
|
+
/**
|
|
95
|
+
* Non-fatal notes, such as no `astryx` on the computer that runs the Astryx CLI.
|
|
96
|
+
*/
|
|
97
|
+
warnings: string[];
|
|
98
|
+
};
|
|
99
|
+
export type InitUserResponse = {
|
|
100
|
+
type: "init.user";
|
|
101
|
+
data: InitUserData;
|
|
102
|
+
};
|
|
62
103
|
/**
|
|
63
104
|
* Options for `init()`.
|
|
64
105
|
*/
|
|
@@ -72,11 +113,15 @@ export type InitOptions = {
|
|
|
72
113
|
*/
|
|
73
114
|
all?: boolean | undefined;
|
|
74
115
|
/**
|
|
75
|
-
* Remove the managed agent-docs block instead of installing.
|
|
116
|
+
* Remove the managed agent-docs block instead of installing; with `user`, remove the computer-level agent text.
|
|
76
117
|
*/
|
|
77
118
|
removeAgents?: boolean | undefined;
|
|
78
119
|
/**
|
|
79
|
-
*
|
|
120
|
+
* Write the computer-level agent text (`~/.agents/skills/astryx/SKILL.md`, linked into `~/.claude/skills` and the skill folders of other installed tools, with a copy for Continue) instead of setting up the folder.
|
|
121
|
+
*/
|
|
122
|
+
user?: boolean | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* Agent preset: claude, cursor, codex, hermes, muse, all. Refused with `user`.
|
|
80
125
|
*/
|
|
81
126
|
agent?: string | undefined;
|
|
82
127
|
/**
|
package/api/init/init.type.mjs
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* @property {string | null} themeTemplatePath Relative output path when `themeTemplate === 'created'`.
|
|
18
18
|
* @property {'workflow' | 'created' | 'skipped' | null} template Template outcome (`workflow` is the CLI default; `created`/`skipped` are programmatic).
|
|
19
19
|
* @property {string | null} templatePath Relative output path when `template === 'created'`.
|
|
20
|
-
* @property {boolean} nextSteps Whether the getting-started "Next steps" were emitted (default mode).
|
|
20
|
+
* @property {boolean} nextSteps Whether the getting-started "Next steps" were emitted (default mode inside a project; false outside one).
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -32,13 +32,47 @@
|
|
|
32
32
|
* @property {{removed: boolean}} data False when no managed agent-docs block was found, so nothing was removed.
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* What `init --user` did with one file of the computer-level agent text.
|
|
37
|
+
* `written`: created or refreshed. `unchanged`: already this release's text.
|
|
38
|
+
* `removed`: deleted (with `--remove-agents`). `absent`: nothing to remove.
|
|
39
|
+
* `kept`: a file left as it is, because a person edited it or Astryx did not
|
|
40
|
+
* write it (see `reason`).
|
|
41
|
+
* @typedef {'written' | 'linked' | 'unchanged' | 'removed' | 'absent' | 'kept'} InitUserAction
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {object} InitUserFile
|
|
46
|
+
* @property {string} path Absolute path in the home folder: the skill file,
|
|
47
|
+
* or a link to its folder.
|
|
48
|
+
* @property {InitUserAction} action
|
|
49
|
+
* @property {'edited' | 'not-astryx'} [reason] Only on `kept`: `edited`, the
|
|
50
|
+
* text no longer matches the hash Astryx recorded in it; `not-astryx`, it
|
|
51
|
+
* has no Astryx markers or is a symlink, or a link target holds something
|
|
52
|
+
* Astryx did not create.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @typedef {object} InitUserData
|
|
57
|
+
* @property {InitUserFile[]} files One row per path acted on: `~/.agents/skills/astryx/SKILL.md` first, then each link to its folder: `~/.claude/skills/astryx` always, and another agent's skills folder when that agent's folder exists (`linked`, or `unchanged` when the link is already there). Removal removes the file and the links Astryx made.
|
|
58
|
+
* @property {string} command The command the text tells agents to run: `astryx`, or the host's command when a host started the run.
|
|
59
|
+
* @property {string[]} warnings Non-fatal notes, such as no `astryx` on the computer that runs the Astryx CLI.
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @typedef {object} InitUserResponse
|
|
64
|
+
* @property {'init.user'} type
|
|
65
|
+
* @property {InitUserData} data
|
|
66
|
+
*/
|
|
67
|
+
|
|
35
68
|
/**
|
|
36
69
|
* Options for `init()`.
|
|
37
70
|
* @typedef {object} InitOptions
|
|
38
71
|
* @property {string} [features] Comma-separated features to install (agents, theme, template).
|
|
39
72
|
* @property {boolean} [all] Install all features.
|
|
40
|
-
* @property {boolean} [removeAgents] Remove the managed agent-docs block instead of installing.
|
|
41
|
-
* @property {
|
|
73
|
+
* @property {boolean} [removeAgents] Remove the managed agent-docs block instead of installing; with `user`, remove the computer-level agent text.
|
|
74
|
+
* @property {boolean} [user] Write the computer-level agent text (`~/.agents/skills/astryx/SKILL.md`, linked into `~/.claude/skills` and the skill folders of other installed tools, with a copy for Continue) instead of setting up the folder.
|
|
75
|
+
* @property {string} [agent] Agent preset: claude, cursor, codex, hermes, muse, all. Refused with `user`.
|
|
42
76
|
* @property {string | string[]} [agentDocsPath] Explicit agent-docs file path(s).
|
|
43
77
|
* @property {string} [templateName] Scaffold a named page template (programmatic only; the CLI never sets it).
|
|
44
78
|
*/
|
package/api/init/run/run.d.mts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* installed built themes and imports their production and font stylesheets. The
|
|
9
9
|
* app imports that module once and passes its default to <Theme>.
|
|
10
10
|
*
|
|
11
|
-
* @param {string} invocation install-aware CLI invocation stem (e.g. `
|
|
11
|
+
* @param {string} invocation install-aware CLI invocation stem (e.g. `pnpm exec astryx`, `yarn astryx`, or `npx @astryxdesign/cli` for one-off runs)
|
|
12
12
|
* @returns {string[]} ordered list of human-facing lines
|
|
13
13
|
*/
|
|
14
14
|
export function getNextSteps(invocation: string): string[];
|
package/api/init/run/run.mjs
CHANGED
|
@@ -19,6 +19,7 @@ import * as fs from 'node:fs';
|
|
|
19
19
|
import {CLI_ROOT} from '../../../foundation/fs/paths.mjs';
|
|
20
20
|
import {PathSafetyError, assertWithin} from '../../../foundation/fs/path-safety.mjs';
|
|
21
21
|
import {getCliInvocation} from '../../../foundation/env/package-manager.mjs';
|
|
22
|
+
import {isOutsideProject} from '../../../foundation/env/project-scope.mjs';
|
|
22
23
|
import {
|
|
23
24
|
installAgentDocs,
|
|
24
25
|
renderAgentDocsBlock,
|
|
@@ -39,7 +40,7 @@ const VALID_AGENTS = ['claude', 'cursor', 'codex', 'hermes', 'muse', 'all'];
|
|
|
39
40
|
* installed built themes and imports their production and font stylesheets. The
|
|
40
41
|
* app imports that module once and passes its default to <Theme>.
|
|
41
42
|
*
|
|
42
|
-
* @param {string} invocation install-aware CLI invocation stem (e.g. `
|
|
43
|
+
* @param {string} invocation install-aware CLI invocation stem (e.g. `pnpm exec astryx`, `yarn astryx`, or `npx @astryxdesign/cli` for one-off runs)
|
|
43
44
|
* @returns {string[]} ordered list of human-facing lines
|
|
44
45
|
*/
|
|
45
46
|
export function getNextSteps(invocation) {
|
|
@@ -140,8 +141,11 @@ function applyTheme(cwd, invocation, data) {
|
|
|
140
141
|
data.themeTemplate = 'failed';
|
|
141
142
|
logger.error('Could not write the theme template.');
|
|
142
143
|
}
|
|
144
|
+
// Outside a project there is no app to add a theme to (spec AST-081 FR3).
|
|
143
145
|
logger.log(
|
|
144
|
-
|
|
146
|
+
isOutsideProject(cwd)
|
|
147
|
+
? ` Edit the blank template for a new theme, or run \`${invocation} theme eject <slug>\` to start from the source of a built theme (\`${invocation} theme list\` to browse).`
|
|
148
|
+
: ` Edit the blank template for a new theme, or run \`${invocation} theme add <slug>\` to import an installed built theme (\`${invocation} theme list\` to browse). Extend an imported theme for ordinary customization; use \`${invocation} theme eject <slug>\` only to fork source.`,
|
|
145
149
|
);
|
|
146
150
|
}
|
|
147
151
|
|
|
@@ -276,7 +280,10 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
276
280
|
}
|
|
277
281
|
|
|
278
282
|
// No flags: TTY-free default — install the AI agent cheat sheet with NO
|
|
279
|
-
// prompts, then print the getting-started guidance.
|
|
283
|
+
// prompts, then print the getting-started guidance. Outside a project the
|
|
284
|
+
// steps would set up a project the folder does not have, so they are left
|
|
285
|
+
// out (spec AST-081 FR3).
|
|
286
|
+
const outside = isOutsideProject(cwd);
|
|
280
287
|
/** @type {import('../init.type.mjs').InitRunData} */
|
|
281
288
|
const data = {
|
|
282
289
|
mode: 'default',
|
|
@@ -288,13 +295,17 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
288
295
|
themeTemplatePath: null,
|
|
289
296
|
template: null,
|
|
290
297
|
templatePath: null,
|
|
291
|
-
nextSteps:
|
|
298
|
+
nextSteps: !outside,
|
|
292
299
|
};
|
|
293
300
|
await applyAgents(cwd, options, invocation, data);
|
|
294
301
|
logger.log('');
|
|
295
302
|
logger.log(
|
|
296
303
|
` Tip: \`${invocation} init --all\` also points you to the theme and page-building workflows.`,
|
|
297
304
|
);
|
|
305
|
+
if (outside) {
|
|
306
|
+
logger.log('');
|
|
307
|
+
return {type: 'init.run', data};
|
|
308
|
+
}
|
|
298
309
|
for (const line of getNextSteps(invocation)) logger.log(line);
|
|
299
310
|
return {type: 'init.run', data};
|
|
300
311
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
|
|
2
|
+
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Write or remove the computer-level agent text and return an `init.user`
|
|
6
|
+
* receipt. Progress is emitted through the shared `logger` (silent by
|
|
7
|
+
* default); warnings go to its warn channel.
|
|
8
|
+
*
|
|
9
|
+
* @param {{remove?: boolean}} [options]
|
|
10
|
+
* @returns {Promise<import('../init.type.mjs').InitUserResponse>}
|
|
11
|
+
*/
|
|
12
|
+
export function user({ remove }?: {
|
|
13
|
+
remove?: boolean;
|
|
14
|
+
}): Promise<import("../init.type.mjs").InitUserResponse>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file init.user leaf — the `--user` path behind `astryx init`.
|
|
5
|
+
*
|
|
6
|
+
* `user(options)` writes, refreshes, or (with `remove`) removes the
|
|
7
|
+
* computer-level agent text: one skill file in the home folder, linked into
|
|
8
|
+
* the skill folders agents read (spec AST-081 FR7, FR8). It records the
|
|
9
|
+
* setting and the links it made in the settings file, so the global copy,
|
|
10
|
+
* which keeps the text current in the background, does the same, or, after
|
|
11
|
+
* `remove`, writes nothing. The adapter does every file access. It works in any
|
|
12
|
+
* folder and never touches a project's agent docs. A file without the Astryx
|
|
13
|
+
* markers, one a person edited, or a symlinked one is kept as it is. When no
|
|
14
|
+
* `astryx` on the computer's search path runs the Astryx CLI, the text is
|
|
15
|
+
* still written and the receipt warns that the CLI should be installed for
|
|
16
|
+
* the computer.
|
|
17
|
+
*
|
|
18
|
+
* @input `remove`; the home folder, search path, and settings of
|
|
19
|
+
* the computer
|
|
20
|
+
* @output an `init.user` receipt
|
|
21
|
+
* @position packages/cli/api/init — dispatched by init.mjs
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
COMPUTER_COMMAND,
|
|
26
|
+
COMPUTER_INSTALL_STEP,
|
|
27
|
+
applyComputerAgentText,
|
|
28
|
+
displayHomePath,
|
|
29
|
+
} from '../_adapter.mjs';
|
|
30
|
+
import {logger} from '../../logger.mjs';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} file
|
|
34
|
+
* @param {string} home
|
|
35
|
+
* @returns {string}
|
|
36
|
+
*/
|
|
37
|
+
const display = (file, home) => displayHomePath(file, home);
|
|
38
|
+
|
|
39
|
+
/** @type {Record<import('../init.type.mjs').InitUserAction, string>} */
|
|
40
|
+
const ACTION_LINES = {
|
|
41
|
+
written: '[ok] Wrote',
|
|
42
|
+
linked: '[ok] Linked',
|
|
43
|
+
unchanged: '[ok] Already current:',
|
|
44
|
+
removed: '[ok] Removed',
|
|
45
|
+
absent: '[ok] Nothing to remove:',
|
|
46
|
+
kept: '[skip] Kept',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** @type {Record<'edited' | 'not-astryx', string>} */
|
|
50
|
+
const KEPT_REASONS = {
|
|
51
|
+
edited: '(edited since Astryx wrote it; delete it to get the current text):',
|
|
52
|
+
'not-astryx': '(not created by Astryx):',
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Write or remove the computer-level agent text and return an `init.user`
|
|
57
|
+
* receipt. Progress is emitted through the shared `logger` (silent by
|
|
58
|
+
* default); warnings go to its warn channel.
|
|
59
|
+
*
|
|
60
|
+
* @param {{remove?: boolean}} [options]
|
|
61
|
+
* @returns {Promise<import('../init.type.mjs').InitUserResponse>}
|
|
62
|
+
*/
|
|
63
|
+
export async function user({remove = false} = {}) {
|
|
64
|
+
const {home, command, files, cliOnSearchPath} = applyComputerAgentText({
|
|
65
|
+
remove,
|
|
66
|
+
});
|
|
67
|
+
/** @type {string[]} */
|
|
68
|
+
const warnings = [];
|
|
69
|
+
// A host's door is its own command; only the plain `astryx` needs a copy of
|
|
70
|
+
// the CLI installed for the computer.
|
|
71
|
+
if (!remove && command === COMPUTER_COMMAND && !cliOnSearchPath) {
|
|
72
|
+
warnings.push(
|
|
73
|
+
`No \`${COMPUTER_COMMAND}\` command on this computer runs the Astryx CLI, so agents cannot run the commands this text names. Install the CLI for the computer: ${COMPUTER_INSTALL_STEP}`,
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
const reason = file.reason ? ` ${KEPT_REASONS[file.reason]}` : '';
|
|
78
|
+
logger.log(
|
|
79
|
+
`${ACTION_LINES[file.action]}${reason || (file.action === 'kept' ? ':' : '')} ${display(file.path, home)}`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
for (const warning of warnings) logger.warn(`[warn] ${warning}`);
|
|
83
|
+
return {
|
|
84
|
+
type: 'init.user',
|
|
85
|
+
data: {files, command, warnings},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file `init({user})` and `astryx init --user`: the `init.user` receipt, the
|
|
5
|
+
* install warning, the refused combinations, and that it touches nothing in
|
|
6
|
+
* the folder it runs in. Every test uses a temporary home folder and search
|
|
7
|
+
* path.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as fs from 'node:fs';
|
|
11
|
+
import * as os from 'node:os';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest';
|
|
14
|
+
import {init} from '../init.mjs';
|
|
15
|
+
import {user} from './user.mjs';
|
|
16
|
+
import {runWithCliDoor} from '../../../foundation/env/cli-command.mjs';
|
|
17
|
+
import {renderComputerAgentText} from '../../../foundation/agent-docs/computer-agent-text.mjs';
|
|
18
|
+
import {runCli} from '../../../test-utils/run-cli.mjs';
|
|
19
|
+
import {settingsFile} from '../../../foundation/env/user-settings.mjs';
|
|
20
|
+
import {readGlobalState} from '../../../foundation/release/global-state.mjs';
|
|
21
|
+
import {cliVersion} from '../../../foundation/release/run-context.mjs';
|
|
22
|
+
|
|
23
|
+
/** @type {string[]} */
|
|
24
|
+
const dirs = [];
|
|
25
|
+
/** @param {string} label */
|
|
26
|
+
function tmp(label) {
|
|
27
|
+
const dir = fs.mkdtempSync(
|
|
28
|
+
path.join(os.tmpdir(), `astryx-init-user-${label}-`),
|
|
29
|
+
);
|
|
30
|
+
dirs.push(dir);
|
|
31
|
+
return dir;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let home = '';
|
|
35
|
+
let emptyPath = '';
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
home = tmp('home');
|
|
38
|
+
emptyPath = tmp('path');
|
|
39
|
+
vi.stubEnv('HOME', home);
|
|
40
|
+
vi.stubEnv('USERPROFILE', home);
|
|
41
|
+
vi.stubEnv('PATH', emptyPath);
|
|
42
|
+
// The settings file and the cache live under this home folder too.
|
|
43
|
+
vi.stubEnv('XDG_CONFIG_HOME', path.join(home, '.config'));
|
|
44
|
+
vi.stubEnv('XDG_CACHE_HOME', path.join(home, '.cache'));
|
|
45
|
+
vi.stubEnv('APPDATA', path.join(home, 'AppData', 'Roaming'));
|
|
46
|
+
vi.stubEnv('LOCALAPPDATA', path.join(home, 'AppData', 'Local'));
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/** The settings file under the temporary home folder. */
|
|
50
|
+
const settings = () => {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(fs.readFileSync(settingsFile(), 'utf8'));
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
afterEach(() => {
|
|
58
|
+
vi.unstubAllEnvs();
|
|
59
|
+
while (dirs.length) {
|
|
60
|
+
fs.rmSync(/** @type {string} */ (dirs.pop()), {
|
|
61
|
+
recursive: true,
|
|
62
|
+
force: true,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const FILE = path.join('.agents', 'skills', 'astryx', 'SKILL.md');
|
|
68
|
+
const CLAUDE = path.join('.claude', 'skills', 'astryx');
|
|
69
|
+
|
|
70
|
+
/** Put a linked Astryx CLI first on the search path. */
|
|
71
|
+
function installCliOnPath() {
|
|
72
|
+
const prefix = tmp('prefix');
|
|
73
|
+
const pkg = path.join(prefix, 'lib', 'node_modules', '@astryxdesign', 'cli');
|
|
74
|
+
fs.mkdirSync(pkg, {recursive: true});
|
|
75
|
+
fs.writeFileSync(
|
|
76
|
+
path.join(pkg, 'package.json'),
|
|
77
|
+
'{"name":"@astryxdesign/cli"}',
|
|
78
|
+
);
|
|
79
|
+
fs.writeFileSync(path.join(pkg, 'bin.mjs'), '#!/usr/bin/env node\n');
|
|
80
|
+
fs.chmodSync(path.join(pkg, 'bin.mjs'), 0o755);
|
|
81
|
+
fs.mkdirSync(path.join(prefix, 'bin'));
|
|
82
|
+
fs.symlinkSync(path.join(pkg, 'bin.mjs'), path.join(prefix, 'bin', 'astryx'));
|
|
83
|
+
vi.stubEnv('PATH', path.join(prefix, 'bin'));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
describe('init({user: true})', () => {
|
|
87
|
+
it('writes the file, links Claude Code to it, and returns the init.user receipt, warning when no astryx runs the CLI', async () => {
|
|
88
|
+
const r = await init({user: true}, {cwd: tmp('cwd')});
|
|
89
|
+
expect(r.type).toBe('init.user');
|
|
90
|
+
if (r.type !== 'init.user') return;
|
|
91
|
+
expect(r.data.files).toEqual([
|
|
92
|
+
{path: path.join(home, FILE), action: 'written'},
|
|
93
|
+
{path: path.join(home, CLAUDE), action: 'linked'},
|
|
94
|
+
]);
|
|
95
|
+
expect(r.data.command).toBe('astryx');
|
|
96
|
+
expect(r.data.warnings).toHaveLength(1);
|
|
97
|
+
expect(r.data.warnings[0]).toContain('npm i -g @astryxdesign/cli');
|
|
98
|
+
expect(fs.readFileSync(path.join(home, FILE), 'utf8')).toBe(
|
|
99
|
+
renderComputerAgentText({command: 'astryx'}),
|
|
100
|
+
);
|
|
101
|
+
expect(fs.readFileSync(path.join(home, CLAUDE, 'SKILL.md'), 'utf8')).toBe(
|
|
102
|
+
renderComputerAgentText({command: 'astryx'}),
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it.skipIf(process.platform === 'win32')(
|
|
107
|
+
'does not warn when the astryx on the search path is the Astryx CLI',
|
|
108
|
+
async () => {
|
|
109
|
+
installCliOnPath();
|
|
110
|
+
const r = await user();
|
|
111
|
+
expect(r.data.warnings).toEqual([]);
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
it("names the host's door and does not ask for a global install", async () => {
|
|
116
|
+
const r = await runWithCliDoor('acme astryx', () => user());
|
|
117
|
+
expect(r.data.command).toBe('acme astryx');
|
|
118
|
+
expect(r.data.warnings).toEqual([]);
|
|
119
|
+
expect(fs.readFileSync(path.join(home, FILE), 'utf8')).toContain(
|
|
120
|
+
"`acme astryx search '<what you need>'`",
|
|
121
|
+
);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('works inside a project and writes nothing in it', async () => {
|
|
125
|
+
const dir = tmp('project');
|
|
126
|
+
fs.writeFileSync(
|
|
127
|
+
path.join(dir, 'package.json'),
|
|
128
|
+
'{"name":"app","dependencies":{"@astryxdesign/core":"*"}}',
|
|
129
|
+
);
|
|
130
|
+
const before = fs.readdirSync(dir).sort();
|
|
131
|
+
const r = await init({user: true}, {cwd: dir});
|
|
132
|
+
expect(r.type).toBe('init.user');
|
|
133
|
+
expect(fs.readdirSync(dir).sort()).toEqual(before);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('records the links it made, and the release that wrote the text', async () => {
|
|
137
|
+
await init({user: true});
|
|
138
|
+
expect(settings()).toEqual({
|
|
139
|
+
computerAgentText: {install: true, links: [path.join(home, CLAUDE)]},
|
|
140
|
+
});
|
|
141
|
+
expect(readGlobalState().agentText).toEqual({writtenBy: cliVersion()});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('keeps every other setting when it records the choice', async () => {
|
|
145
|
+
fs.mkdirSync(path.dirname(settingsFile()), {recursive: true});
|
|
146
|
+
fs.writeFileSync(settingsFile(), '{"other": 1}');
|
|
147
|
+
await init({user: true, removeAgents: true});
|
|
148
|
+
expect(settings()).toEqual({
|
|
149
|
+
other: 1,
|
|
150
|
+
computerAgentText: {install: false, links: []},
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('with removeAgents removes the file and the links it made, and records that the text is not wanted', async () => {
|
|
155
|
+
await init({user: true});
|
|
156
|
+
const r = await init({user: true, removeAgents: true});
|
|
157
|
+
expect(r.type).toBe('init.user');
|
|
158
|
+
if (r.type !== 'init.user') return;
|
|
159
|
+
expect(r.data.files).toEqual([
|
|
160
|
+
{path: path.join(home, FILE), action: 'removed'},
|
|
161
|
+
{path: path.join(home, CLAUDE), action: 'removed'},
|
|
162
|
+
]);
|
|
163
|
+
expect(r.data.warnings).toEqual([]);
|
|
164
|
+
expect(fs.existsSync(path.join(home, FILE))).toBe(false);
|
|
165
|
+
expect(fs.existsSync(path.join(home, CLAUDE))).toBe(false);
|
|
166
|
+
expect(settings()).toEqual({
|
|
167
|
+
computerAgentText: {install: false, links: []},
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it.each([
|
|
172
|
+
[{features: 'agents'}, '--features'],
|
|
173
|
+
[{all: true}, '--all'],
|
|
174
|
+
[{agentDocsPath: 'X.md'}, '--agent-docs-path'],
|
|
175
|
+
[{agent: 'claude'}, '--agent'],
|
|
176
|
+
[{removeAgents: true, agent: 'claude'}, '--agent'],
|
|
177
|
+
])(
|
|
178
|
+
'refuses %o with ERR_INVALID_ARGUMENT and writes nothing',
|
|
179
|
+
async (extra, flag) => {
|
|
180
|
+
await expect(init({user: true, ...extra})).rejects.toMatchObject({
|
|
181
|
+
code: 'ERR_INVALID_ARGUMENT',
|
|
182
|
+
message: expect.stringContaining(flag),
|
|
183
|
+
});
|
|
184
|
+
expect(fs.existsSync(path.join(home, '.agents'))).toBe(false);
|
|
185
|
+
expect(fs.existsSync(path.join(home, '.claude'))).toBe(false);
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('astryx init --user', () => {
|
|
191
|
+
it('prints the file, the link, and the install warning in text mode', async () => {
|
|
192
|
+
const r = await runCli(['init', '--user'], tmp('cwd'));
|
|
193
|
+
expect(r.status).toBe(0);
|
|
194
|
+
expect(r.stdout).toContain(`Wrote ~${path.sep}${FILE}`);
|
|
195
|
+
expect(r.stdout).toContain(`Linked ~${path.sep}${CLAUDE}`);
|
|
196
|
+
expect(r.stderr).toContain('npm i -g @astryxdesign/cli');
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('emits the init.user envelope under --json', async () => {
|
|
200
|
+
const r = await runCli(['--json', 'init', '--user'], tmp('cwd'));
|
|
201
|
+
expect(r.status).toBe(0);
|
|
202
|
+
const env = JSON.parse(r.stdout);
|
|
203
|
+
expect(env.type).toBe('init.user');
|
|
204
|
+
expect(
|
|
205
|
+
env.data.files.map((/** @type {{action: string}} */ f) => f.action),
|
|
206
|
+
).toEqual(['written', 'linked']);
|
|
207
|
+
expect(env.data.command).toBe('astryx');
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('names a file a person edited as kept, and why', async () => {
|
|
211
|
+
await runCli(['init', '--user'], tmp('cwd'));
|
|
212
|
+
const file = path.join(home, FILE);
|
|
213
|
+
fs.appendFileSync(file, 'my note\n');
|
|
214
|
+
const r = await runCli(['init', '--user'], tmp('cwd'));
|
|
215
|
+
expect(r.status).toBe(0);
|
|
216
|
+
expect(r.stdout).toContain(
|
|
217
|
+
`Kept (edited since Astryx wrote it; delete it to get the current text): ~${path.sep}${FILE}`,
|
|
218
|
+
);
|
|
219
|
+
expect(fs.readFileSync(file, 'utf8')).toMatch(/my note\n$/u);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('exits 1 with ERR_INVALID_ARGUMENT when combined with --all or --agent', async () => {
|
|
223
|
+
for (const extra of [['--all'], ['--agent', 'claude']]) {
|
|
224
|
+
const r = await runCli(
|
|
225
|
+
['--json', 'init', '--user', ...extra],
|
|
226
|
+
tmp('cwd'),
|
|
227
|
+
);
|
|
228
|
+
expect(r.status).toBe(1);
|
|
229
|
+
expect(JSON.parse(r.stdout).code).toBe('ERR_INVALID_ARGUMENT');
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
});
|
|
@@ -10,3 +10,36 @@
|
|
|
10
10
|
* @returns {Promise<import('../../foundation/discovery/prop-drift.mjs').PropDriftReport>}
|
|
11
11
|
*/
|
|
12
12
|
export function integrationPropDrift(integration: any, cwd: string): Promise<import("../../foundation/discovery/prop-drift.mjs").PropDriftReport>;
|
|
13
|
+
/**
|
|
14
|
+
* The passages two of a package's topics, or one of them and a Core topic,
|
|
15
|
+
* repeat word for word (architecture:cli-surface DEC-8). Reads the package's
|
|
16
|
+
* topics and Core's guides.
|
|
17
|
+
*
|
|
18
|
+
* @param {Parameters<typeof findCopiedPassages>[0]} discovered the package's
|
|
19
|
+
* docs, as discoverIntegrationDocs returns them
|
|
20
|
+
*/
|
|
21
|
+
export function integrationCopiedPassages(discovered: Parameters<typeof findCopiedPassages>[0]): Promise<import("./authoring-checks.type.mjs").CopiedPassage[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Padding phrases and low-density topics in a package's prose
|
|
24
|
+
* (architecture:cli-surface DEC-8). Reads the package's topics, and Core's
|
|
25
|
+
* guides for the density median a finding names.
|
|
26
|
+
*
|
|
27
|
+
* @param {Parameters<typeof findFluff>[0]} discovered the package's docs, as
|
|
28
|
+
* discoverIntegrationDocs returns them
|
|
29
|
+
*/
|
|
30
|
+
export function integrationFluff(discovered: Parameters<typeof findFluff>[0]): Promise<import("./authoring-checks.type.mjs").DocFluff[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Code spans in a package's prose that write `astryx docs <name>` for a doc
|
|
33
|
+
* that exists, where `{@link generic:<name>}` would be checked
|
|
34
|
+
* (architecture:cli-surface DEC-8). Reads the package's topics, its own
|
|
35
|
+
* component docs, and the names of Core's docs.
|
|
36
|
+
*
|
|
37
|
+
* @param {Parameters<typeof findStrayPointers>[0]} discovered the package's
|
|
38
|
+
* docs, as discoverIntegrationDocs returns them
|
|
39
|
+
* @param {any} [integration] the loaded integration, whose component docs are
|
|
40
|
+
* read too
|
|
41
|
+
*/
|
|
42
|
+
export function integrationStrayPointers(discovered: Parameters<typeof findStrayPointers>[0], integration?: any): Promise<import("./authoring-checks.type.mjs").StrayPointer[]>;
|
|
43
|
+
import { findCopiedPassages } from '../../foundation/discovery/copied-passages.mjs';
|
|
44
|
+
import { findFluff } from '../../foundation/discovery/doc-fluff.mjs';
|
|
45
|
+
import { findStrayPointers } from '../../foundation/discovery/stray-pointers.mjs';
|
|
@@ -15,6 +15,9 @@ import {
|
|
|
15
15
|
integrationSourceForDoc,
|
|
16
16
|
} from '../../foundation/discovery/component-discovery.mjs';
|
|
17
17
|
import {comparePropDocs} from '../../foundation/discovery/prop-drift.mjs';
|
|
18
|
+
import {findCopiedPassages} from '../../foundation/discovery/copied-passages.mjs';
|
|
19
|
+
import {findFluff} from '../../foundation/discovery/doc-fluff.mjs';
|
|
20
|
+
import {findStrayPointers} from '../../foundation/discovery/stray-pointers.mjs';
|
|
18
21
|
|
|
19
22
|
/**
|
|
20
23
|
* Each component doc's props compared with the component's TypeScript props,
|
|
@@ -52,3 +55,58 @@ export async function integrationPropDrift(integration, cwd) {
|
|
|
52
55
|
resolveFrom: [cwd, packageDir],
|
|
53
56
|
});
|
|
54
57
|
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The passages two of a package's topics, or one of them and a Core topic,
|
|
61
|
+
* repeat word for word (architecture:cli-surface DEC-8). Reads the package's
|
|
62
|
+
* topics and Core's guides.
|
|
63
|
+
*
|
|
64
|
+
* @param {Parameters<typeof findCopiedPassages>[0]} discovered the package's
|
|
65
|
+
* docs, as discoverIntegrationDocs returns them
|
|
66
|
+
*/
|
|
67
|
+
export function integrationCopiedPassages(discovered) {
|
|
68
|
+
return findCopiedPassages(discovered);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Padding phrases and low-density topics in a package's prose
|
|
73
|
+
* (architecture:cli-surface DEC-8). Reads the package's topics, and Core's
|
|
74
|
+
* guides for the density median a finding names.
|
|
75
|
+
*
|
|
76
|
+
* @param {Parameters<typeof findFluff>[0]} discovered the package's docs, as
|
|
77
|
+
* discoverIntegrationDocs returns them
|
|
78
|
+
*/
|
|
79
|
+
export function integrationFluff(discovered) {
|
|
80
|
+
return findFluff(discovered);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Code spans in a package's prose that write `astryx docs <name>` for a doc
|
|
85
|
+
* that exists, where `{@link generic:<name>}` would be checked
|
|
86
|
+
* (architecture:cli-surface DEC-8). Reads the package's topics, its own
|
|
87
|
+
* component docs, and the names of Core's docs.
|
|
88
|
+
*
|
|
89
|
+
* @param {Parameters<typeof findStrayPointers>[0]} discovered the package's
|
|
90
|
+
* docs, as discoverIntegrationDocs returns them
|
|
91
|
+
* @param {any} [integration] the loaded integration, whose component docs are
|
|
92
|
+
* read too
|
|
93
|
+
*/
|
|
94
|
+
export async function integrationStrayPointers(discovered, integration) {
|
|
95
|
+
/** @type {{name: string, file: string}[]} */
|
|
96
|
+
const components = [];
|
|
97
|
+
if (integration?.components) {
|
|
98
|
+
const seen = new Set();
|
|
99
|
+
try {
|
|
100
|
+
const {components: records} =
|
|
101
|
+
await discoverValidIntegrationComponents(integration);
|
|
102
|
+
for (const record of records) {
|
|
103
|
+
if (!record.docPath || seen.has(record.docPath)) continue;
|
|
104
|
+
seen.add(record.docPath);
|
|
105
|
+
components.push({name: record.name, file: record.docPath});
|
|
106
|
+
}
|
|
107
|
+
} catch {
|
|
108
|
+
// `validate` reports component docs that do not load.
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return findStrayPointers({...discovered, components});
|
|
112
|
+
}
|