@vltpkg/cli-sdk 1.0.0-rc.23 → 1.0.0-rc.24

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.
Files changed (103) hide show
  1. package/dist/commands/bugs.d.ts +17 -0
  2. package/dist/commands/bugs.js +163 -0
  3. package/dist/commands/build.d.ts +24 -0
  4. package/dist/commands/build.js +101 -0
  5. package/dist/commands/cache.d.ts +64 -0
  6. package/dist/commands/cache.js +256 -0
  7. package/dist/commands/ci.d.ts +10 -0
  8. package/dist/commands/ci.js +40 -0
  9. package/dist/commands/config.d.ts +5 -0
  10. package/dist/commands/config.js +429 -0
  11. package/dist/commands/create.d.ts +8 -0
  12. package/dist/commands/create.js +102 -0
  13. package/dist/commands/docs.d.ts +17 -0
  14. package/dist/commands/docs.js +153 -0
  15. package/dist/commands/exec-cache.d.ts +48 -0
  16. package/dist/commands/exec-cache.js +145 -0
  17. package/dist/commands/exec-local.d.ts +5 -0
  18. package/dist/commands/exec-local.js +46 -0
  19. package/dist/commands/exec.d.ts +8 -0
  20. package/dist/commands/exec.js +161 -0
  21. package/dist/commands/help.d.ts +3 -0
  22. package/dist/commands/help.js +43 -0
  23. package/dist/commands/init.d.ts +7 -0
  24. package/dist/commands/init.js +116 -0
  25. package/dist/commands/install/reporter.d.ts +10 -0
  26. package/dist/commands/install/reporter.js +93 -0
  27. package/dist/commands/install.d.ts +27 -0
  28. package/dist/commands/install.js +80 -0
  29. package/dist/commands/list.d.ts +17 -0
  30. package/dist/commands/list.js +197 -0
  31. package/dist/commands/login.d.ts +3 -0
  32. package/dist/commands/login.js +22 -0
  33. package/dist/commands/logout.d.ts +3 -0
  34. package/dist/commands/logout.js +22 -0
  35. package/dist/commands/pack.d.ts +31 -0
  36. package/dist/commands/pack.js +205 -0
  37. package/dist/commands/ping.d.ts +17 -0
  38. package/dist/commands/ping.js +114 -0
  39. package/dist/commands/pkg.d.ts +6 -0
  40. package/dist/commands/pkg.js +232 -0
  41. package/dist/commands/publish.d.ts +21 -0
  42. package/dist/commands/publish.js +282 -0
  43. package/dist/commands/query.d.ts +18 -0
  44. package/dist/commands/query.js +216 -0
  45. package/dist/commands/repo.d.ts +17 -0
  46. package/dist/commands/repo.js +157 -0
  47. package/dist/commands/run-exec.d.ts +5 -0
  48. package/dist/commands/run-exec.js +40 -0
  49. package/dist/commands/run.d.ts +5 -0
  50. package/dist/commands/run.js +62 -0
  51. package/dist/commands/token.d.ts +3 -0
  52. package/dist/commands/token.js +39 -0
  53. package/dist/commands/uninstall.d.ts +15 -0
  54. package/dist/commands/uninstall.js +39 -0
  55. package/dist/commands/update.d.ts +13 -0
  56. package/dist/commands/update.js +46 -0
  57. package/dist/commands/version.d.ts +25 -0
  58. package/dist/commands/version.js +252 -0
  59. package/dist/commands/view.d.ts +22 -0
  60. package/dist/commands/view.js +334 -0
  61. package/dist/commands/whoami.d.ts +12 -0
  62. package/dist/commands/whoami.js +28 -0
  63. package/dist/config/definition.d.ts +407 -0
  64. package/dist/config/definition.js +684 -0
  65. package/dist/config/index.d.ts +218 -0
  66. package/dist/config/index.js +488 -0
  67. package/dist/config/merge.d.ts +3 -0
  68. package/dist/config/merge.js +27 -0
  69. package/dist/config/usage.d.ts +18 -0
  70. package/dist/config/usage.js +39 -0
  71. package/dist/custom-help.d.ts +8 -0
  72. package/dist/custom-help.js +419 -0
  73. package/dist/exec-command.d.ts +52 -0
  74. package/dist/exec-command.js +313 -0
  75. package/dist/index.d.ts +3 -0
  76. package/dist/index.js +72 -0
  77. package/dist/load-command.d.ts +15 -0
  78. package/dist/load-command.js +20 -0
  79. package/dist/mermaid-image-view.d.ts +18 -0
  80. package/dist/mermaid-image-view.js +36 -0
  81. package/dist/output.d.ts +20 -0
  82. package/dist/output.js +125 -0
  83. package/dist/pack-tarball.d.ts +23 -0
  84. package/dist/pack-tarball.js +256 -0
  85. package/dist/parse-add-remove-args.d.ts +28 -0
  86. package/dist/parse-add-remove-args.js +103 -0
  87. package/dist/print-err.d.ts +13 -0
  88. package/dist/print-err.js +193 -0
  89. package/dist/query-diff-files.d.ts +17 -0
  90. package/dist/query-diff-files.js +63 -0
  91. package/dist/query-host-contexts.d.ts +15 -0
  92. package/dist/query-host-contexts.js +136 -0
  93. package/dist/read-password.d.ts +7 -0
  94. package/dist/read-password.js +32 -0
  95. package/dist/read-project-folders.d.ts +17 -0
  96. package/dist/read-project-folders.js +100 -0
  97. package/dist/reload-config.d.ts +2 -0
  98. package/dist/reload-config.js +11 -0
  99. package/dist/render-mermaid.d.ts +22 -0
  100. package/dist/render-mermaid.js +68 -0
  101. package/dist/view.d.ts +29 -0
  102. package/dist/view.js +30 -0
  103. package/package.json +25 -25
@@ -0,0 +1,153 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { PackageInfoClient } from '@vltpkg/package-info';
3
+ import { Spec } from '@vltpkg/spec';
4
+ import { urlOpen } from '@vltpkg/url-open';
5
+ import { actual } from '@vltpkg/graph';
6
+ import { Query } from '@vltpkg/query';
7
+ import { SecurityArchive } from '@vltpkg/security-archive';
8
+ import { createHostContextsMap } from "../query-host-contexts.js";
9
+ import { commandUsage } from "../config/usage.js";
10
+ import hostedGitInfo from 'hosted-git-info';
11
+ const { fromUrl: hostedGitInfoFromUrl } = hostedGitInfo;
12
+ export const usage = () => commandUsage({
13
+ command: 'docs',
14
+ usage: ['[<spec>]', '[--target=<query>]'],
15
+ description: `Open documentation for a package in a web browser.
16
+ Reads repository information from package.json or fetches
17
+ manifest data for the specified package.`,
18
+ options: {
19
+ target: {
20
+ value: '<query>',
21
+ description: 'Query selector to filter packages using DSS syntax.',
22
+ },
23
+ },
24
+ examples: {
25
+ '': {
26
+ description: 'Open docs for the current package (reads local package.json)',
27
+ },
28
+ 'abbrev@2.0.0': {
29
+ description: 'Open docs for a specific package version',
30
+ },
31
+ '--target=":root > *"': {
32
+ description: 'List documentation URLs for all direct dependencies',
33
+ },
34
+ },
35
+ });
36
+ export const views = {
37
+ human: r => {
38
+ if (Array.isArray(r)) {
39
+ let msg = 'Multiple package docs found:\n';
40
+ msg += r.map(item => `• ${item.name}: ${item.url}`).join('\n');
41
+ return msg;
42
+ }
43
+ return '';
44
+ },
45
+ json: r => r,
46
+ };
47
+ const getUrlFromManifest = (manifest) => {
48
+ const { name, homepage, repository } = manifest;
49
+ if (!name) {
50
+ throw error('No package name found');
51
+ }
52
+ // Extract repository URL
53
+ let url;
54
+ if (homepage) {
55
+ url = homepage;
56
+ }
57
+ else if (repository) {
58
+ const repoUrl = typeof repository === 'string' ? repository
59
+ : typeof repository === 'object' && 'url' in repository ?
60
+ repository.url
61
+ : /* c8 ignore next */ undefined;
62
+ if (repoUrl) {
63
+ // Try to get hosted git info
64
+ const info = hostedGitInfoFromUrl(repoUrl.replace(/^git\+/, ''));
65
+ if (info?.docs && typeof info.docs === 'function') {
66
+ url = info.docs();
67
+ }
68
+ }
69
+ }
70
+ // Fallback to vlt.io package page
71
+ if (!url) {
72
+ url = `https://vlt.io/explore/npm/${name}/overview`;
73
+ }
74
+ return url;
75
+ };
76
+ export const command = async (conf) => {
77
+ const { projectRoot, packageJson } = conf.options;
78
+ const targetOption = conf.get('target');
79
+ // Handle --target query
80
+ if (targetOption) {
81
+ const mainManifest = packageJson.maybeRead(projectRoot);
82
+ if (!mainManifest) {
83
+ throw error('No package.json found in project root', {
84
+ path: projectRoot,
85
+ });
86
+ }
87
+ const graph = actual.load({
88
+ ...conf.options,
89
+ mainManifest,
90
+ monorepo: conf.options.monorepo,
91
+ loadManifests: true,
92
+ });
93
+ const securityArchive = Query.hasSecuritySelectors(targetOption) ?
94
+ await SecurityArchive.start({
95
+ nodes: [...graph.nodes.values()],
96
+ })
97
+ : undefined;
98
+ const hostContexts = await createHostContextsMap(conf);
99
+ const query = new Query({
100
+ nodes: new Set(graph.nodes.values()),
101
+ edges: graph.edges,
102
+ importers: graph.importers,
103
+ securityArchive,
104
+ hostContexts,
105
+ });
106
+ const { nodes } = await query.search(targetOption, {
107
+ signal: new AbortController().signal,
108
+ });
109
+ const results = [];
110
+ for (const node of nodes) {
111
+ if (!node.manifest)
112
+ continue;
113
+ const url = getUrlFromManifest(node.manifest);
114
+ results.push({
115
+ url,
116
+ name: node.name /* c8 ignore next */ ?? '(unknown)',
117
+ });
118
+ }
119
+ if (results.length === 0) {
120
+ throw error('No packages found matching target query', {
121
+ found: targetOption,
122
+ });
123
+ }
124
+ // If single result, open it
125
+ if (results.length === 1) {
126
+ const result = results[0];
127
+ /* c8 ignore next 3 */
128
+ if (!result) {
129
+ throw error('Unexpected empty result');
130
+ }
131
+ await urlOpen(result.url);
132
+ return result;
133
+ }
134
+ // Multiple results, return the list
135
+ return results;
136
+ }
137
+ // read the package spec from a positional argument or local package.json
138
+ const specArg = conf.positionals[0];
139
+ const manifest = conf.positionals.length === 0 ? packageJson.read(projectRoot)
140
+ : specArg ?
141
+ await new PackageInfoClient(conf.options).manifest(Spec.parseArgs(specArg, conf.options))
142
+ : /* c8 ignore next */ packageJson.read(projectRoot);
143
+ const url = getUrlFromManifest(manifest);
144
+ const { name } = manifest;
145
+ /* c8 ignore start - getUrlFromManifest already validates name */
146
+ if (!name) {
147
+ throw error('No package name found');
148
+ }
149
+ /* c8 ignore stop */
150
+ // Open the URL
151
+ await urlOpen(url);
152
+ return { url, name };
153
+ };
@@ -0,0 +1,48 @@
1
+ import type { VlxInfo } from '@vltpkg/vlx';
2
+ import type { LoadedConfig } from '../config/index.ts';
3
+ import type { CommandFn, CommandUsage } from '../index.ts';
4
+ import type { ViewOptions, Views } from '../view.ts';
5
+ import { ViewClass } from '../view.ts';
6
+ export type ExecCacheSubcommands = keyof (typeof usageDef)['subcommands'];
7
+ export declare class ExecCacheView extends ViewClass {
8
+ constructor(options: ViewOptions, conf: LoadedConfig);
9
+ stdout(...args: unknown[]): void;
10
+ }
11
+ export declare const views: Views<void | string[] | VlxInfo[]>;
12
+ declare const usageDef: {
13
+ readonly command: "exec-cache";
14
+ readonly usage: "<command> [flags]";
15
+ readonly description: "Work with vlt exec-cache folders";
16
+ readonly subcommands: {
17
+ readonly ls: {
18
+ readonly usage: "";
19
+ readonly description: "Show previously installed packages used for `vlt exec`.\n Key provided can be either the package name, or the full\n key.";
20
+ };
21
+ readonly delete: {
22
+ readonly usage: "[<key>...]";
23
+ readonly description: "Delete previously installed packages used for\n `vlt exec`. If no keys are provided, then all entries\n will be deleted.";
24
+ };
25
+ readonly info: {
26
+ readonly usage: "<key>";
27
+ readonly description: "Show extended information about a given `vlt exec`\n installation.";
28
+ };
29
+ readonly install: {
30
+ readonly usage: "<spec>...";
31
+ readonly description: "Install the specified package(s) in the `vlt exec`\n central cache location. Metadata info about each\n installation will be printed.";
32
+ };
33
+ };
34
+ readonly examples: {
35
+ readonly ls: {
36
+ readonly description: "Show all the keys for the installations in the `vlt exec`\n cache.";
37
+ };
38
+ readonly 'delete typescript': {
39
+ readonly description: "Delete all versions of typescript installed for vlt exec";
40
+ };
41
+ readonly 'info typescript-695bf962': {
42
+ readonly description: "Show extended info about a specific version of typescript";
43
+ };
44
+ };
45
+ };
46
+ export declare const usage: CommandUsage;
47
+ export declare const command: CommandFn<string[] | VlxInfo[]>;
48
+ export {};
@@ -0,0 +1,145 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { RollbackRemove } from '@vltpkg/rollback-remove';
3
+ import * as vlx from '@vltpkg/vlx';
4
+ import { basename } from 'node:path';
5
+ import { commandUsage } from "../config/usage.js";
6
+ import { stdout } from "../output.js";
7
+ import { ViewClass } from "../view.js";
8
+ let view;
9
+ export class ExecCacheView extends ViewClass {
10
+ constructor(options, conf) {
11
+ super(options, conf);
12
+ view = this;
13
+ }
14
+ stdout(...args) {
15
+ stdout(...args);
16
+ }
17
+ }
18
+ export const views = {
19
+ human: ExecCacheView,
20
+ };
21
+ const usageDef = {
22
+ command: 'exec-cache',
23
+ usage: '<command> [flags]',
24
+ description: 'Work with vlt exec-cache folders',
25
+ subcommands: {
26
+ ls: {
27
+ usage: '',
28
+ description: `Show previously installed packages used for \`vlt exec\`.
29
+ Key provided can be either the package name, or the full
30
+ key.`,
31
+ },
32
+ delete: {
33
+ usage: '[<key>...]',
34
+ description: `Delete previously installed packages used for
35
+ \`vlt exec\`. If no keys are provided, then all entries
36
+ will be deleted.`,
37
+ },
38
+ info: {
39
+ usage: '<key>',
40
+ description: `Show extended information about a given \`vlt exec\`
41
+ installation.`,
42
+ },
43
+ install: {
44
+ usage: '<spec>...',
45
+ description: `Install the specified package(s) in the \`vlt exec\`
46
+ central cache location. Metadata info about each
47
+ installation will be printed.`,
48
+ },
49
+ },
50
+ examples: {
51
+ ls: {
52
+ description: `Show all the keys for the installations in the \`vlt exec\`
53
+ cache.`,
54
+ },
55
+ 'delete typescript': {
56
+ description: `Delete all versions of typescript installed for vlt exec`,
57
+ },
58
+ 'info typescript-695bf962': {
59
+ description: `Show extended info about a specific version of typescript`,
60
+ },
61
+ },
62
+ };
63
+ export const usage = () => commandUsage(usageDef);
64
+ export const command = async (conf) => {
65
+ const [sub, ...args] = conf.positionals;
66
+ switch (sub) {
67
+ case 'ls':
68
+ return ls(conf, args, view);
69
+ case 'info':
70
+ return info(conf, args, view);
71
+ case 'install':
72
+ return install(conf, args, view);
73
+ case 'delete':
74
+ return deleteEntries(conf, args, view);
75
+ default: {
76
+ throw error('Unrecognized exec-cache command', {
77
+ code: 'EUSAGE',
78
+ found: sub,
79
+ validOptions: Object.keys(usageDef.subcommands),
80
+ });
81
+ }
82
+ }
83
+ };
84
+ const install = async (conf, keys, view) => {
85
+ if (!keys.length) {
86
+ throw error('Must supply a package spec to install', {
87
+ code: 'EUSAGE',
88
+ });
89
+ }
90
+ const allowScripts = conf.get('allow-scripts') ?
91
+ String(conf.get('allow-scripts'))
92
+ : ':not(*)';
93
+ return Promise.all(keys.map(async (key) => {
94
+ const info = await vlx.install(key, {
95
+ ...conf.options,
96
+ query: undefined,
97
+ allowScripts,
98
+ });
99
+ view?.stdout(info);
100
+ return info.path;
101
+ }));
102
+ };
103
+ const ls = async (_conf, args, view) => {
104
+ const results = [];
105
+ for await (const path of vlx.list()) {
106
+ const key = basename(path);
107
+ if (args.length && !args.some(a => key.includes(a)))
108
+ continue;
109
+ results.push(key);
110
+ view?.stdout(key);
111
+ }
112
+ return results;
113
+ };
114
+ const info = async (conf, keys, view) => {
115
+ const allowScripts = conf.get('allow-scripts') ?
116
+ String(conf.get('allow-scripts'))
117
+ : ':not(*)';
118
+ const results = [];
119
+ for await (const key of keys.length ? keys : vlx.list()) {
120
+ const info = vlx.info(key, {
121
+ ...conf.options,
122
+ query: undefined,
123
+ allowScripts,
124
+ });
125
+ results.push(info);
126
+ view?.stdout(info);
127
+ }
128
+ return results;
129
+ };
130
+ const deleteEntries = async (conf, keys, view) => {
131
+ const allowScripts = conf.get('allow-scripts') ?
132
+ String(conf.get('allow-scripts'))
133
+ : ':not(*)';
134
+ const remover = new RollbackRemove();
135
+ const removed = (await vlx.delete(keys, remover, {
136
+ ...conf.options,
137
+ query: undefined,
138
+ allowScripts,
139
+ })).map(path => {
140
+ view?.stdout(`- ${basename(path)}`);
141
+ return path;
142
+ });
143
+ remover.confirm();
144
+ return removed;
145
+ };
@@ -0,0 +1,5 @@
1
+ import type { ExecResult } from '../exec-command.ts';
2
+ import type { CommandFn, CommandUsage } from '../index.ts';
3
+ export { views } from '../exec-command.ts';
4
+ export declare const usage: CommandUsage;
5
+ export declare const command: CommandFn<ExecResult>;
@@ -0,0 +1,46 @@
1
+ import { exec, execFG } from '@vltpkg/run';
2
+ import { commandUsage } from "../config/usage.js";
3
+ import { ExecCommand } from "../exec-command.js";
4
+ export { views } from "../exec-command.js";
5
+ export const usage = () => commandUsage({
6
+ command: 'exec-local',
7
+ usage: '[command]',
8
+ description: `Run an arbitrary command, with the local installed packages
9
+ first in the PATH. Ie, this will run your locally installed
10
+ package bins.
11
+
12
+ If no command is provided, then a shell is spawned in the
13
+ current working directory, with the locally installed package
14
+ bins first in the PATH.
15
+
16
+ Note that any vlt configs must be specified *before* the
17
+ command, as the remainder of the command line options are
18
+ provided to the exec process.`,
19
+ options: {
20
+ scope: {
21
+ value: '<query>',
22
+ description: 'Filter execution targets using a DSS query.',
23
+ },
24
+ workspace: {
25
+ value: '<path|glob>',
26
+ description: 'Limit execution to matching workspace paths or globs.',
27
+ },
28
+ 'workspace-group': {
29
+ value: '<name>',
30
+ description: 'Limit execution to named workspace groups.',
31
+ },
32
+ recursive: {
33
+ description: 'Run across all selected workspaces.',
34
+ },
35
+ 'if-present': {
36
+ description: 'When running across multiple packages, only include packages with matching scripts.',
37
+ },
38
+ bail: {
39
+ description: 'When running across multiple workspaces, stop on first failure.',
40
+ },
41
+ },
42
+ });
43
+ export const command = async (conf) => {
44
+ delete conf.options['script-shell'];
45
+ return await new ExecCommand(conf, exec, execFG).run();
46
+ };
@@ -0,0 +1,8 @@
1
+ import type { PromptFn } from '@vltpkg/vlx';
2
+ import type { ExecResult } from '../exec-command.ts';
3
+ import type { CommandFn, CommandUsage } from '../index.ts';
4
+ export { views } from '../exec-command.ts';
5
+ export declare const usage: CommandUsage;
6
+ export declare const prettyPath: (path: string) => string;
7
+ export declare const promptFn: PromptFn;
8
+ export declare const command: CommandFn<ExecResult>;
@@ -0,0 +1,161 @@
1
+ import { exec, execFG } from '@vltpkg/run';
2
+ import * as vlx from '@vltpkg/vlx';
3
+ import { homedir } from 'node:os';
4
+ import { env, platform } from 'node:process';
5
+ import { createInterface } from 'node:readline/promises';
6
+ import { commandUsage } from "../config/usage.js";
7
+ import { ExecCommand } from "../exec-command.js";
8
+ import { styleTextStdout } from "../output.js";
9
+ export { views } from "../exec-command.js";
10
+ export const usage = () => commandUsage({
11
+ command: 'exec',
12
+ usage: '[--package=<pkg>] [--call=<cmd>] [command...]',
13
+ description: `Run a command defined by a package, installing it
14
+ if necessary.
15
+
16
+ If the package specifier is provided explicitly via the
17
+ \`--package\` config, then that is what will be used. If
18
+ a satisfying instance of the named package exists in the
19
+ local \`node_modules\` folder, then that will be used.
20
+
21
+ If \`--package\` is not set, then vlt will attempt to infer
22
+ the package to be installed if necessary, in the following
23
+ manner:
24
+
25
+ - If the first argument is an executable found in the
26
+ \`node_modules/.bin\` folder (ie, provided by an
27
+ installed direct dependency), then that will be used.
28
+ The search stops, and nothing will be installed.
29
+ - Otherwise, vlt attempts to resolve the first argument
30
+ as if it was a \`--package\` option, and then swap it
31
+ out with the "default" executable provided by that
32
+ package.
33
+
34
+ The "default" executable provided by a package is:
35
+
36
+ - If the package provides a single executable string in the
37
+ \`bin\` field, then that is the executable to use.
38
+ - Otherwise, if there is a \`bin\` with the same name
39
+ as the package (or just the portion after the \`/\` in
40
+ the case of scoped packages), then that will be used.
41
+
42
+ If the appropriate excutable cannot be determined, then
43
+ an error will be raised.
44
+
45
+ At no point will \`vlt exec\` change the locally installed
46
+ dependencies. Any installs it performs is done in vlt's XDG
47
+ data directory.
48
+ `,
49
+ examples: {
50
+ '--package typescript@5 tsc': {
51
+ description: 'Run tsc provided by typescript version 5',
52
+ },
53
+ 'eslint src/file.js': {
54
+ description: 'Run the default bin provided by eslint',
55
+ },
56
+ 'eslint@9.24 src/file.js': {
57
+ description: 'Run the default bin provided by eslint version 9.24',
58
+ },
59
+ 'create-react-app --call="echo $PWD"': {
60
+ description: 'Install create-react-app and run an arbitrary command with its bins in PATH',
61
+ },
62
+ '--call="echo $PWD" --scope=":workspace"': {
63
+ description: 'Run an arbitrary command in the context of each workspace',
64
+ },
65
+ },
66
+ options: {
67
+ package: {
68
+ value: '<specifier>',
69
+ description: 'Explicitly set the package to search for bins.',
70
+ },
71
+ call: {
72
+ value: '<cmd>',
73
+ description: 'Run an arbitrary command string after installing any specified package and adding its bins to PATH.',
74
+ },
75
+ 'allow-scripts': {
76
+ value: '<query>',
77
+ description: 'Filter which packages are allowed to run lifecycle scripts using DSS query syntax.',
78
+ },
79
+ scope: {
80
+ value: '<query>',
81
+ description: 'Filter execution targets using a DSS query.',
82
+ },
83
+ workspace: {
84
+ value: '<path|glob>',
85
+ description: 'Limit execution to matching workspace paths or globs.',
86
+ },
87
+ 'workspace-group': {
88
+ value: '<name>',
89
+ description: 'Limit execution to named workspace groups.',
90
+ },
91
+ recursive: {
92
+ description: 'Run across all selected workspaces.',
93
+ },
94
+ 'if-present': {
95
+ description: 'When running across multiple packages, only include packages with matching scripts.',
96
+ },
97
+ bail: {
98
+ description: 'When running across multiple workspaces, stop on first failure.',
99
+ },
100
+ 'script-shell': {
101
+ value: '<shell>',
102
+ description: 'The shell to use for --call commands and script execution.',
103
+ },
104
+ },
105
+ });
106
+ const HOME = homedir();
107
+ export const prettyPath = (path) => path.startsWith(HOME) ? `~${path.substring(HOME.length)}` : path;
108
+ export const promptFn = async (pkgSpec, path, resolution) => {
109
+ const response = await createInterface(process.stdin, process.stdout).question(`About to install: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], String(pkgSpec))}
110
+ from: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], resolution)}
111
+ into: ${styleTextStdout(['bgWhiteBright', 'black', 'bold'], prettyPath(path))}
112
+ Is this ok? (y) `);
113
+ process.stdin.pause();
114
+ return response;
115
+ };
116
+ export const command = async (conf) => {
117
+ /* c8 ignore start */
118
+ const allowScripts = conf.get('allow-scripts') ?
119
+ String(conf.get('allow-scripts'))
120
+ : ':not(*)';
121
+ /* c8 ignore stop */
122
+ const callOption = conf.get('call');
123
+ if (callOption) {
124
+ // Install any specified package and add its bins to PATH, but don't
125
+ // use its default executable - the --call string is the command to run.
126
+ // Only install when a package is explicitly defined (via --package flag
127
+ // or as a positional argument). Don't prompt for confirmation since the
128
+ // user's explicit --call command implies consent.
129
+ const pkgOption = conf.get('package') ?? conf.positionals[0];
130
+ if (pkgOption) {
131
+ await vlx.resolve([], {
132
+ ...conf.options,
133
+ package: pkgOption,
134
+ query: undefined,
135
+ allowScripts,
136
+ });
137
+ }
138
+ // Determine the shell to use for the --call command
139
+ const shell = conf.get('script-shell') ??
140
+ env.SHELL ??
141
+ /* c8 ignore next */
142
+ (platform === 'win32' ? 'cmd.exe' : '/bin/sh');
143
+ // cmd.exe uses '/c', all other shells use '-c'
144
+ /* c8 ignore next */
145
+ const shellFlag = shell === 'cmd.exe' ? '/c' : '-c';
146
+ // Replace positionals with [shell, shellFlag, callOption]
147
+ conf.positionals.splice(0, conf.positionals.length, shell, shellFlag, callOption);
148
+ }
149
+ else {
150
+ const arg0 = await vlx.resolve(conf.positionals, {
151
+ ...conf.options,
152
+ query: undefined,
153
+ allowScripts,
154
+ }, promptFn);
155
+ if (arg0)
156
+ conf.positionals[0] = arg0;
157
+ }
158
+ // now we have arg0! let's gooooo!!
159
+ delete conf.options['script-shell'];
160
+ return await new ExecCommand(conf, exec, execFG).run();
161
+ };
@@ -0,0 +1,3 @@
1
+ import type { CommandFn, CommandUsage } from '../load-command.ts';
2
+ export declare const usage: CommandUsage;
3
+ export declare const command: CommandFn<string>;
@@ -0,0 +1,43 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { commandUsage } from "../config/usage.js";
3
+ import { loadCommand } from "../load-command.js";
4
+ import { getCommand } from "../config/definition.js";
5
+ import { generateDefaultHelp, generateFullHelp, } from "../custom-help.js";
6
+ export const usage = () => commandUsage({
7
+ command: 'help',
8
+ usage: '[<command>]',
9
+ description: 'Print the full help output for the CLI, or help for a specific command',
10
+ examples: {
11
+ '': { description: 'Show general CLI help' },
12
+ install: { description: 'Show help for the install command' },
13
+ run: { description: 'Show help for the run command' },
14
+ },
15
+ options: {
16
+ all: {
17
+ description: 'Show all commands, bins, and flags.',
18
+ },
19
+ },
20
+ });
21
+ export const command = async (conf) => {
22
+ // If no positional arguments, show general help
23
+ if (conf.positionals.length === 0) {
24
+ // Check for color support (prefer explicit config, fall back to TTY detection)
25
+ const colors = conf.values.color ?? process.stdout.isTTY;
26
+ // Use full custom help if --all flag is set
27
+ if (conf.values.all) {
28
+ return generateFullHelp(colors);
29
+ }
30
+ return generateDefaultHelp(colors);
31
+ }
32
+ // Get the command name from the first positional argument
33
+ const cmdName = conf.positionals[0];
34
+ const canonicalCmd = getCommand(cmdName);
35
+ if (!canonicalCmd) {
36
+ throw error(`Unknown command: ${cmdName}`, {
37
+ found: cmdName,
38
+ code: 'EUSAGE',
39
+ });
40
+ }
41
+ const command = await loadCommand(canonicalCmd);
42
+ return command.usage().usage();
43
+ };
@@ -0,0 +1,7 @@
1
+ import type { InitFileResults } from '@vltpkg/init';
2
+ import type { CommandFn, CommandUsage } from '../index.ts';
3
+ export declare const usage: CommandUsage;
4
+ export declare const views: {
5
+ readonly human: (results: InitFileResults | InitFileResults[]) => string;
6
+ };
7
+ export declare const command: CommandFn<InitFileResults | InitFileResults[]>;