@astryxdesign/cli 0.7.2 → 0.7.3-canary.02f5fe4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -71
- package/api/build/_adapter.d.mts +58 -0
- package/api/build/_adapter.mjs +127 -3
- package/api/build/blocks/blocks.d.mts +92 -0
- package/api/build/blocks/blocks.mjs +528 -0
- package/api/build/blocks/blocks.test.mjs +238 -0
- package/api/build/blocks/blocks.weights.json +1 -0
- package/api/build/build.mjs +25 -6
- package/api/build/build.type.mjs +1 -1
- package/api/build/kit/answer.d.mts +18 -0
- package/api/build/kit/answer.mjs +195 -0
- package/api/build/kit/answer.test.mjs +108 -0
- package/api/build/kit/kind.d.mts +25 -0
- package/api/build/kit/kind.mjs +170 -0
- package/api/build/kit/kit.d.mts +2 -4
- package/api/build/kit/kit.mjs +8 -398
- package/api/build/kit/rank.d.mts +3 -32
- package/api/build/kit/rank.mjs +25 -342
- package/api/build/kit/rank.test.mjs +2 -1
- package/api/build/kit/signals.d.mts +79 -0
- package/api/build/kit/signals.mjs +295 -0
- package/api/build/kit/start.d.mts +32 -0
- package/api/build/kit/start.mjs +163 -0
- package/api/build/kit/words.d.mts +72 -0
- package/api/build/kit/words.mjs +202 -0
- package/api/build/tree.d.mts +20 -0
- package/api/build/tree.mjs +53 -0
- package/api/build/tree.test.mjs +185 -0
- package/api/build/tree.weights.json +1 -0
- package/api/component/_adapter.mjs +39 -5
- package/api/component/component-replacement.test.mjs +1 -0
- package/api/component/component.mjs +17 -3
- package/api/component/component.test.mjs +15 -0
- package/api/component/doc-links.test.mjs +2 -2
- package/api/discover/_adapter.d.mts +1 -2
- package/api/discover/_adapter.mjs +42 -17
- package/api/discover/_adapter.test.mjs +42 -0
- package/api/discover/discover.mjs +0 -1
- package/api/docs/_adapter.d.mts +2 -2
- package/api/docs/_adapter.mjs +82 -23
- package/api/docs/docs-homes.test.mjs +127 -0
- package/api/docs/docs.doc.mjs +3 -3
- package/api/docs/docs.test.mjs +35 -19
- package/api/docs/integration-tree.test.mjs +20 -20
- package/api/docs/integrationDocs.test.mjs +1 -1
- package/api/docs/namespace-section.test.mjs +6 -6
- package/api/docs/reference-blocks.test.mjs +2 -2
- package/api/doctor/_adapter.d.mts +33 -13
- package/api/doctor/_adapter.mjs +55 -25
- package/api/doctor/doctor.d.mts +23 -5
- package/api/doctor/doctor.mjs +183 -40
- package/api/doctor/doctor.test.mjs +95 -12
- package/api/hook/hook.mjs +1 -1
- package/api/init/init.doc.mjs +20 -6
- package/api/init/init.test.mjs +18 -2
- package/api/init/init.type.d.mts +3 -3
- package/api/init/init.type.mjs +3 -3
- package/api/init/remove/remove.mjs +17 -4
- package/api/init/remove/remove.test.mjs +114 -2
- package/api/init/run/run.mjs +69 -6
- package/api/integration/_adapter.d.mts +8 -0
- package/api/integration/_adapter.mjs +21 -1
- package/api/integration/authoring-checks.mjs +83 -9
- package/api/integration/authoring-checks.test.mjs +220 -0
- package/api/integration/pack-check.mjs +123 -4
- package/api/integration/pack-check.test.mjs +87 -0
- package/api/integration/validate-integration-case-disk.test.mjs +111 -0
- package/api/integration/validate-integration-fixes.test.mjs +6 -5
- package/api/integration/validate-integration-gaps.test.mjs +1975 -0
- package/api/integration/validate-integration.d.mts +15 -2
- package/api/integration/validate-integration.mjs +298 -39
- package/api/integration/validate-integration.type.d.mts +90 -1
- package/api/integration/validate-integration.type.mjs +67 -2
- package/api/integration/validateIntegration.doc.mjs +1 -1
- package/api/search/ORDERING.md +28 -0
- package/api/search/_adapter.d.mts +82 -2
- package/api/search/_adapter.mjs +157 -10
- package/api/search/_adapter.test.mjs +173 -0
- package/api/search/_candidate-score.d.mts +40 -0
- package/api/search/_candidate-score.mjs +238 -0
- package/api/search/_cards.json +6098 -0
- package/api/search/_compound.d.mts +50 -0
- package/api/search/_compound.mjs +170 -0
- package/api/search/_doc-searcher.d.mts +4 -0
- package/api/search/_doc-searcher.mjs +23 -0
- package/api/search/_doc-searcher.test.mjs +36 -0
- package/api/search/_doc-searcher.weights.json +1 -0
- package/api/search/_doc-text.d.mts +30 -0
- package/api/search/_doc-text.mjs +87 -0
- package/api/search/_entries.d.mts +63 -0
- package/api/search/_entries.mjs +232 -0
- package/api/search/_entries.test.mjs +48 -0
- package/api/search/_features.d.mts +35 -0
- package/api/search/_features.mjs +155 -0
- package/api/search/_gather-components.d.mts +26 -0
- package/api/search/_gather-components.mjs +284 -0
- package/api/search/_gather-docs.d.mts +20 -0
- package/api/search/_gather-docs.mjs +254 -0
- package/api/search/_gather-hooks.d.mts +12 -0
- package/api/search/_gather-hooks.mjs +52 -0
- package/api/search/_gather-templates.d.mts +25 -0
- package/api/search/_gather-templates.mjs +107 -0
- package/api/search/_lexical.d.mts +135 -0
- package/api/search/_lexical.mjs +351 -0
- package/api/search/_main-searcher.d.mts +19 -0
- package/api/search/_main-searcher.mjs +115 -0
- package/api/search/_main-searcher.test.mjs +106 -0
- package/api/search/_main-searcher.weights.json +1 -0
- package/api/search/_module-doc.d.mts +32 -0
- package/api/search/_module-doc.mjs +78 -0
- package/api/search/_order.d.mts +32 -0
- package/api/search/_order.mjs +162 -0
- package/api/search/_order.test.mjs +72 -0
- package/api/search/_priority.d.mts +50 -0
- package/api/search/_priority.mjs +139 -0
- package/api/search/_query-words.d.mts +25 -0
- package/api/search/_query-words.mjs +92 -0
- package/api/search/_query.d.mts +65 -0
- package/api/search/_query.mjs +176 -0
- package/api/search/_result.d.mts +97 -0
- package/api/search/_result.mjs +150 -0
- package/api/search/_score.d.mts +60 -0
- package/api/search/_score.mjs +283 -0
- package/api/search/_synonyms.d.mts +21 -0
- package/api/search/_synonyms.mjs +67 -0
- package/api/search/_template-searcher.d.mts +4 -0
- package/api/search/_template-searcher.mjs +23 -0
- package/api/search/_template-searcher.test.mjs +40 -0
- package/api/search/_template-searcher.weights.json +1 -0
- package/api/search/_titles.d.mts +33 -0
- package/api/search/_titles.mjs +65 -0
- package/api/search/_words.d.mts +64 -0
- package/api/search/_words.mjs +157 -0
- package/api/search/search.d.mts +22 -305
- package/api/search/search.doc.mjs +8 -6
- package/api/search/search.mjs +56 -2482
- package/api/search/search.test.mjs +14 -14
- package/api/search/search.type.d.mts +6 -1
- package/api/search/search.type.mjs +6 -1
- package/api/search/tree.d.mts +15 -0
- package/api/search/tree.mjs +40 -0
- package/api/search/tree.test.mjs +66 -0
- package/api/search/tree.weights.json +1 -0
- package/api/template/template.mjs +5 -1
- package/api/theme/build/build.packed-old-core.test.mjs +1 -0
- package/api/upgrade/_adapter.d.mts +57 -9
- package/api/upgrade/_adapter.mjs +198 -28
- package/api/upgrade/registry/registry.d.mts +10 -4
- package/api/upgrade/registry/registry.mjs +33 -16
- package/api/upgrade/registry/registry.test.mjs +85 -0
- package/api/upgrade/run/run.d.mts +4 -2
- package/api/upgrade/run/run.mjs +13 -2
- package/api/upgrade/run/run.test.mjs +417 -3
- package/api/upgrade/upgrade.doc.mjs +10 -5
- package/api/upgrade/upgrade.mjs +13 -2
- package/api/upgrade/upgrade.test.mjs +194 -0
- package/api/upgrade/upgrade.type.d.mts +5 -3
- package/api/upgrade/upgrade.type.mjs +8 -6
- package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
- package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
- package/assets/docs/author-a-theme.doc.mjs +2 -2
- package/assets/docs/is-my-code-good.doc.mjs +287 -0
- package/assets/docs/tree/add-a-component.doc.mjs +1 -1
- package/assets/docs/tree/add-a-theme.doc.mjs +1 -1
- package/assets/docs/tree/add-a-topic.doc.mjs +2 -2
- package/assets/docs/tree/agent-guidance.doc.mjs +1 -1
- package/assets/docs/tree/api.doc.mjs +6 -0
- package/assets/docs/tree/{integrations.doc.mjs → authoring.doc.mjs} +15 -6
- package/assets/docs/tree/block-template.doc.mjs +1 -1
- package/assets/docs/tree/build-the-template.doc.mjs +1 -1
- package/assets/docs/tree/building-blocks.doc.mjs +2 -2
- package/assets/docs/tree/check-the-props.doc.mjs +1 -1
- package/assets/docs/tree/check-your-docs.doc.mjs +2 -2
- package/assets/docs/tree/checks.doc.mjs +3 -3
- package/assets/docs/tree/ci-and-containers.doc.mjs +13 -0
- package/assets/docs/tree/cli-command.doc.mjs +1 -1
- package/assets/docs/tree/cli.doc.mjs +1 -1
- package/assets/docs/tree/codemods.doc.mjs +1 -1
- package/assets/docs/tree/component-family.doc.mjs +1 -1
- package/assets/docs/tree/component-imports.doc.mjs +1 -1
- package/assets/docs/tree/components.doc.mjs +1 -1
- package/assets/docs/tree/configuration.doc.mjs +1 -1
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +1 -1
- package/assets/docs/tree/define-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
- package/assets/docs/tree/docs.doc.mjs +1 -1
- package/assets/docs/tree/document-the-template.doc.mjs +1 -1
- package/assets/docs/tree/document-the-theme.doc.mjs +1 -1
- package/assets/docs/tree/export-template-assets.doc.mjs +1 -1
- package/assets/docs/tree/extend-or-replace.doc.mjs +1 -1
- package/assets/docs/{authoring.doc.mjs → tree/field-reference.doc.mjs} +4 -3
- package/assets/docs/tree/fonts-and-assets.doc.mjs +1 -1
- package/assets/docs/tree/generate-a-palette.doc.mjs +1 -1
- package/assets/docs/tree/global-integrations.doc.mjs +2 -2
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +4 -4
- package/assets/docs/tree/help.doc.mjs +2 -2
- package/assets/docs/tree/host-entry.doc.mjs +128 -0
- package/assets/docs/tree/links.doc.mjs +1 -1
- package/assets/docs/tree/package-and-test.doc.mjs +1 -1
- package/assets/docs/tree/page-template.doc.mjs +1 -1
- package/assets/docs/tree/publishing.doc.mjs +1 -1
- package/assets/docs/tree/quick-start.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-component.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-template.doc.mjs +1 -1
- package/assets/docs/tree/sections-and-placement.doc.mjs +1 -1
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/ship.doc.mjs +2 -2
- package/assets/docs/tree/short-and-findable.doc.mjs +1 -1
- package/assets/docs/tree/single-component.doc.mjs +1 -1
- package/assets/docs/tree/start-a-template.doc.mjs +1 -1
- package/assets/docs/tree/subcomponent.doc.mjs +1 -1
- package/assets/docs/tree/template-assets.doc.mjs +1 -1
- package/assets/docs/tree/template-doc-overview.doc.mjs +2 -2
- package/assets/docs/tree/template-fonts.doc.mjs +1 -1
- package/assets/docs/tree/template-grading-rubric.doc.mjs +17 -38
- package/assets/docs/tree/template-icons.doc.mjs +1 -1
- package/assets/docs/tree/template-images-media.doc.mjs +1 -1
- package/assets/docs/tree/template-styles.doc.mjs +1 -1
- package/assets/docs/tree/templates.doc.mjs +1 -1
- package/assets/docs/tree/test-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/test-template-in-app.doc.mjs +1 -1
- package/assets/docs/tree/themes.doc.mjs +1 -1
- package/assets/docs/tree/tokens-data.doc.mjs +2 -2
- package/assets/docs/tree/troubleshooting.doc.mjs +1 -1
- package/assets/docs/tree/upgrading.doc.mjs +1 -1
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +1 -1
- package/assets/docs/tree/verify-packed-template.doc.mjs +1 -1
- package/assets/docs/tree/versioning.doc.mjs +5 -1
- package/assets/docs/tree/write-good-templates.doc.mjs +1 -1
- package/assets/docs/tree/write-the-template-file.doc.mjs +1 -1
- package/assets/docs/use-integrations.doc.mjs +120 -0
- package/assets/docs/working-with-ai.doc.mjs +6 -2
- package/assets/templates/themes/butter/butterTheme.ts +4 -2
- package/assets/templates/themes/stone/stoneTheme.ts +4 -2
- package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
- package/authoring/debug/parse.d.mts +1 -1
- package/authoring/doctypes/schema/schema.doc.mjs +1 -1
- package/authoring/integration/integration.doc.mjs +1 -1
- package/authoring/integration/type.ts +1 -1
- package/clients/cli/bin/astryx.mjs +7 -78
- package/clients/cli/command-result-coverage.test.mjs +6 -5
- package/clients/cli/commands/build-theme.color-scheme.test.mjs +1 -1
- package/clients/cli/commands/{component/index.mjs → component.mjs} +37 -37
- package/clients/cli/commands/component.test.mjs +6 -6
- package/clients/cli/commands/docs.doc.mjs +2 -2
- package/clients/cli/commands/docs.mjs +1 -1
- package/clients/cli/commands/docs.test.mjs +14 -14
- package/clients/cli/commands/doctor-integration.test.mjs +49 -1
- package/clients/cli/commands/doctor.doc.mjs +1 -1
- package/clients/cli/commands/doctor.mjs +40 -0
- package/clients/cli/commands/doctor.test.mjs +65 -0
- package/clients/cli/commands/{hook/index.mjs → hook.mjs} +22 -22
- package/clients/cli/commands/import-hint-correctness.test.mjs +1 -1
- package/clients/cli/commands/init.behavior.test.mjs +230 -1
- package/clients/cli/commands/init.doc.mjs +28 -9
- package/clients/cli/commands/init.flag-help.test.mjs +1 -0
- package/clients/cli/commands/init.mjs +2 -2
- package/clients/cli/commands/integration-check.test.mjs +48 -0
- package/clients/cli/commands/integration.doc.mjs +1 -1
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/manifest.mjs +67 -0
- package/clients/cli/commands/outside-project.test.mjs +101 -1
- package/clients/cli/commands/postinstall.doc.mjs +23 -0
- package/clients/cli/commands/postinstall.mjs +31 -0
- package/clients/cli/commands/setup-nudge.test.mjs +78 -0
- package/clients/cli/commands/{build-theme.mjs → theme.mjs} +1 -1
- package/clients/cli/commands/upgrade.doc.mjs +4 -2
- package/clients/cli/commands/upgrade.mjs +9 -2
- package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
- package/clients/cli/index.mjs +54 -94
- package/clients/cli/lib/component-format.mjs +1 -1
- package/clients/cli/lib/define-command.mjs +12 -7
- package/clients/cli/lib/exit-codes.test.mjs +5 -0
- package/clients/cli/lib/manifest.test.mjs +12 -0
- package/clients/cli/lib/welcome-box.mjs +50 -0
- package/clients/cli/run.mjs +108 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +32 -7
- package/foundation/agent-docs/agent-doc-state.mjs +58 -9
- package/foundation/agent-docs/agent-docs.d.mts +100 -12
- package/foundation/agent-docs/agent-docs.mjs +1017 -105
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
- package/foundation/agent-docs/agent-docs.test.mjs +683 -39
- package/foundation/agent-docs/computer-agent-text.d.mts +39 -2
- package/foundation/agent-docs/computer-agent-text.mjs +135 -8
- package/foundation/agent-docs/computer-agent-text.test.mjs +99 -2
- package/foundation/config/project.mjs +20 -22
- package/foundation/config/project.test.mjs +56 -0
- package/foundation/discovery/authoring-self-docs.d.mts +7 -0
- package/foundation/discovery/authoring-self-docs.mjs +16 -4
- package/foundation/discovery/authoring-self-docs.test.mjs +15 -3
- package/foundation/discovery/authoring-surface.d.mts +1 -1
- package/foundation/discovery/authoring-surface.mjs +2 -2
- package/foundation/discovery/authoring-surface.test.mjs +1 -1
- package/foundation/discovery/cli-self-docs.d.mts +2 -1
- package/foundation/discovery/cli-self-docs.mjs +4 -3
- package/foundation/discovery/cli-self-docs.test.mjs +2 -2
- package/foundation/discovery/component-discovery.d.mts +37 -0
- package/foundation/discovery/component-discovery.mjs +80 -5
- package/foundation/discovery/component-loader.d.mts +1 -1
- package/foundation/discovery/docs-discovery.mjs +14 -1
- package/foundation/discovery/module-exports.d.mts +41 -0
- package/foundation/discovery/module-exports.mjs +253 -0
- package/foundation/discovery/runner-allowlist.d.mts +2 -4
- package/foundation/discovery/runner-allowlist.mjs +2 -4
- package/foundation/discovery/runner-commands.d.mts +77 -0
- package/foundation/discovery/runner-commands.mjs +294 -0
- package/foundation/discovery/runner-commands.test.mjs +128 -0
- package/foundation/discovery/stray-pointers.test.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +18 -1
- package/foundation/discovery/template-needs.mjs +1 -44
- package/foundation/discovery/theme-discovery.mjs +147 -3
- package/foundation/doc-compiler/doc-loads.test.mjs +33 -9
- package/foundation/doc-compiler/read.mjs +59 -1
- package/foundation/doc-compiler/read.test.mjs +11 -2
- package/foundation/doc-compiler/split-topic-keywords.test.mjs +3 -2
- package/foundation/doc-compiler/tree.d.mts +32 -6
- package/foundation/doc-compiler/tree.mjs +77 -43
- package/foundation/doc-compiler/tree.test.mjs +7 -7
- package/foundation/fs/paths.d.mts +70 -8
- package/foundation/fs/paths.mjs +556 -38
- package/foundation/fs/paths.test.mjs +430 -54
- package/foundation/fs/read-record.d.mts +18 -0
- package/foundation/fs/read-record.mjs +131 -0
- package/foundation/fs/read-record.test.mjs +77 -0
- package/foundation/integrations/autolink.d.mts +2 -1
- package/foundation/integrations/autolink.mjs +4 -13
- package/foundation/integrations/cli-peer-version.d.mts +36 -0
- package/foundation/integrations/cli-peer-version.mjs +132 -0
- package/foundation/integrations/cli-peer-version.test.mjs +354 -0
- package/foundation/integrations/computer-integrations.d.mts +6 -3
- package/foundation/integrations/computer-integrations.mjs +38 -9
- package/foundation/integrations/contribution-inventory.d.mts +15 -20
- package/foundation/integrations/contribution-inventory.mjs +41 -5
- package/foundation/integrations/exports-subpaths.d.mts +57 -0
- package/foundation/integrations/exports-subpaths.mjs +113 -0
- package/foundation/integrations/integrations.d.mts +27 -1
- package/foundation/integrations/integrations.mjs +61 -2
- package/foundation/integrations/public-imports.d.mts +118 -0
- package/foundation/integrations/public-imports.mjs +1769 -0
- package/foundation/integrations/public-imports.test.mjs +1793 -0
- package/foundation/integrations/validate-contributions.d.mts +115 -0
- package/foundation/integrations/validate-contributions.mjs +1168 -13
- package/foundation/release/cache.test.mjs +24 -21
- package/foundation/release/global-state.d.mts +8 -4
- package/foundation/release/global-state.mjs +4 -2
- package/foundation/release/handoff.d.mts +23 -4
- package/foundation/release/handoff.mjs +175 -8
- package/foundation/release/notices.d.mts +62 -8
- package/foundation/release/notices.mjs +136 -25
- package/foundation/release/notices.test.mjs +21 -0
- package/foundation/release/run-context.mjs +14 -0
- package/foundation/response/response-types.doc.mjs +1 -1
- package/foundation/route/route.d.mts +285 -0
- package/foundation/route/route.mjs +324 -0
- package/foundation/route/route.test.mjs +153 -0
- package/foundation/runtime/hosted-runtime.test.mjs +403 -0
- package/foundation/runtime/locked-versions.d.mts +32 -0
- package/foundation/runtime/locked-versions.mjs +65 -0
- package/foundation/runtime/package-root.d.mts +91 -0
- package/foundation/runtime/package-root.mjs +174 -0
- package/foundation/runtime/package-set.d.mts +62 -0
- package/foundation/runtime/package-set.mjs +130 -0
- package/foundation/runtime/package-set.test.mjs +432 -0
- package/foundation/text/string-utils.d.mts +2 -1
- package/foundation/text/string-utils.mjs +16 -5
- package/foundation/text/suggest-order.d.mts +72 -0
- package/foundation/text/suggest-order.mjs +363 -0
- package/foundation/text/suggest-order.test.mjs +259 -0
- package/host/door-conformance.test.mjs +274 -0
- package/host/index.d.ts +116 -0
- package/host/index.mjs +295 -0
- package/host/index.test.mjs +302 -0
- package/package.json +14 -9
|
@@ -802,8 +802,28 @@ describe('stopped and damaged installs heal', () => {
|
|
|
802
802
|
});
|
|
803
803
|
});
|
|
804
804
|
|
|
805
|
+
/** @param {number} pid */
|
|
806
|
+
const alive = pid => {
|
|
807
|
+
try {
|
|
808
|
+
process.kill(pid, 0);
|
|
809
|
+
return true;
|
|
810
|
+
} catch {
|
|
811
|
+
return false;
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
/** @param {() => boolean} done @param {number} ms */
|
|
816
|
+
const waitFor = async (done, ms) => {
|
|
817
|
+
const end = Date.now() + ms;
|
|
818
|
+
while (Date.now() < end) {
|
|
819
|
+
if (done()) return true;
|
|
820
|
+
await new Promise(r => setTimeout(r, 100));
|
|
821
|
+
}
|
|
822
|
+
return done();
|
|
823
|
+
};
|
|
824
|
+
|
|
805
825
|
describe('runNpm time limit', () => {
|
|
806
|
-
it('ends a package manager that ignores SIGTERM, leaving no process behind', () => {
|
|
826
|
+
it('ends a package manager that ignores SIGTERM, leaving no process behind', async () => {
|
|
807
827
|
const marker = tempDir('npm-pid');
|
|
808
828
|
const pidFile = path.join(marker, 'pid');
|
|
809
829
|
const result = runNpm([], {
|
|
@@ -819,30 +839,13 @@ describe('runNpm time limit', () => {
|
|
|
819
839
|
});
|
|
820
840
|
expect(/** @type {any} */ (result.error)?.code).toBe('ETIMEDOUT');
|
|
821
841
|
const pid = Number(fs.readFileSync(pidFile, 'utf-8'));
|
|
822
|
-
|
|
842
|
+
// The guard sends SIGKILL and exits at once; the killed process can still
|
|
843
|
+
// exist for a moment (the signal in flight, or awaiting reaping).
|
|
844
|
+
expect(await waitFor(() => !alive(pid), 5_000)).toBe(true);
|
|
823
845
|
});
|
|
824
846
|
});
|
|
825
847
|
|
|
826
848
|
describe('no install outlives its run', () => {
|
|
827
|
-
/** @param {number} pid */
|
|
828
|
-
const alive = pid => {
|
|
829
|
-
try {
|
|
830
|
-
process.kill(pid, 0);
|
|
831
|
-
return true;
|
|
832
|
-
} catch {
|
|
833
|
-
return false;
|
|
834
|
-
}
|
|
835
|
-
};
|
|
836
|
-
/** @param {() => boolean} done @param {number} ms */
|
|
837
|
-
const waitFor = async (done, ms) => {
|
|
838
|
-
const end = Date.now() + ms;
|
|
839
|
-
while (Date.now() < end) {
|
|
840
|
-
if (done()) return true;
|
|
841
|
-
await new Promise(r => setTimeout(r, 100));
|
|
842
|
-
}
|
|
843
|
-
return done();
|
|
844
|
-
};
|
|
845
|
-
|
|
846
849
|
it('ends npm when the run that started it is killed outright, and removes its process-id record', async () => {
|
|
847
850
|
const dir = tempDir('orphan');
|
|
848
851
|
const pidFile = path.join(dir, 'npm-pid');
|
|
@@ -20,9 +20,11 @@
|
|
|
20
20
|
*/
|
|
21
21
|
/**
|
|
22
22
|
* Why an update notice did not print: `already-shown` (it printed within the
|
|
23
|
-
* day)
|
|
23
|
+
* day), `no-newer` (nothing newer is known), or `no-project` (the folder
|
|
24
|
+
* installs Core but belongs to no Astryx project, so no install command
|
|
25
|
+
* fits). Recorded only while the run
|
|
24
26
|
* holds the state file's lock.
|
|
25
|
-
* @typedef {{reason: 'already-shown' | 'no-newer', at: number}} NoticeSkip
|
|
27
|
+
* @typedef {{reason: 'already-shown' | 'no-newer' | 'no-project', at: number}} NoticeSkip
|
|
26
28
|
*/
|
|
27
29
|
/**
|
|
28
30
|
* The state file.
|
|
@@ -242,11 +244,13 @@ export type GlobalState = {
|
|
|
242
244
|
};
|
|
243
245
|
/**
|
|
244
246
|
* Why an update notice did not print: `already-shown` (it printed within the
|
|
245
|
-
* day)
|
|
247
|
+
* day), `no-newer` (nothing newer is known), or `no-project` (the folder
|
|
248
|
+
* installs Core but belongs to no Astryx project, so no install command
|
|
249
|
+
* fits). Recorded only while the run
|
|
246
250
|
* holds the state file's lock.
|
|
247
251
|
*/
|
|
248
252
|
export type NoticeSkip = {
|
|
249
|
-
reason: "already-shown" | "no-newer";
|
|
253
|
+
reason: "already-shown" | "no-newer" | "no-project";
|
|
250
254
|
at: number;
|
|
251
255
|
};
|
|
252
256
|
/**
|
|
@@ -68,9 +68,11 @@ export const CHECK_INTERVAL_MS = 24 * 60 * 60_000;
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* Why an update notice did not print: `already-shown` (it printed within the
|
|
71
|
-
* day)
|
|
71
|
+
* day), `no-newer` (nothing newer is known), or `no-project` (the folder
|
|
72
|
+
* installs Core but belongs to no Astryx project, so no install command
|
|
73
|
+
* fits). Recorded only while the run
|
|
72
74
|
* holds the state file's lock.
|
|
73
|
-
* @typedef {{reason: 'already-shown' | 'no-newer', at: number}} NoticeSkip
|
|
75
|
+
* @typedef {{reason: 'already-shown' | 'no-newer' | 'no-project', at: number}} NoticeSkip
|
|
74
76
|
*/
|
|
75
77
|
|
|
76
78
|
/**
|
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
* @returns {string}
|
|
11
11
|
*/
|
|
12
12
|
export function whoAnsweredLine(choice: import("./choose.mjs").ReleaseChoice, computer?: boolean): string;
|
|
13
|
+
/**
|
|
14
|
+
* The line for a run this copy answers in place of the project's own CLI,
|
|
15
|
+
* which a host declined, when this copy is that CLI's release (FR2).
|
|
16
|
+
* @param {string} version
|
|
17
|
+
* @param {string} reason the reason, as {@link declinedReasonText} words it
|
|
18
|
+
* @returns {string}
|
|
19
|
+
*/
|
|
20
|
+
export function inPlaceOfProjectLine(version: string, reason: string): string;
|
|
13
21
|
/**
|
|
14
22
|
* The line for a run handed to the project's own CLI.
|
|
15
23
|
* @param {string} projectVersion
|
|
@@ -41,15 +49,26 @@ export function progressText(event: "install" | "wait", version: string): string
|
|
|
41
49
|
* @returns {string}
|
|
42
50
|
*/
|
|
43
51
|
export function fallbackLine(wanted: string, reason: string, answering: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* The fallback warning's reason for a project CLI a host declined.
|
|
54
|
+
* @param {string} reason the host's own words
|
|
55
|
+
* @returns {string}
|
|
56
|
+
*/
|
|
57
|
+
export function declinedReasonText(reason: string): string;
|
|
44
58
|
/**
|
|
45
59
|
* Choose who answers and hand off when it is not this copy.
|
|
46
|
-
* @param {{cliRoot: string, argv: string[]}} input
|
|
47
|
-
*
|
|
60
|
+
* @param {{cliRoot: string, argv: string[], declinedProjectCli?: string}} input
|
|
61
|
+
* argv after `node astryx`; the reason a programmatic host declined the
|
|
62
|
+
* project's own CLI, when it did
|
|
63
|
+
* @returns {Promise<import('../../host/index.js').HostedCliResult | undefined>}
|
|
64
|
+
* resolves with nothing when this copy answers, and with that release's
|
|
65
|
+
* result when another package set's host entry answered a hosted run
|
|
48
66
|
*/
|
|
49
|
-
export function startRun({ cliRoot, argv }: {
|
|
67
|
+
export function startRun({ cliRoot, argv, declinedProjectCli }: {
|
|
50
68
|
cliRoot: string;
|
|
51
69
|
argv: string[];
|
|
52
|
-
|
|
70
|
+
declinedProjectCli?: string;
|
|
71
|
+
}): Promise<import("../../host/index.js").HostedCliResult | undefined>;
|
|
53
72
|
/**
|
|
54
73
|
* How long a hand-off waits after an interrupt before passing it on to a CLI
|
|
55
74
|
* that is still running. An interrupt sent to the whole process group (a
|
|
@@ -19,9 +19,26 @@
|
|
|
19
19
|
* (notices.mjs); a global copy also starts the daily update check, which
|
|
20
20
|
* installs nothing (global-state.mjs).
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
22
|
+
* A programmatic host that found the project's own CLI and did not run it
|
|
23
|
+
* passes the reason (spec AST-081 FR1, FR2). That run is never handed to the
|
|
24
|
+
* project's CLI: this copy answers in its place when it is that CLI's release,
|
|
25
|
+
* saying so in a line of its own; a package set of the host's whose CLI is
|
|
26
|
+
* that release answers through its own host entry; and otherwise this copy
|
|
27
|
+
* answers as for a release that cannot be obtained, with the warning naming
|
|
28
|
+
* the reason.
|
|
29
|
+
*
|
|
30
|
+
* A hosted run installs nothing (architecture:cli-surface INV30): a release
|
|
31
|
+
* other than this copy comes only from the first of the host's package sets
|
|
32
|
+
* that qualifies. When that CLI ships a host entry, the entry runs in this
|
|
33
|
+
* process with the same inputs, discover sources included, and the host's
|
|
34
|
+
* call settles with its result; otherwise its bin takes the run. With no such
|
|
35
|
+
* set, this copy answers, announced.
|
|
36
|
+
*
|
|
37
|
+
* @input the running copy, argv, the working folder, and a host's
|
|
38
|
+
* declined-project-CLI reason
|
|
39
|
+
* @output returns when this copy answers, or with another release's result
|
|
40
|
+
* when its host entry answered; never returns after a hand-off to a bin
|
|
41
|
+
* @position foundation/release — called once per run by clients/cli/run.mjs.
|
|
25
42
|
*/
|
|
26
43
|
|
|
27
44
|
import {spawn} from 'node:child_process';
|
|
@@ -32,8 +49,10 @@ import {
|
|
|
32
49
|
isGlobalCopy,
|
|
33
50
|
namesWhoAnswered,
|
|
34
51
|
packageRootOf,
|
|
52
|
+
projectRootOf,
|
|
35
53
|
runningCopy,
|
|
36
54
|
} from './choose.mjs';
|
|
55
|
+
import {readReleaseFacts} from './project.mjs';
|
|
37
56
|
import {ensureRelease, userCacheDir} from './cache.mjs';
|
|
38
57
|
import {
|
|
39
58
|
maybeFetchCore,
|
|
@@ -43,6 +62,8 @@ import {
|
|
|
43
62
|
import {recordRunChoice} from './run-context.mjs';
|
|
44
63
|
import {noticeLines} from './notices.mjs';
|
|
45
64
|
import {cliDoor, runWithCliDoor} from '../env/cli-command.mjs';
|
|
65
|
+
import {hostedRun} from '../runtime/package-root.mjs';
|
|
66
|
+
import {qualifyingRoot} from '../runtime/package-set.mjs';
|
|
46
67
|
|
|
47
68
|
/** Where each release's notes are published. */
|
|
48
69
|
|
|
@@ -63,6 +84,17 @@ export function whoAnsweredLine(choice, computer = false) {
|
|
|
63
84
|
: `astryx: answered by CLI ${choice.version} with Core ${core}, outside a project`;
|
|
64
85
|
}
|
|
65
86
|
|
|
87
|
+
/**
|
|
88
|
+
* The line for a run this copy answers in place of the project's own CLI,
|
|
89
|
+
* which a host declined, when this copy is that CLI's release (FR2).
|
|
90
|
+
* @param {string} version
|
|
91
|
+
* @param {string} reason the reason, as {@link declinedReasonText} words it
|
|
92
|
+
* @returns {string}
|
|
93
|
+
*/
|
|
94
|
+
export function inPlaceOfProjectLine(version, reason) {
|
|
95
|
+
return `astryx: answered by CLI ${version}, the release of this project's CLI, in its place (${reason})`;
|
|
96
|
+
}
|
|
97
|
+
|
|
66
98
|
/**
|
|
67
99
|
* The line for a run handed to the project's own CLI.
|
|
68
100
|
* @param {string} projectVersion
|
|
@@ -131,16 +163,32 @@ function failUnavailable(message, json) {
|
|
|
131
163
|
process.exit(1);
|
|
132
164
|
}
|
|
133
165
|
|
|
166
|
+
/**
|
|
167
|
+
* The fallback warning's reason for a project CLI a host declined.
|
|
168
|
+
* @param {string} reason the host's own words
|
|
169
|
+
* @returns {string}
|
|
170
|
+
*/
|
|
171
|
+
export function declinedReasonText(reason) {
|
|
172
|
+
return `project CLI skipped: ${reason}`;
|
|
173
|
+
}
|
|
174
|
+
|
|
134
175
|
/**
|
|
135
176
|
* Choose who answers and hand off when it is not this copy.
|
|
136
|
-
* @param {{cliRoot: string, argv: string[]}} input
|
|
137
|
-
*
|
|
177
|
+
* @param {{cliRoot: string, argv: string[], declinedProjectCli?: string}} input
|
|
178
|
+
* argv after `node astryx`; the reason a programmatic host declined the
|
|
179
|
+
* project's own CLI, when it did
|
|
180
|
+
* @returns {Promise<import('../../host/index.js').HostedCliResult | undefined>}
|
|
181
|
+
* resolves with nothing when this copy answers, and with that release's
|
|
182
|
+
* result when another package set's host entry answered a hosted run
|
|
138
183
|
*/
|
|
139
|
-
export async function startRun({cliRoot, argv}) {
|
|
184
|
+
export async function startRun({cliRoot, argv, declinedProjectCli}) {
|
|
140
185
|
const json = argv.includes('--json');
|
|
141
186
|
const self = runningCopy(cliRoot);
|
|
142
187
|
const cacheDir = userCacheDir();
|
|
143
|
-
|
|
188
|
+
// A host carries its own CLI and keeps it current itself: a hosted copy
|
|
189
|
+
// runs none of the global copy's background work, and installs nothing.
|
|
190
|
+
const hosted = hostedRun();
|
|
191
|
+
const global = !hosted && isGlobalCopy(cliRoot, cacheDir);
|
|
144
192
|
if (global) {
|
|
145
193
|
try {
|
|
146
194
|
maybeStartCheck();
|
|
@@ -189,7 +237,46 @@ export async function startRun({cliRoot, argv}) {
|
|
|
189
237
|
};
|
|
190
238
|
}
|
|
191
239
|
|
|
192
|
-
|
|
240
|
+
// A host declined the project's own CLI (FR2): the run is never handed to
|
|
241
|
+
// it. The release equal to that CLI's version answers in its place when
|
|
242
|
+
// this copy is that release, or when a package set of the host's holds it
|
|
243
|
+
// with a host entry; otherwise this copy answers, announced as for a release
|
|
244
|
+
// that cannot be obtained, naming the reason.
|
|
245
|
+
let declined = null;
|
|
246
|
+
/** Set when this copy answers in place of the declined CLI, its release. */
|
|
247
|
+
let inPlace = null;
|
|
248
|
+
if (
|
|
249
|
+
declinedProjectCli &&
|
|
250
|
+
choice.copy === 'project' &&
|
|
251
|
+
choice.answer !== 'self'
|
|
252
|
+
) {
|
|
253
|
+
if (choice.version === self.version) {
|
|
254
|
+
// Still the project CLI's release (`copy` stays `project`), never the
|
|
255
|
+
// release matched to the project's Core, which can be another.
|
|
256
|
+
choice = {...choice, answer: 'self', bin: null, unavailable: null};
|
|
257
|
+
inPlace = declinedReasonText(declinedProjectCli);
|
|
258
|
+
} else {
|
|
259
|
+
const served = hosted
|
|
260
|
+
? qualifyingRoot({
|
|
261
|
+
release: choice.version,
|
|
262
|
+
projectDir: projectDirOf(process.cwd()),
|
|
263
|
+
roots: hosted.roots,
|
|
264
|
+
needsHostEntry: true,
|
|
265
|
+
})
|
|
266
|
+
: null;
|
|
267
|
+
if (served && 'root' in served && served.hostEntry) {
|
|
268
|
+
const answered = await answerInPackageSet(
|
|
269
|
+
served.hostEntry,
|
|
270
|
+
served.root,
|
|
271
|
+
{argv, declinedProjectCli},
|
|
272
|
+
);
|
|
273
|
+
if (answered) return answered;
|
|
274
|
+
}
|
|
275
|
+
declined = declinedReasonText(declinedProjectCli);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (!declined && choice.unavailable && choice.copy === 'project') {
|
|
193
280
|
failUnavailable(
|
|
194
281
|
`This project's CLI ${choice.version} could not be started: ${choice.unavailable}. Reinstall the project's dependencies.`,
|
|
195
282
|
json,
|
|
@@ -245,6 +332,11 @@ export async function startRun({cliRoot, argv}) {
|
|
|
245
332
|
});
|
|
246
333
|
};
|
|
247
334
|
|
|
335
|
+
if (declined) {
|
|
336
|
+
await fallBack(declined);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
248
340
|
if (choice.unavailable) {
|
|
249
341
|
await fallBack(choice.unavailable);
|
|
250
342
|
return;
|
|
@@ -256,6 +348,8 @@ export async function startRun({cliRoot, argv}) {
|
|
|
256
348
|
// line; a hint after the command, once a day, says how to match it.
|
|
257
349
|
if (!json && (choice.copy === 'matched' || choice.copy === 'carried'))
|
|
258
350
|
console.error(whoAnsweredLine(choice, computer));
|
|
351
|
+
else if (!json && inPlace)
|
|
352
|
+
console.error(inPlaceOfProjectLine(choice.version, inPlace));
|
|
259
353
|
process.once('exit', code => {
|
|
260
354
|
if (code === 0) notify();
|
|
261
355
|
});
|
|
@@ -263,6 +357,32 @@ export async function startRun({cliRoot, argv}) {
|
|
|
263
357
|
}
|
|
264
358
|
|
|
265
359
|
let bin = choice.bin;
|
|
360
|
+
if (!bin && hosted) {
|
|
361
|
+
const served = qualifyingRoot({
|
|
362
|
+
release: choice.version,
|
|
363
|
+
projectDir: projectDirOf(process.cwd()),
|
|
364
|
+
roots: hosted.roots,
|
|
365
|
+
});
|
|
366
|
+
if (!('root' in served)) {
|
|
367
|
+
await fallBack(served.reason);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (served.hostEntry) {
|
|
371
|
+
const answered = await answerInPackageSet(served.hostEntry, served.root, {
|
|
372
|
+
argv,
|
|
373
|
+
});
|
|
374
|
+
if (answered) return answered;
|
|
375
|
+
}
|
|
376
|
+
// A hosted run installs nothing (INV30): a set whose CLI starts through
|
|
377
|
+
// neither its host entry nor a bin leaves this copy to answer.
|
|
378
|
+
if (!served.bin) {
|
|
379
|
+
await fallBack(
|
|
380
|
+
`the CLI ${choice.version} in the package set at ${served.root} could not be started`,
|
|
381
|
+
);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
bin = served.bin;
|
|
385
|
+
}
|
|
266
386
|
if (!bin) {
|
|
267
387
|
const release = ensureRelease(choice.version, {
|
|
268
388
|
cacheDir,
|
|
@@ -295,6 +415,53 @@ export async function startRun({cliRoot, argv}) {
|
|
|
295
415
|
*/
|
|
296
416
|
export const INTERRUPT_GRACE_MS = 5000;
|
|
297
417
|
|
|
418
|
+
/**
|
|
419
|
+
* The project folder a run in `cwd` belongs to, or null outside a project.
|
|
420
|
+
* @param {string} cwd
|
|
421
|
+
* @returns {string | null}
|
|
422
|
+
*/
|
|
423
|
+
function projectDirOf(cwd) {
|
|
424
|
+
try {
|
|
425
|
+
return projectRootOf(readReleaseFacts(cwd));
|
|
426
|
+
} catch {
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Hand a hosted run over to the CLI of one of the host's package sets,
|
|
433
|
+
* through that CLI's own host entry, in this process, with the inputs this run
|
|
434
|
+
* got: the arguments, the folder, the command name, the approved integrations,
|
|
435
|
+
* the discover sources, and the reason the host declined the project's CLI.
|
|
436
|
+
* Its roots are that package set alone. That CLI prints its own who-answered
|
|
437
|
+
* line and notices, and the host's call settles with its result.
|
|
438
|
+
* @param {string} hostEntry the package set's `host/index.mjs`
|
|
439
|
+
* @param {string} root the package set
|
|
440
|
+
* @param {{argv: string[], declinedProjectCli?: string}} run
|
|
441
|
+
* @returns {Promise<import('../../host/index.js').HostedCliResult | null>} null
|
|
442
|
+
* when the entry cannot be loaded, before anything ran
|
|
443
|
+
*/
|
|
444
|
+
async function answerInPackageSet(hostEntry, root, {argv, declinedProjectCli}) {
|
|
445
|
+
const hosted = hostedRun();
|
|
446
|
+
if (!hosted?.loadHostEntry) return null;
|
|
447
|
+
let answer;
|
|
448
|
+
try {
|
|
449
|
+
answer = await hosted.loadHostEntry(hostEntry);
|
|
450
|
+
} catch {
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
const door = cliDoor();
|
|
454
|
+
return answer({
|
|
455
|
+
argv,
|
|
456
|
+
cwd: process.cwd(),
|
|
457
|
+
roots: [root],
|
|
458
|
+
integrations: [...hosted.integrations],
|
|
459
|
+
discoverSources: [...hosted.discoverSources],
|
|
460
|
+
...(door ? {cliCommand: door} : {}),
|
|
461
|
+
...(declinedProjectCli ? {declinedProjectCli} : {}),
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
298
465
|
/**
|
|
299
466
|
* Run `bin` as this run and end with its exit status.
|
|
300
467
|
* @param {string} bin
|
|
@@ -91,24 +91,71 @@ export function globalBehind({ self, stateDir }: {
|
|
|
91
91
|
};
|
|
92
92
|
stateDir?: string;
|
|
93
93
|
}): GlobalBehind | null;
|
|
94
|
+
/**
|
|
95
|
+
* The command that adds a package to the project of a run in `cwd`, with the
|
|
96
|
+
* project's package manager (spec AST-081 FR12). Null when `cwd` belongs to
|
|
97
|
+
* no project `spec:AST-040` FR9 defines, and in a folder inside the project
|
|
98
|
+
* whose package.json is not the project's (see {@link installFolder}): a run
|
|
99
|
+
* there loads integrations from that package.json, so a package added to the
|
|
100
|
+
* project would stay unused there, and the advice is
|
|
101
|
+
* {@link RUN_FROM_PROJECT}.
|
|
102
|
+
* @param {string} cwd
|
|
103
|
+
* @returns {((name: string) => string) | null}
|
|
104
|
+
*/
|
|
105
|
+
export function projectAddCommand(cwd: string): ((name: string) => string) | null;
|
|
94
106
|
/**
|
|
95
107
|
* The commands that bring a project's own CLI and Core to one release, with
|
|
96
108
|
* the project's package manager: when the CLI is newer, Core up to it and then
|
|
97
109
|
* the codemods from Core's release; otherwise the CLI to Core's release.
|
|
110
|
+
* Null in a folder that belongs to no project, or whose package.json is not
|
|
111
|
+
* the project's (see {@link installFolder}).
|
|
98
112
|
* @param {{cwd: string, cli: string, core: string}} options
|
|
99
|
-
* @returns {string}
|
|
113
|
+
* @returns {string | null}
|
|
100
114
|
*/
|
|
101
115
|
export function alignCliAndCore({ cwd, cli, core }: {
|
|
102
116
|
cwd: string;
|
|
103
117
|
cli: string;
|
|
104
118
|
core: string;
|
|
105
|
-
}): string;
|
|
119
|
+
}): string | null;
|
|
120
|
+
/**
|
|
121
|
+
* Where a command that adds an Astryx package runs, for a run in `cwd`: in
|
|
122
|
+
* the project `spec:AST-040` FR9 defines, which stops at a repository root
|
|
123
|
+
* and never counts the home folder (spec AST-081 FR2, FR10). Null when `cwd`
|
|
124
|
+
* belongs to no such project, so no command adds anything. When `cwd`'s
|
|
125
|
+
* nearest package.json is not the project's, as in a tool folder that
|
|
126
|
+
* installs its own Core, a package manager would add to the tool's
|
|
127
|
+
* package.json, so `moved` says the command runs in the project's folder.
|
|
128
|
+
* @param {string} cwd
|
|
129
|
+
* @returns {{dir: string, moved: boolean} | null}
|
|
130
|
+
*/
|
|
131
|
+
export function installFolder(cwd: string): {
|
|
132
|
+
dir: string;
|
|
133
|
+
moved: boolean;
|
|
134
|
+
} | null;
|
|
135
|
+
/**
|
|
136
|
+
* The command that adds the CLI at Core's version, for a run in `cwd` whose
|
|
137
|
+
* Core is `core`, with the project's package manager in the project root.
|
|
138
|
+
* `command` is null in a folder inside the project whose package.json is not
|
|
139
|
+
* the project's (see {@link installFolder}), where the advice is
|
|
140
|
+
* {@link RUN_FROM_PROJECT}. Null when the folder belongs to no project.
|
|
141
|
+
* @param {{cwd: string, core: string}} options
|
|
142
|
+
* @returns {{root: string, core: string, command: string | null} | null}
|
|
143
|
+
*/
|
|
144
|
+
export function cliInstallAdvice({ cwd, core }: {
|
|
145
|
+
cwd: string;
|
|
146
|
+
core: string;
|
|
147
|
+
}): {
|
|
148
|
+
root: string;
|
|
149
|
+
core: string;
|
|
150
|
+
command: string | null;
|
|
151
|
+
} | null;
|
|
106
152
|
/**
|
|
107
153
|
* The hint for a project with no CLI of its own, answered by `answered` while
|
|
108
154
|
* its Core is `core`: the command that adds the CLI at Core's version, with
|
|
109
|
-
* the project's package manager.
|
|
155
|
+
* the project's package manager (see {@link cliInstallAdvice}). Null when no
|
|
156
|
+
* command fits, or when the project the command adds to already matches.
|
|
110
157
|
* @param {{cwd: string, answered: string, core: string}} options
|
|
111
|
-
* @returns {{root: string, line: string}}
|
|
158
|
+
* @returns {{root: string, line: string} | null}
|
|
112
159
|
*/
|
|
113
160
|
export function noCliHint({ cwd, answered, core }: {
|
|
114
161
|
cwd: string;
|
|
@@ -117,15 +164,16 @@ export function noCliHint({ cwd, answered, core }: {
|
|
|
117
164
|
}): {
|
|
118
165
|
root: string;
|
|
119
166
|
line: string;
|
|
120
|
-
};
|
|
167
|
+
} | null;
|
|
121
168
|
/**
|
|
122
169
|
* The hint's text.
|
|
123
170
|
* @param {string} answered
|
|
124
171
|
* @param {string} core
|
|
125
|
-
* @param {string} command the command that adds the CLI at Core's
|
|
172
|
+
* @param {string | null} command the command that adds the CLI at Core's
|
|
173
|
+
* version; null in a folder whose package.json is not the project's
|
|
126
174
|
* @returns {string}
|
|
127
175
|
*/
|
|
128
|
-
export function noCliHintLine(answered: string, core: string, command: string): string;
|
|
176
|
+
export function noCliHintLine(answered: string, core: string, command: string | null): string;
|
|
129
177
|
/**
|
|
130
178
|
* The command that installs the CLI at `version` in the project at `root`,
|
|
131
179
|
* with its package manager.
|
|
@@ -140,7 +188,7 @@ export function addCliCommand(root: string, version: string): string;
|
|
|
140
188
|
* @param {{cwd: string, current: string, stateDir?: string}} options
|
|
141
189
|
* @returns {ProjectLag | null}
|
|
142
190
|
*/
|
|
143
|
-
export function projectLag({ cwd, current, stateDir }: {
|
|
191
|
+
export function projectLag({ cwd, current: given, stateDir }: {
|
|
144
192
|
cwd: string;
|
|
145
193
|
current: string;
|
|
146
194
|
stateDir?: string;
|
|
@@ -207,6 +255,12 @@ export function noticeLines({ cwd, self, choice, json, stateDir, cacheDir, now,
|
|
|
207
255
|
}): string[];
|
|
208
256
|
/** A notice prints at most once in this long. */
|
|
209
257
|
export const NOTICE_INTERVAL_MS: number;
|
|
258
|
+
/**
|
|
259
|
+
* What to tell a run in a folder inside a project whose package.json is not
|
|
260
|
+
* the project's: run from the project's folder, since adding there would make
|
|
261
|
+
* the folder a project of its own (spec AST-081 FR2).
|
|
262
|
+
*/
|
|
263
|
+
export const RUN_FROM_PROJECT: "Run this from the Astryx project's folder, or declare an Astryx package in this folder's package.json to make it a project of its own.";
|
|
210
264
|
export type GlobalBehind = {
|
|
211
265
|
/**
|
|
212
266
|
* the global copy's version
|