@vltpkg/cli-sdk 1.3.8 → 1.5.0
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/dist/allow-skills.d.ts +36 -0
- package/dist/allow-skills.js +49 -0
- package/dist/commands/build.d.ts +7 -1
- package/dist/commands/build.js +19 -9
- package/dist/commands/cache.d.ts +2 -2
- package/dist/commands/cache.js +22 -7
- package/dist/commands/ci.d.ts +1 -1
- package/dist/commands/ci.js +10 -2
- package/dist/commands/init.js +7 -8
- package/dist/commands/install/reporter.js +46 -0
- package/dist/commands/install.d.ts +29 -1
- package/dist/commands/install.js +35 -1
- package/dist/commands/list.js +3 -1
- package/dist/commands/pack.js +2 -1
- package/dist/commands/pkg.js +4 -1
- package/dist/commands/publish.d.ts +0 -1
- package/dist/commands/publish.js +31 -17
- package/dist/commands/query.js +3 -1
- package/dist/commands/skills.d.ts +56 -0
- package/dist/commands/skills.js +268 -0
- package/dist/commands/uninstall.d.ts +5 -1
- package/dist/commands/uninstall.js +4 -2
- package/dist/commands/unpublish.d.ts +0 -1
- package/dist/commands/unpublish.js +17 -4
- package/dist/commands/update.d.ts +12 -0
- package/dist/commands/update.js +18 -1
- package/dist/commands/version.js +4 -1
- package/dist/config/definition.d.ts +26 -2
- package/dist/config/definition.js +75 -11
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +22 -6
- package/dist/config/spec-aliases.d.ts +22 -0
- package/dist/config/spec-aliases.js +47 -0
- package/dist/custom-help.js +4 -0
- package/dist/exec-command.js +12 -6
- package/dist/index.js +18 -8
- package/dist/load-command.d.ts +2 -0
- package/dist/migrate-workspaces.d.ts +16 -0
- package/dist/migrate-workspaces.js +44 -0
- package/dist/output.js +2 -1
- package/dist/print-err.js +4 -1
- package/dist/publish-config.d.ts +9 -0
- package/dist/publish-config.js +8 -0
- package/dist/save-types.d.ts +20 -0
- package/dist/save-types.js +105 -0
- package/dist/skills-prompt.d.ts +28 -0
- package/dist/skills-prompt.js +78 -0
- package/dist/sort-scope-locations.d.ts +11 -0
- package/dist/sort-scope-locations.js +57 -0
- package/package.json +28 -28
|
@@ -53,6 +53,7 @@ export declare const commands: {
|
|
|
53
53
|
readonly 'run-exec': "run-exec";
|
|
54
54
|
readonly run: "run";
|
|
55
55
|
readonly setup: "setup";
|
|
56
|
+
readonly skills: "skills";
|
|
56
57
|
readonly token: "token";
|
|
57
58
|
readonly uninstall: "uninstall";
|
|
58
59
|
readonly unpublish: "unpublish";
|
|
@@ -75,7 +76,7 @@ export declare const recordFields: readonly ["git-hosts", "registries", "git-hos
|
|
|
75
76
|
export type RecordField = (typeof recordFields)[number];
|
|
76
77
|
export declare const isRecordField: (s: string) => s is RecordField;
|
|
77
78
|
/** Valid `store-linker` values. */
|
|
78
|
-
export declare const storeLinkers: readonly ["auto", "hardlink", "copy", "unpack"];
|
|
79
|
+
export declare const storeLinkers: readonly ["auto", "hardlink", "clone", "copy", "unpack"];
|
|
79
80
|
export declare const definition: import("jackspeak").Jack<{
|
|
80
81
|
color: {
|
|
81
82
|
short: string;
|
|
@@ -139,7 +140,7 @@ export declare const definition: import("jackspeak").Jack<{
|
|
|
139
140
|
'store-linker': {
|
|
140
141
|
hint: string;
|
|
141
142
|
description: string;
|
|
142
|
-
validOptions: readonly ["auto", "hardlink", "copy", "unpack"];
|
|
143
|
+
validOptions: readonly ["auto", "hardlink", "clone", "copy", "unpack"];
|
|
143
144
|
default: string;
|
|
144
145
|
};
|
|
145
146
|
tag: {
|
|
@@ -365,16 +366,25 @@ export declare const definition: import("jackspeak").Jack<{
|
|
|
365
366
|
short: string;
|
|
366
367
|
description: string;
|
|
367
368
|
};
|
|
369
|
+
'save-types': {
|
|
370
|
+
description: string;
|
|
371
|
+
};
|
|
368
372
|
'save-config': {
|
|
369
373
|
description: string;
|
|
370
374
|
};
|
|
375
|
+
'migrate-workspaces': {
|
|
376
|
+
description: string;
|
|
377
|
+
default: true;
|
|
378
|
+
};
|
|
371
379
|
} & {
|
|
372
380
|
'save-dev': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
373
381
|
'save-exact': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
374
382
|
'save-optional': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
375
383
|
'save-peer': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
376
384
|
'save-prod': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
385
|
+
'save-types': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
377
386
|
'save-config': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
387
|
+
'migrate-workspaces': import("jackspeak").ConfigOption<"boolean", false, undefined>;
|
|
378
388
|
} & {
|
|
379
389
|
'save-prefix': {
|
|
380
390
|
description: string;
|
|
@@ -425,6 +435,20 @@ export declare const definition: import("jackspeak").Jack<{
|
|
|
425
435
|
};
|
|
426
436
|
} & {
|
|
427
437
|
'allow-scripts': import("jackspeak").ConfigOption<"string", false, readonly string[] | undefined>;
|
|
438
|
+
} & {
|
|
439
|
+
'allow-skills': {
|
|
440
|
+
hint: string;
|
|
441
|
+
description: string;
|
|
442
|
+
};
|
|
443
|
+
} & {
|
|
444
|
+
'allow-skills': import("jackspeak").ConfigOption<"string", false, readonly string[] | undefined>;
|
|
445
|
+
} & {
|
|
446
|
+
'skills-dir': {
|
|
447
|
+
hint: string;
|
|
448
|
+
description: string;
|
|
449
|
+
};
|
|
450
|
+
} & {
|
|
451
|
+
'skills-dir': import("jackspeak").ConfigOption<"string", true, readonly string[] | undefined>;
|
|
428
452
|
} & {
|
|
429
453
|
access: {
|
|
430
454
|
description: string;
|
|
@@ -46,6 +46,7 @@ const canonicalCommands = {
|
|
|
46
46
|
'run-exec': 'run-exec',
|
|
47
47
|
run: 'run',
|
|
48
48
|
setup: 'setup',
|
|
49
|
+
skills: 'skills',
|
|
49
50
|
token: 'token',
|
|
50
51
|
uninstall: 'uninstall',
|
|
51
52
|
unpublish: 'unpublish',
|
|
@@ -114,6 +115,7 @@ export const isRecordField = (s) => recordFields.includes(s);
|
|
|
114
115
|
export const storeLinkers = [
|
|
115
116
|
'auto',
|
|
116
117
|
'hardlink',
|
|
118
|
+
'clone',
|
|
117
119
|
'copy',
|
|
118
120
|
'unpack',
|
|
119
121
|
];
|
|
@@ -226,8 +228,11 @@ export const definition = j
|
|
|
226
228
|
|
|
227
229
|
There is **no** built-in \`npm\` registry URL; the \`npm\`
|
|
228
230
|
alias must be configured (e.g. via \`vlt setup\`) before it
|
|
229
|
-
can be used. The \`gh\`
|
|
230
|
-
|
|
231
|
+
can be used. The \`gh\` alias has a built-in default
|
|
232
|
+
that can be overridden here. A name used by
|
|
233
|
+
\`--jsr-registries\` or \`--git-hosts\` (e.g. \`jsr\`,
|
|
234
|
+
\`github\`), or a built-in protocol (e.g. \`file\`), is
|
|
235
|
+
an error.
|
|
231
236
|
|
|
232
237
|
Aliases given on the command line or in
|
|
233
238
|
\`VLT_REGISTRIES\` (newline-delimited) merge with the
|
|
@@ -317,28 +322,35 @@ export const definition = j
|
|
|
317
322
|
default: cacheDir,
|
|
318
323
|
},
|
|
319
324
|
'store-linker': {
|
|
320
|
-
hint: 'auto | hardlink | copy | unpack',
|
|
325
|
+
hint: 'auto | hardlink | clone | copy | unpack',
|
|
321
326
|
description: `How packages are placed in \`node_modules\`. Every
|
|
322
327
|
linker but \`unpack\` fills a global store under
|
|
323
328
|
\`cache\` in the background, then places packages
|
|
324
329
|
from it.
|
|
325
330
|
|
|
326
331
|
- auto: Default. On Linux, hardlink from the global
|
|
327
|
-
store, copying any file that cannot be linked.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
332
|
+
store, copying any file that cannot be linked. On
|
|
333
|
+
macOS, clone from it, on a Node with \`node:ffi\`
|
|
334
|
+
(26.1 and later, and \`--allow-ffi\` under
|
|
335
|
+
\`--permission\`); a hardlink is the slowest way
|
|
336
|
+
to place a file on APFS, so macOS without it, and
|
|
337
|
+
Windows, unpack by default.
|
|
331
338
|
- hardlink: Hardlink from the global store on every
|
|
332
339
|
platform.
|
|
340
|
+
- clone: Clone each package directory from the
|
|
341
|
+
global store copy-on-write (\`clonefile\`, macOS
|
|
342
|
+
on APFS). Files share storage with the store
|
|
343
|
+
until edited, so editing in place is safe.
|
|
344
|
+
Unpacks where cloning fails.
|
|
333
345
|
- copy: Copy from the global store. Use this when
|
|
334
346
|
editing files in \`node_modules\` in place, since
|
|
335
347
|
a hardlink shares its content with every project.
|
|
336
348
|
- unpack: Unpack each package tarball, skipping the
|
|
337
349
|
global store.
|
|
338
350
|
|
|
339
|
-
A package is copied right before its
|
|
340
|
-
scripts run, so they don't change its files
|
|
341
|
-
store.
|
|
351
|
+
A hardlinked package is copied right before its
|
|
352
|
+
install scripts run, so they don't change its files
|
|
353
|
+
in the store; a cloned one needs no copy.
|
|
342
354
|
An invalid \`VLT_STORE_LINKER\` warns and uses
|
|
343
355
|
\`unpack\`.`,
|
|
344
356
|
validOptions: storeLinkers,
|
|
@@ -514,7 +526,9 @@ export const definition = j
|
|
|
514
526
|
config: {
|
|
515
527
|
hint: 'all | user | project',
|
|
516
528
|
description: `Specify which configuration to show or operate on when running
|
|
517
|
-
\`vlt config\` commands
|
|
529
|
+
\`vlt config\` commands, and which file
|
|
530
|
+
\`vlt skills link\` saves \`allow-skills\` to. For read
|
|
531
|
+
operations (get, pick, list):
|
|
518
532
|
\`all\` shows merged configuration from both user and project
|
|
519
533
|
files (default). For write operations (set, delete, edit):
|
|
520
534
|
defaults to \`project\`. \`user\` shows/modifies only user-level
|
|
@@ -702,6 +716,11 @@ export const definition = j
|
|
|
702
716
|
devDependencies or optionalDependencies, but you want to
|
|
703
717
|
move it to be a non-optional production dependency.`,
|
|
704
718
|
},
|
|
719
|
+
'save-types': {
|
|
720
|
+
description: `Also save the matching \`@types/*\` package as a
|
|
721
|
+
devDependency for each added registry package that
|
|
722
|
+
ships no TypeScript types of its own.`,
|
|
723
|
+
},
|
|
705
724
|
'save-config': {
|
|
706
725
|
description: `Save the registry and git host options given on the
|
|
707
726
|
command line or via \`VLT_*\` env (\`--registry\`,
|
|
@@ -713,6 +732,17 @@ export const definition = j
|
|
|
713
732
|
\`add\` or \`update\`. Values a config file already
|
|
714
733
|
has are left alone.`,
|
|
715
734
|
},
|
|
735
|
+
'migrate-workspaces': {
|
|
736
|
+
description: `Save workspaces read from the \`workspaces\` field of
|
|
737
|
+
the root \`package.json\` or from
|
|
738
|
+
\`pnpm-workspace.yaml\` to the project \`vlt.json\` on
|
|
739
|
+
\`vlt install\`. \`vlt.json\` then takes precedence.
|
|
740
|
+
|
|
741
|
+
Set \`--no-migrate-workspaces\` to skip this; an
|
|
742
|
+
already saved \`workspaces\` field stays until
|
|
743
|
+
removed.`,
|
|
744
|
+
default: true,
|
|
745
|
+
},
|
|
716
746
|
})
|
|
717
747
|
.opt({
|
|
718
748
|
'save-prefix': {
|
|
@@ -780,6 +810,40 @@ export const definition = j
|
|
|
780
810
|
Runs scripts only for direct dependencies of the current project and any occurrences
|
|
781
811
|
of a specific dependency with the name "my-package" anywhere in the dependency graph.`,
|
|
782
812
|
},
|
|
813
|
+
})
|
|
814
|
+
.opt({
|
|
815
|
+
'allow-skills': {
|
|
816
|
+
hint: 'query',
|
|
817
|
+
description: `Link the agent skills (folders with a \`SKILL.md\`) shipped by
|
|
818
|
+
installed packages matching this DSS query into
|
|
819
|
+
the project's agent skill dirs (see \`skills-dir\`)
|
|
820
|
+
after \`install\`, \`ci\`, \`update\` or
|
|
821
|
+
\`uninstall\`. End a selector with
|
|
822
|
+
\`:skill(<name>, …)\` to pick single skills (\`*\`
|
|
823
|
+
globs, double-quoted names). Unset (the default) or
|
|
824
|
+
\`:not(*)\` links nothing and skips all skills work.
|
|
825
|
+
|
|
826
|
+
\`vlt install --allow-skills=<query>\` saves the query
|
|
827
|
+
to the project \`vlt.json\`; \`vlt skills link
|
|
828
|
+
[<query>]\` sets, saves and applies it.
|
|
829
|
+
|
|
830
|
+
Example: --allow-skills="#agent-browser:skill(agent-browser)"
|
|
831
|
+
Links the agent-browser skill from a package with the same name.`,
|
|
832
|
+
},
|
|
833
|
+
})
|
|
834
|
+
.optList({
|
|
835
|
+
'skills-dir': {
|
|
836
|
+
hint: 'path',
|
|
837
|
+
description: `Dirs to link agent skills into (see \`allow-skills\`),
|
|
838
|
+
relative to the project root. Replaces detection:
|
|
839
|
+
\`.agents/skills\`, plus \`<folder>/skills\` for each
|
|
840
|
+
agent folder at the project root (e.g. \`.claude/\`),
|
|
841
|
+
\`.claude/skills\` inside Claude Code, and existing
|
|
842
|
+
\`.<name>/skills\` dirs. An empty list (\`[]\` in
|
|
843
|
+
vlt.json, or \`--skills-dir=\`) links nothing. Each
|
|
844
|
+
dir must be inside the project, not in
|
|
845
|
+
node_modules.`,
|
|
846
|
+
},
|
|
783
847
|
})
|
|
784
848
|
.opt({
|
|
785
849
|
access: {
|
package/dist/config/index.d.ts
CHANGED
|
@@ -85,6 +85,8 @@ export type ConfigOptions = ConfigOptionsNoExtras & Pick<SpecOptions, 'catalog'
|
|
|
85
85
|
storeRoot: string;
|
|
86
86
|
monorepo?: Monorepo;
|
|
87
87
|
packageInfo: PackageInfoClient;
|
|
88
|
+
/** aborted when the command fails */
|
|
89
|
+
signal: AbortSignal;
|
|
88
90
|
};
|
|
89
91
|
/**
|
|
90
92
|
* The base config definition set as a type
|
|
@@ -125,6 +127,8 @@ export declare class Config {
|
|
|
125
127
|
* to recalculate the options.
|
|
126
128
|
*/
|
|
127
129
|
resetOptions(projectRoot?: string): void;
|
|
130
|
+
/** Abort requests still in flight */
|
|
131
|
+
abort(): void;
|
|
128
132
|
/**
|
|
129
133
|
* positional arguments to the vlt process
|
|
130
134
|
*/
|
package/dist/config/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { error } from '@vltpkg/error-cause';
|
|
|
24
24
|
import { PackageInfoClient } from '@vltpkg/package-info';
|
|
25
25
|
import { PackageJson } from '@vltpkg/package-json';
|
|
26
26
|
import { storeRoot } from '@vltpkg/registry-client/store-root';
|
|
27
|
+
import { cloneAvailable } from '@vltpkg/tar/clonefile';
|
|
27
28
|
import { resetCaches } from '@vltpkg/dep-id';
|
|
28
29
|
import { getOptions } from '@vltpkg/spec';
|
|
29
30
|
import { assertRecordStringString, assertRecordStringT, isObject, isRecordStringString, } from '@vltpkg/types';
|
|
@@ -35,6 +36,7 @@ import { PathScurry } from 'path-scurry';
|
|
|
35
36
|
import { commands, definition, defaultValues, getCommand, isRecordField, recordFields, storeLinkers, } from "./definition.js";
|
|
36
37
|
import { merge } from "./merge.js";
|
|
37
38
|
import { cloneLayer, mergeLayers } from "./merge-layers.js";
|
|
39
|
+
import { assertSpecAliases } from "./spec-aliases.js";
|
|
38
40
|
export { commands, definition, isRecordField, recordFields, };
|
|
39
41
|
export const kCustomInspect = Symbol.for('nodejs.util.inspect.custom');
|
|
40
42
|
// turn a set of pairs into a Record object.
|
|
@@ -172,6 +174,7 @@ export class Config {
|
|
|
172
174
|
const asRecords = pairsToRecords(this.parse().values);
|
|
173
175
|
const extras = {
|
|
174
176
|
projectRoot: this.projectRoot,
|
|
177
|
+
signal: this.#abort.signal,
|
|
175
178
|
storeRoot: storeRoot(asRecords.cache),
|
|
176
179
|
scurry,
|
|
177
180
|
packageJson,
|
|
@@ -197,7 +200,8 @@ export class Config {
|
|
|
197
200
|
return Object.fromEntries(Object.entries(options).filter(([k]) => k !== 'monorepo' &&
|
|
198
201
|
k !== 'scurry' &&
|
|
199
202
|
k !== 'packageJson' &&
|
|
200
|
-
k !== 'packageInfo'
|
|
203
|
+
k !== 'packageInfo' &&
|
|
204
|
+
k !== 'signal'));
|
|
201
205
|
},
|
|
202
206
|
});
|
|
203
207
|
return this.#options;
|
|
@@ -213,6 +217,11 @@ export class Config {
|
|
|
213
217
|
}
|
|
214
218
|
// memoized options() getter value
|
|
215
219
|
#options;
|
|
220
|
+
#abort = new AbortController();
|
|
221
|
+
/** Abort requests still in flight */
|
|
222
|
+
abort() {
|
|
223
|
+
this.#abort.abort();
|
|
224
|
+
}
|
|
216
225
|
/**
|
|
217
226
|
* positional arguments to the vlt process
|
|
218
227
|
*/
|
|
@@ -277,13 +286,16 @@ export class Config {
|
|
|
277
286
|
// ok, applied cmd-specific defaults, do rest of the parse
|
|
278
287
|
this.jack.applyDefaults(p);
|
|
279
288
|
// `auto` only hardlinks from the global store on linux: on APFS a
|
|
280
|
-
// hardlink is the slowest way to place a file, so darwin
|
|
281
|
-
//
|
|
282
|
-
//
|
|
289
|
+
// hardlink is the slowest way to place a file, so darwin clones
|
|
290
|
+
// instead, when its node can load `node:ffi` to call clonefile(2)
|
|
291
|
+
// with, and win32 (and darwin without it) unpack by default. the
|
|
292
|
+
// env layer is rewritten too, so `explicit` records the resolved
|
|
293
|
+
// value.
|
|
283
294
|
if (p.values['store-linker'] === 'auto' &&
|
|
284
295
|
process.platform !== 'linux') {
|
|
285
|
-
|
|
286
|
-
|
|
296
|
+
const linker = cloneAvailable() ? 'clone' : 'unpack';
|
|
297
|
+
p.values['store-linker'] = linker;
|
|
298
|
+
envValues['store-linker'] = linker;
|
|
287
299
|
}
|
|
288
300
|
// what was set on the cli or env for this run. record fields hold
|
|
289
301
|
// only those pairs, env then cli, so later ones win per key.
|
|
@@ -317,6 +329,10 @@ export class Config {
|
|
|
317
329
|
const base = (k in cmdPairs ? cmdPairs[k] : fileValues[k]) ?? [];
|
|
318
330
|
values[k] = dedupePairs([...base, ...pairs]);
|
|
319
331
|
}
|
|
332
|
+
// skipped for `vlt config`, so a bad alias can be removed
|
|
333
|
+
if (cmdOrFallback !== 'config') {
|
|
334
|
+
assertSpecAliases(pairsToRecords(p.values));
|
|
335
|
+
}
|
|
320
336
|
this.jack.writeEnv(p);
|
|
321
337
|
process.env[kParentEnv] = JSON.stringify({
|
|
322
338
|
explicit,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare const builtins: {
|
|
2
|
+
registries: {
|
|
3
|
+
gh: string;
|
|
4
|
+
};
|
|
5
|
+
'jsr-registries': {
|
|
6
|
+
jsr: string;
|
|
7
|
+
};
|
|
8
|
+
'git-hosts': {
|
|
9
|
+
github: string;
|
|
10
|
+
bitbucket: string;
|
|
11
|
+
gitlab: string;
|
|
12
|
+
gist: string;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
type SpecAliasField = keyof typeof builtins;
|
|
16
|
+
/**
|
|
17
|
+
* Throw `ECONFIG` if a spec prefix alias is in more than one of
|
|
18
|
+
* `registries` / `jsr-registries` / `git-hosts` (built-ins included),
|
|
19
|
+
* or is a built-in protocol. Overriding a built-in in its own field is ok.
|
|
20
|
+
*/
|
|
21
|
+
export declare const assertSpecAliases: (values: Partial<Record<SpecAliasField, Record<string, string>>>) => void;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { error } from '@vltpkg/error-cause';
|
|
2
|
+
import { builtinProtocols, defaultGitHosts, defaultJsrRegistries, defaultRegistries, } from '@vltpkg/spec';
|
|
3
|
+
const builtins = {
|
|
4
|
+
registries: defaultRegistries,
|
|
5
|
+
'jsr-registries': defaultJsrRegistries,
|
|
6
|
+
'git-hosts': defaultGitHosts,
|
|
7
|
+
};
|
|
8
|
+
const fields = Object.keys(builtins);
|
|
9
|
+
/**
|
|
10
|
+
* Throw `ECONFIG` if a spec prefix alias is in more than one of
|
|
11
|
+
* `registries` / `jsr-registries` / `git-hosts` (built-ins included),
|
|
12
|
+
* or is a built-in protocol. Overriding a built-in in its own field is ok.
|
|
13
|
+
*/
|
|
14
|
+
export const assertSpecAliases = (values) => {
|
|
15
|
+
const owners = new Map();
|
|
16
|
+
for (const field of fields) {
|
|
17
|
+
for (const key of Object.keys(builtins[field])) {
|
|
18
|
+
if (values[field]?.[key] === undefined) {
|
|
19
|
+
owners.set(key, { field, builtin: true });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
for (const field of fields) {
|
|
24
|
+
for (const key of Object.keys(values[field] ?? {})) {
|
|
25
|
+
const name = `${field}.${key}`;
|
|
26
|
+
if (builtinProtocols.has(key)) {
|
|
27
|
+
throw error(`${name} shadows the built-in \`${key}:\` protocol`, {
|
|
28
|
+
code: 'ECONFIG',
|
|
29
|
+
name,
|
|
30
|
+
found: key,
|
|
31
|
+
wanted: 'a name that is not a built-in protocol',
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
const owner = owners.get(key);
|
|
35
|
+
if (owner) {
|
|
36
|
+
const where = `${owner.field}.${key}${owner.builtin ? ' (built-in)' : ''}`;
|
|
37
|
+
throw error(`\`${key}:\` spec prefix defined in both ${where} and ${name}`, {
|
|
38
|
+
code: 'ECONFIG',
|
|
39
|
+
name,
|
|
40
|
+
found: key,
|
|
41
|
+
wanted: `a ${field} name not used by ${owner.field}`,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
owners.set(key, { field, builtin: false });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
package/dist/custom-help.js
CHANGED
|
@@ -183,6 +183,10 @@ const commandHelp = {
|
|
|
183
183
|
desc: 'Configure your vlt.io account registries',
|
|
184
184
|
defaultOrder: 0,
|
|
185
185
|
},
|
|
186
|
+
skills: {
|
|
187
|
+
args: '[list|link]',
|
|
188
|
+
desc: 'Manage agent skills from installed packages',
|
|
189
|
+
},
|
|
186
190
|
token: {
|
|
187
191
|
args: '[add|rm]',
|
|
188
192
|
desc: 'Manage authentication tokens',
|
package/dist/exec-command.js
CHANGED
|
@@ -14,6 +14,7 @@ import { stderr, stdout, styleTextStdout } from "./output.js";
|
|
|
14
14
|
import assert from 'node:assert';
|
|
15
15
|
import { resolve } from 'node:path';
|
|
16
16
|
import { createHostContextsMap } from "./query-host-contexts.js";
|
|
17
|
+
import { sortScopeLocations } from "./sort-scope-locations.js";
|
|
17
18
|
const isScriptSet = (o) => {
|
|
18
19
|
if (!o || typeof o !== 'object')
|
|
19
20
|
return false;
|
|
@@ -98,11 +99,13 @@ export class ExecCommand {
|
|
|
98
99
|
this.#defaultIgnoreMissing = true;
|
|
99
100
|
const mainManifest = conf.options.packageJson.maybeRead(this.projectRoot);
|
|
100
101
|
let graph;
|
|
102
|
+
let monorepo;
|
|
101
103
|
if (mainManifest) {
|
|
104
|
+
monorepo = Monorepo.load(this.projectRoot);
|
|
102
105
|
graph = actual.load({
|
|
103
106
|
...conf.options,
|
|
104
107
|
mainManifest,
|
|
105
|
-
monorepo
|
|
108
|
+
monorepo,
|
|
106
109
|
loadManifests: false,
|
|
107
110
|
});
|
|
108
111
|
}
|
|
@@ -120,14 +123,15 @@ export class ExecCommand {
|
|
|
120
123
|
const { nodes } = await query.search(queryString, {
|
|
121
124
|
signal: new AbortController().signal,
|
|
122
125
|
});
|
|
123
|
-
|
|
126
|
+
const locations = [];
|
|
124
127
|
for (const node of nodes) {
|
|
125
128
|
const { location } = node.toJSON();
|
|
126
129
|
assert(location, error(`node ${node.id} has no location`, {
|
|
127
130
|
found: node,
|
|
128
131
|
}));
|
|
129
|
-
|
|
132
|
+
locations.push(location);
|
|
130
133
|
}
|
|
134
|
+
this.#nodes = sortScopeLocations(locations, monorepo);
|
|
131
135
|
}
|
|
132
136
|
else if (paths?.length || groups?.length || recursive) {
|
|
133
137
|
this.#defaultIgnoreMissing = true;
|
|
@@ -163,8 +167,9 @@ export class ExecCommand {
|
|
|
163
167
|
}
|
|
164
168
|
// run across workspaces
|
|
165
169
|
let failed = false;
|
|
166
|
-
const runInDir = async (cwd, label) => {
|
|
167
|
-
const
|
|
170
|
+
const runInDir = async (cwd, label, signal) => {
|
|
171
|
+
const arg = { ...this.bgArg(cwd), signal };
|
|
172
|
+
const result = await this.bg(arg).catch((er) => {
|
|
168
173
|
if (isErrorWithCause(er) && isRunResult(er.cause)) {
|
|
169
174
|
this.printResult(label, er.cause);
|
|
170
175
|
}
|
|
@@ -189,7 +194,8 @@ export class ExecCommand {
|
|
|
189
194
|
}
|
|
190
195
|
}
|
|
191
196
|
else if (this.#monorepo) {
|
|
192
|
-
|
|
197
|
+
// aborted on the first failure, killing the rest
|
|
198
|
+
const wsResultMap = await this.#monorepo.run((ws, signal) => runInDir(ws.fullpath, ws.path, signal));
|
|
193
199
|
for (const [ws, result] of wsResultMap) {
|
|
194
200
|
if (result)
|
|
195
201
|
resultMap.set(ws.path, result);
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { format } from 'node:util';
|
|
2
|
-
import { asRootError } from '@vltpkg/output/error';
|
|
2
|
+
import { asRootError, findRootError } from '@vltpkg/output/error';
|
|
3
|
+
import { setVltJsonOnly } from '@vltpkg/workspaces';
|
|
3
4
|
import { loadPackageJson } from 'package-json-from-dist';
|
|
4
5
|
import { getSortedCliOptions, getSortedKeys, } from "./config/definition.js";
|
|
5
6
|
import { Config } from "./config/index.js";
|
|
@@ -12,13 +13,14 @@ const loadVlt = async (cwd, argv) => {
|
|
|
12
13
|
return await Config.load(cwd, argv);
|
|
13
14
|
}
|
|
14
15
|
catch (e) {
|
|
15
|
-
const
|
|
16
|
+
const code = findRootError(e, { code: 'ECONFIG' }) ? 'ECONFIG' : 'JACKSPEAK';
|
|
17
|
+
const err = asRootError(e, { code });
|
|
16
18
|
const { found, path, wanted, name } = err.cause;
|
|
17
19
|
const isConfigFile = typeof path === 'string';
|
|
18
|
-
const msg = isConfigFile ?
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const validOptions = wanted ? undefined
|
|
20
|
+
const msg = isConfigFile ? `Problem in Config File ${path}`
|
|
21
|
+
: code === 'ECONFIG' ? 'Config Error'
|
|
22
|
+
: 'Invalid Option Flag';
|
|
23
|
+
const validOptions = wanted || code === 'ECONFIG' ? undefined
|
|
22
24
|
: isConfigFile ? getSortedKeys()
|
|
23
25
|
: getSortedCliOptions();
|
|
24
26
|
stderr(msg);
|
|
@@ -34,7 +36,10 @@ const loadVlt = async (cwd, argv) => {
|
|
|
34
36
|
stderr(indent('Valid Options:'));
|
|
35
37
|
stderr(indent(validOptions.join('\n'), 4));
|
|
36
38
|
}
|
|
37
|
-
|
|
39
|
+
// `vlt help` would fail the same way
|
|
40
|
+
if (code !== 'ECONFIG') {
|
|
41
|
+
stderr(indent(`Run 'vlt help' for more information about available options.`));
|
|
42
|
+
}
|
|
38
43
|
return flushAndExit(process.exitCode || 1);
|
|
39
44
|
}
|
|
40
45
|
};
|
|
@@ -45,6 +50,8 @@ const run = async () => {
|
|
|
45
50
|
if (vlt.get('version')) {
|
|
46
51
|
return stdout(version);
|
|
47
52
|
}
|
|
53
|
+
// ci reads workspaces from vlt.json only; set before options load
|
|
54
|
+
setVltJsonOnly(vlt.command === 'ci');
|
|
48
55
|
const { monorepo } = vlt.options;
|
|
49
56
|
// Infer the workspace by being in that directory.
|
|
50
57
|
if (vlt.get('workspace') === undefined) {
|
|
@@ -57,7 +64,10 @@ const run = async () => {
|
|
|
57
64
|
if (vlt.command !== 'init' &&
|
|
58
65
|
(vlt.get('workspace') || vlt.get('workspace-group')) &&
|
|
59
66
|
![...(monorepo?.values() ?? [])].length) {
|
|
60
|
-
|
|
67
|
+
const where = vlt.command === 'ci' ?
|
|
68
|
+
'the vlt.json config (vlt ci ignores package.json and pnpm-workspace.yaml)'
|
|
69
|
+
: 'the vlt.json config, the "workspaces" field of the root package.json, or the "packages" list of pnpm-workspace.yaml';
|
|
70
|
+
stderr(`Error: No matching workspaces found. Make sure ${where} contains the correct workspaces.`);
|
|
61
71
|
if (vlt.get('workspace')) {
|
|
62
72
|
stderr(indent(`Workspace: ${format(vlt.get('workspace'))}`));
|
|
63
73
|
}
|
package/dist/load-command.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export type Command<T> = {
|
|
|
15
15
|
* Set to `true` by commands that hit a registry or resolve registry
|
|
16
16
|
* specs. There is no default registry, so `outputCommand()` fails
|
|
17
17
|
* early with an `ECONFIG` error when one of these runs unconfigured.
|
|
18
|
+
* `publish`/`unpublish` check in-command instead, since
|
|
19
|
+
* `publishConfig.registry` may suffice.
|
|
18
20
|
*/
|
|
19
21
|
needsRegistry?: boolean;
|
|
20
22
|
/**
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { WorkspaceConfigSource } from '@vltpkg/workspaces';
|
|
2
|
+
import type { LoadedConfig } from './config/index.ts';
|
|
3
|
+
export type MigratedWorkspaces = {
|
|
4
|
+
source: WorkspaceConfigSource;
|
|
5
|
+
workspaces: string[];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Save workspaces read from `package.json` or `pnpm-workspace.yaml` to
|
|
9
|
+
* the project `vlt.json`, unless `--no-migrate-workspaces`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const migrateWorkspaces: (conf: LoadedConfig) => MigratedWorkspaces | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Warn when workspaces are declared only outside `vlt.json`, which
|
|
14
|
+
* `vlt ci` ignores.
|
|
15
|
+
*/
|
|
16
|
+
export declare const warnIgnoredWorkspaces: (conf: LoadedConfig) => void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { save } from '@vltpkg/vlt-json';
|
|
2
|
+
import { migratableWSConfig, resolveWSConfig, } from '@vltpkg/workspaces';
|
|
3
|
+
import { stderr } from "./output.js";
|
|
4
|
+
// workspaces declared outside vlt.json, if any
|
|
5
|
+
const found = (conf) => {
|
|
6
|
+
const resolved = resolveWSConfig(conf.options.projectRoot, conf.options.packageJson, false);
|
|
7
|
+
const workspaces = migratableWSConfig(resolved);
|
|
8
|
+
const { source } = resolved;
|
|
9
|
+
if (!workspaces?.length || !source)
|
|
10
|
+
return;
|
|
11
|
+
return { source, workspaces };
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Save workspaces read from `package.json` or `pnpm-workspace.yaml` to
|
|
15
|
+
* the project `vlt.json`, unless `--no-migrate-workspaces`.
|
|
16
|
+
*/
|
|
17
|
+
export const migrateWorkspaces = (conf) => {
|
|
18
|
+
if (!conf.options['migrate-workspaces'])
|
|
19
|
+
return;
|
|
20
|
+
const migrated = found(conf);
|
|
21
|
+
if (migrated)
|
|
22
|
+
save('workspaces', migrated.workspaces);
|
|
23
|
+
return migrated;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Warn when workspaces are declared only outside `vlt.json`, which
|
|
27
|
+
* `vlt ci` ignores.
|
|
28
|
+
*/
|
|
29
|
+
export const warnIgnoredWorkspaces = (conf) => {
|
|
30
|
+
const { loglevel } = conf.values;
|
|
31
|
+
if (loglevel === 'silent' || loglevel === 'error')
|
|
32
|
+
return;
|
|
33
|
+
let migrated;
|
|
34
|
+
try {
|
|
35
|
+
migrated = found(conf);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// invalid workspaces config: nothing to suggest
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!migrated)
|
|
42
|
+
return;
|
|
43
|
+
stderr(`Warning: vlt ci reads workspaces from vlt.json only; ignoring ${migrated.source}, its workspaces are not installed. Run \`vlt install\` to save them to vlt.json, or add them there.`);
|
|
44
|
+
};
|
package/dist/output.js
CHANGED
|
@@ -227,6 +227,7 @@ export const outputCommand = async (cliCommand, conf, { start, vltVersion } = {
|
|
|
227
227
|
...formatOptions,
|
|
228
228
|
colors: stderrColor,
|
|
229
229
|
});
|
|
230
|
-
|
|
230
|
+
// stop pending requests, so the process can exit on its own
|
|
231
|
+
conf.abort();
|
|
231
232
|
}
|
|
232
233
|
};
|
package/dist/print-err.js
CHANGED
|
@@ -223,8 +223,11 @@ const printCode = (err, usage, stderr, format) => {
|
|
|
223
223
|
return {};
|
|
224
224
|
}
|
|
225
225
|
case 'ECONFIG': {
|
|
226
|
-
const { found, wanted, validOptions } = err.cause;
|
|
226
|
+
const { found, wanted, validOptions, from } = err.cause;
|
|
227
227
|
stderr(`Config Error: ${err.message}`);
|
|
228
|
+
if (from) {
|
|
229
|
+
stderr(indent(`From: ${format(from)}`));
|
|
230
|
+
}
|
|
228
231
|
if (found) {
|
|
229
232
|
stderr(indent(`Found: ${format(found)}`));
|
|
230
233
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { NormalizedManifest } from '@vltpkg/types';
|
|
2
|
+
type PublishConfig = {
|
|
3
|
+
directory?: string;
|
|
4
|
+
registry?: string;
|
|
5
|
+
access?: string;
|
|
6
|
+
tag?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const getPublishConfig: (manifest: NormalizedManifest) => PublishConfig | undefined;
|
|
9
|
+
export {};
|