@duyquangnvx/agent-cli 0.27.0 → 0.28.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/CHANGELOG.md +27 -0
- package/dist/agent-cli.js +9 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/built-ins/agents-md.d.ts +3 -2
- package/dist/built-ins/agents-md.js +8 -9
- package/dist/built-ins/agents-md.js.map +1 -1
- package/dist/built-ins/commands.d.ts +2 -1
- package/dist/built-ins/commands.js.map +1 -1
- package/dist/built-ins/doctor-rows.js +1 -1
- package/dist/built-ins/doctor-rows.js.map +1 -1
- package/dist/built-ins/doctor.d.ts +0 -1
- package/dist/built-ins/doctor.js +21 -8
- package/dist/built-ins/doctor.js.map +1 -1
- package/dist/built-ins/install/dependency.js +23 -23
- package/dist/built-ins/install/dependency.js.map +1 -1
- package/dist/built-ins/install/global-npm.d.ts +6 -3
- package/dist/built-ins/install/global-npm.js +19 -14
- package/dist/built-ins/install/global-npm.js.map +1 -1
- package/dist/built-ins/install/global.js +6 -7
- package/dist/built-ins/install/global.js.map +1 -1
- package/dist/built-ins/install/install.d.ts +0 -3
- package/dist/built-ins/install/install.js +0 -1
- package/dist/built-ins/install/install.js.map +1 -1
- package/dist/built-ins/install/release-check.js +10 -17
- package/dist/built-ins/install/release-check.js.map +1 -1
- package/dist/built-ins/npm.d.ts +8 -7
- package/dist/built-ins/npm.js +20 -12
- package/dist/built-ins/npm.js.map +1 -1
- package/dist/built-ins/project-root.d.ts +4 -4
- package/dist/built-ins/project-root.js +12 -22
- package/dist/built-ins/project-root.js.map +1 -1
- package/dist/built-ins/read.d.ts +5 -0
- package/dist/built-ins/read.js +29 -0
- package/dist/built-ins/read.js.map +1 -0
- package/dist/built-ins/setup.d.ts +1 -2
- package/dist/built-ins/setup.js +32 -26
- package/dist/built-ins/setup.js.map +1 -1
- package/dist/built-ins/skill/home.d.ts +2 -1
- package/dist/built-ins/skill/home.js +19 -17
- package/dist/built-ins/skill/home.js.map +1 -1
- package/dist/built-ins/skill/install-command.d.ts +2 -1
- package/dist/built-ins/skill/install-command.js +13 -11
- package/dist/built-ins/skill/install-command.js.map +1 -1
- package/dist/built-ins/skill/project.js +6 -7
- package/dist/built-ins/skill/project.js.map +1 -1
- package/dist/built-ins/skill/sync.d.ts +4 -3
- package/dist/built-ins/skill/sync.js +24 -17
- package/dist/built-ins/skill/sync.js.map +1 -1
- package/dist/built-ins/update.d.ts +1 -1
- package/dist/built-ins/update.js +9 -7
- package/dist/built-ins/update.js.map +1 -1
- package/dist/built-ins/upgrades.d.ts +2 -1
- package/dist/built-ins/upgrades.js +5 -12
- package/dist/built-ins/upgrades.js.map +1 -1
- package/dist/check-examples.js +5 -23
- package/dist/check-examples.js.map +1 -1
- package/dist/check-next-steps.d.ts +3 -9
- package/dist/check-next-steps.js +20 -32
- package/dist/check-next-steps.js.map +1 -1
- package/dist/command-line/line-problem.d.ts +14 -0
- package/dist/command-line/line-problem.js +41 -0
- package/dist/command-line/line-problem.js.map +1 -0
- package/dist/context/files.d.ts +3 -0
- package/dist/context/files.js +17 -2
- package/dist/context/files.js.map +1 -1
- package/dist/context/outputs.d.ts +13 -24
- package/dist/context/outputs.js +37 -37
- package/dist/context/outputs.js.map +1 -1
- package/dist/context/spawn.js +3 -1
- package/dist/context/spawn.js.map +1 -1
- package/dist/context/tools.d.ts +9 -4
- package/dist/context/tools.js +12 -12
- package/dist/context/tools.js.map +1 -1
- package/dist/context.d.ts +3 -1
- package/dist/define-command.d.ts +19 -12
- package/dist/define-command.js +5 -3
- package/dist/define-command.js.map +1 -1
- package/dist/define.d.ts +10 -3
- package/dist/define.js.map +1 -1
- package/dist/errors.d.ts +3 -6
- package/dist/errors.js +17 -28
- package/dist/errors.js.map +1 -1
- package/dist/execute.d.ts +7 -16
- package/dist/execute.js +11 -14
- package/dist/execute.js.map +1 -1
- package/dist/exit-classes.d.ts +7 -10
- package/dist/exit-classes.js +20 -81
- package/dist/exit-classes.js.map +1 -1
- package/dist/failure.d.ts +36 -0
- package/dist/failure.js +65 -0
- package/dist/failure.js.map +1 -0
- package/dist/help-json.js +5 -3
- package/dist/help-json.js.map +1 -1
- package/dist/help.js +3 -3
- package/dist/help.js.map +1 -1
- package/dist/output.d.ts +3 -10
- package/dist/output.js +14 -24
- package/dist/output.js.map +1 -1
- package/dist/run-cli.js +7 -5
- package/dist/run-cli.js.map +1 -1
- package/dist/run-command.d.ts +6 -1
- package/dist/run-command.js +31 -158
- package/dist/run-command.js.map +1 -1
- package/dist/run-options.d.ts +5 -2
- package/dist/run-scope.d.ts +35 -0
- package/dist/run-scope.js +138 -0
- package/dist/run-scope.js.map +1 -0
- package/dist/runtime-codes.d.ts +140 -1
- package/dist/runtime-codes.js +60 -4
- package/dist/runtime-codes.js.map +1 -1
- package/docs/example/cli.test.ts +9 -2
- package/docs/example/cli.ts +1 -0
- package/docs/example/folder.ts +1 -0
- package/docs/guides/commands.md +1 -1
- package/docs/guides/doctor.md +2 -1
- package/docs/guides/errors.md +1 -1
- package/docs/guides/testing.md +2 -1
- package/package.json +1 -1
- package/dist/command-errors.d.ts +0 -8
- package/dist/command-errors.js +0 -25
- package/dist/command-errors.js.map +0 -1
- package/dist/command-line/route-line.d.ts +0 -15
- package/dist/command-line/route-line.js +0 -18
- package/dist/command-line/route-line.js.map +0 -1
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { CliError } from "../../errors.js";
|
|
2
|
+
import { NOT_GLOBAL_INSTALL } from "../../runtime-codes.js";
|
|
2
3
|
import { setupCommand } from "../setup.js";
|
|
3
4
|
import { updateCommand } from "../update.js";
|
|
4
|
-
import { globalInstallOf, globalNpm,
|
|
5
|
+
import { globalInstallOf, globalNpm, setupLineOf } from "./global-npm.js";
|
|
5
6
|
import { releaseCheck } from "./release-check.js";
|
|
6
7
|
import { runAsOf } from "./run-as.js";
|
|
7
|
-
function checkOf(cli, install,
|
|
8
|
+
function checkOf(cli, install, launch) {
|
|
8
9
|
return {
|
|
9
10
|
install: async (ctx) => {
|
|
10
|
-
const npm = globalNpm(cli, install, ctx,
|
|
11
|
+
const npm = globalNpm(cli, install, ctx, launch);
|
|
11
12
|
try {
|
|
12
|
-
const copy = await globalInstallOf(bin, npm);
|
|
13
|
+
const copy = await globalInstallOf(launch.bin, npm);
|
|
13
14
|
return { state: "ok", message: `a global npm install under ${copy.prefix}` };
|
|
14
15
|
}
|
|
15
16
|
catch (error) {
|
|
@@ -25,7 +26,7 @@ function checkOf(cli, install, { bin, node }) {
|
|
|
25
26
|
},
|
|
26
27
|
release: async (ctx) => {
|
|
27
28
|
const fix = `${cli.name} update`;
|
|
28
|
-
return { npm: globalNpm(cli, install, ctx,
|
|
29
|
+
return { npm: globalNpm(cli, install, ctx, launch), advise: () => ({ fix }) };
|
|
29
30
|
},
|
|
30
31
|
};
|
|
31
32
|
}
|
|
@@ -37,8 +38,6 @@ export function globalInstall(cli, install) {
|
|
|
37
38
|
setup: setupCommand(cli, install, launch),
|
|
38
39
|
update: updateCommand(cli, install, launch),
|
|
39
40
|
}),
|
|
40
|
-
// `setup` and `update` fail as the source's when the registry has no release.
|
|
41
|
-
exitClasses: ["source"],
|
|
42
41
|
check: (launch) => checkOf(cli, install, launch),
|
|
43
42
|
notice: (launch, ctx) => releaseCheck(cli, install, adapter.runAs, launch, ctx),
|
|
44
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/built-ins/install/global.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"global.js","sourceRoot":"","sources":["../../../src/built-ins/install/global.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,SAAS,OAAO,CAAC,GAAe,EAAE,OAAsB,EAAE,MAAc;IACtE,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,GAAY,EAA0B,EAAE;YACtD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YACjD,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACpD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,8BAA8B,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;oBACnE,OAAO;wBACL,KAAK,EAAE,SAAS;wBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,GAAG,EAAE,WAAW,CAAC,OAAO,CAAC;qBAC1B,CAAC;gBACJ,CAAC;gBACD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,GAAY,EAAE,EAAE;YAC9B,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC;YACjC,OAAO,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAChF,CAAC;KACF,CAAC;AACJ,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,aAAa,CAAC,GAAe,EAAE,OAAsB;IACnE,MAAM,OAAO,GAAY;QACvB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC;QACnB,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACrB,KAAK,EAAE,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;YACzC,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;SAC5C,CAAC;QACF,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC;QAChD,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC;KAChF,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Context } from "../../context.js";
|
|
2
2
|
import type { Commands, CommandTreeCli, DoctorFinding } from "../../define.js";
|
|
3
|
-
import type { DeclaredExitClass } from "../../error-table.js";
|
|
4
3
|
import type { Launch } from "../commands.js";
|
|
5
4
|
import type { NpmContext } from "../npm.js";
|
|
6
5
|
import type { SkillCli } from "../skill/skill.js";
|
|
@@ -28,8 +27,6 @@ export interface Install {
|
|
|
28
27
|
/** How every command line the Runtime gives its caller starts (ADR 0011). */
|
|
29
28
|
readonly runAs: string;
|
|
30
29
|
readonly builtIns: (launch: Launch) => Commands;
|
|
31
|
-
/** The Exit classes its Built-ins can end in, besides those every CLI can. */
|
|
32
|
-
readonly exitClasses: readonly DeclaredExitClass[];
|
|
33
30
|
/** Called once per `doctor` run. */
|
|
34
31
|
readonly check: (launch: Launch) => InstallCheck;
|
|
35
32
|
/** Run before a Command, so an agent that rarely runs `doctor` still hears of a newer release. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/built-ins/install/install.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/built-ins/install/install.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAkCtC,MAAM,QAAQ,GAAG,KAAK,IAAmB,EAAE,GAAE,CAAC,CAAC;AAE/C,SAAS,SAAS,CAAC,GAAe;IAChC,MAAM,OAAO,GAAG,KAAK,IAA4B,EAAE,CAAC,CAAC;QACnD,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,gBAAgB,GAAG,CAAC,IAAI,sBAAsB;KACxD,CAAC,CAAC;IACH,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC;QACnB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACpB,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACZ,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,OAAO,EAAE,EAAE,CAAC;SACpD,CAAC;QACF,MAAM,EAAE,QAAQ;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAe;IACvC,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC;IACxB,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACjD,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACnG,CAAC"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
2
1
|
import { homedir } from "node:os";
|
|
3
|
-
import {
|
|
2
|
+
import { join } from "node:path";
|
|
4
3
|
import * as z from "zod";
|
|
5
|
-
import {
|
|
6
|
-
import { CliError, cliVariable, errnoOf, isDebug, messageOf, orMissing } from "../../errors.js";
|
|
4
|
+
import { CliError, cliVariable, errnoOf, isDebug, messageOf } from "../../errors.js";
|
|
7
5
|
import { latestViewArgs, npmOf } from "../npm.js";
|
|
6
|
+
import { readIfAny } from "../read.js";
|
|
8
7
|
import { compareVersions, isVersion } from "../semver.js";
|
|
9
8
|
import { globalNpm } from "./global-npm.js";
|
|
10
9
|
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
@@ -72,24 +71,18 @@ function parsedCheck(text) {
|
|
|
72
71
|
return undefined;
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
|
-
async function lastCheck(file) {
|
|
76
|
-
const text = await
|
|
74
|
+
async function lastCheck(files, file) {
|
|
75
|
+
const text = await readIfAny(files, file);
|
|
77
76
|
return text === undefined ? undefined : parsedCheck(text);
|
|
78
77
|
}
|
|
79
|
-
async function writeCheck(file, check) {
|
|
80
|
-
await mkdir(dirname(file), { recursive: true });
|
|
81
|
-
const temp = tempPathOf(file);
|
|
82
|
-
await writeFile(temp, JSON.stringify(check));
|
|
83
|
-
await rename(temp, file);
|
|
84
|
-
}
|
|
85
78
|
// The time is written before the check starts, so runs started meanwhile, or after a check that
|
|
86
79
|
// failed, start none until the next day.
|
|
87
|
-
async function startCheck(cli, install, file, last,
|
|
80
|
+
async function startCheck(cli, install, file, last, launch, ctx) {
|
|
88
81
|
const checkedAt = ctx.clock.now();
|
|
89
82
|
const previous = last?.latest ?? "";
|
|
90
|
-
await
|
|
91
|
-
const npm = globalNpm(cli, install, ctx,
|
|
92
|
-
const { path, env } = npmOf(npm
|
|
83
|
+
await ctx.files.write(file, JSON.stringify({ checkedAt, latest: last?.latest }));
|
|
84
|
+
const npm = globalNpm(cli, install, ctx, launch);
|
|
85
|
+
const { path, env } = await npmOf(npm);
|
|
93
86
|
await ctx.spawnDetached(process.execPath, ["-e", CHECK_SCRIPT, file, String(checkedAt), previous, path, ...latestViewArgs(npm.registry)], { env });
|
|
94
87
|
}
|
|
95
88
|
function debugLine(cli, ctx, text) {
|
|
@@ -118,7 +111,7 @@ export async function releaseCheck(cli, install, runAs, launch, ctx) {
|
|
|
118
111
|
}
|
|
119
112
|
async function checkAndTell(cli, install, runAs, launch, ctx) {
|
|
120
113
|
const file = cacheFileOf(cli.name, ctx.env);
|
|
121
|
-
const last = await lastCheck(file);
|
|
114
|
+
const last = await lastCheck(ctx.files, file);
|
|
122
115
|
if (last?.error !== undefined)
|
|
123
116
|
debugLine(cli, ctx, last.error);
|
|
124
117
|
if (last === undefined || ctx.clock.now() - last.checkedAt >= CHECK_INTERVAL_MS) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release-check.js","sourceRoot":"","sources":["../../../src/built-ins/install/release-check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"release-check.js","sourceRoot":"","sources":["../../../src/built-ins/install/release-check.ts"],"names":[],"mappings":"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"}
|
package/dist/built-ins/npm.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
import type { Files } from "../context/files.js";
|
|
1
2
|
import type { Context, Env } from "../context.js";
|
|
2
3
|
import type { CommandTreeCli } from "../define.js";
|
|
3
4
|
import { type Step } from "../next-step.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const NPM_FAILED = "NPM_FAILED";
|
|
8
|
-
export declare const NO_LATEST = "NO_LATEST";
|
|
5
|
+
import type { Launch } from "./commands.js";
|
|
6
|
+
/** What a Command running npm may fail with, for it to declare in `errors`. */
|
|
7
|
+
export declare const NPM_ERRORS: readonly ["REGISTRY_UNREACHABLE", "REGISTRY_AUTH", "INSTALL_FAILED", "NPM_FAILED", "NO_LATEST"];
|
|
9
8
|
/** The registry npm asks for a package, and what failures say about it. */
|
|
10
9
|
export interface Registry {
|
|
11
10
|
readonly package: string;
|
|
@@ -32,10 +31,12 @@ export interface NpmContext {
|
|
|
32
31
|
readonly signal: AbortSignal;
|
|
33
32
|
/** The Node running the CLI, whose npm installs into it. */
|
|
34
33
|
readonly node: string | undefined;
|
|
34
|
+
readonly platform: NodeJS.Platform;
|
|
35
|
+
readonly files: Files;
|
|
35
36
|
}
|
|
36
37
|
/** Which kind of npm call failed, since the same npm code means different things for each. */
|
|
37
38
|
export type NpmCall = "prefix" | "view" | "install";
|
|
38
|
-
export declare function npmContext(cli: Pick<CommandTreeCli, "name">, registry: Registry, ctx: Context, node:
|
|
39
|
+
export declare function npmContext(cli: Pick<CommandTreeCli, "name">, registry: Registry, ctx: Context, { node, platform }: Pick<Launch, "node" | "platform">, cwd: string): NpmContext;
|
|
39
40
|
/** The `@scope` of a scoped package name. */
|
|
40
41
|
export declare function scopeOf(name: string): string | undefined;
|
|
41
42
|
/** The command a person runs to install the CLI globally from its registry. */
|
|
@@ -47,7 +48,7 @@ interface Npm {
|
|
|
47
48
|
readonly path: string;
|
|
48
49
|
readonly env: Env;
|
|
49
50
|
}
|
|
50
|
-
export declare function npmOf(ctx: NpmContext
|
|
51
|
+
export declare function npmOf(ctx: NpmContext): Promise<Npm>;
|
|
51
52
|
/**
|
|
52
53
|
* Runs npm with a fresh cache, so a stale cache never answers for the registry; maps its failures to codes.
|
|
53
54
|
* `signal` kills npm when it aborts; pass null for a step that must finish.
|
package/dist/built-ins/npm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// biome-ignore lint/style/noRestrictedImports: npm's scratch cache is the Runtime's own temp folder, never the operator's files, so no failure there is theirs to act on.
|
|
2
2
|
import { mkdtemp, rm } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { delimiter, dirname, join } from "node:path";
|
|
@@ -6,14 +6,18 @@ import { isAgent } from "../context/agent.js";
|
|
|
6
6
|
import { spawnChild } from "../context/spawn.js";
|
|
7
7
|
import { CliError, messageOf, runtimeError } from "../errors.js";
|
|
8
8
|
import { wholeLine } from "../next-step.js";
|
|
9
|
+
import { INSTALL_FAILED, NO_LATEST, NPM_FAILED, REGISTRY_AUTH, REGISTRY_UNREACHABLE, } from "../runtime-codes.js";
|
|
9
10
|
import { lastLines } from "../tail.js";
|
|
10
11
|
import { isVersion } from "./semver.js";
|
|
11
|
-
|
|
12
|
-
export const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
/** What a Command running npm may fail with, for it to declare in `errors`. */
|
|
13
|
+
export const NPM_ERRORS = [
|
|
14
|
+
REGISTRY_UNREACHABLE,
|
|
15
|
+
REGISTRY_AUTH,
|
|
16
|
+
INSTALL_FAILED,
|
|
17
|
+
NPM_FAILED,
|
|
18
|
+
NO_LATEST,
|
|
19
|
+
];
|
|
20
|
+
export function npmContext(cli, registry, ctx, { node, platform }, cwd) {
|
|
17
21
|
return {
|
|
18
22
|
cliName: cli.name,
|
|
19
23
|
rerun: ctx.rerun(),
|
|
@@ -22,6 +26,8 @@ export function npmContext(cli, registry, ctx, node, cwd) {
|
|
|
22
26
|
env: ctx.env,
|
|
23
27
|
signal: ctx.signal,
|
|
24
28
|
node,
|
|
29
|
+
platform,
|
|
30
|
+
files: ctx.files,
|
|
25
31
|
};
|
|
26
32
|
}
|
|
27
33
|
const STDERR_TAIL_LINES = 10;
|
|
@@ -53,10 +59,12 @@ export function setupCommandLine({ package: name, flags }) {
|
|
|
53
59
|
return ["npx", "-y", ...flags, `${name}@latest`, "setup"].join(" ");
|
|
54
60
|
}
|
|
55
61
|
// Under nvm the first npm on PATH may belong to another Node, and install there.
|
|
56
|
-
export function npmOf(ctx
|
|
62
|
+
export async function npmOf(ctx) {
|
|
63
|
+
const windows = ctx.platform === "win32";
|
|
57
64
|
const beside = ctx.node === undefined ? undefined : join(dirname(ctx.node), windows ? "npm.cmd" : "npm");
|
|
58
|
-
if (beside === undefined || !
|
|
65
|
+
if (beside === undefined || !(await ctx.files.exists(beside))) {
|
|
59
66
|
return { path: "npm", env: ctx.env };
|
|
67
|
+
}
|
|
60
68
|
if (windows)
|
|
61
69
|
return { path: beside, env: ctx.env };
|
|
62
70
|
// npm starts with `#!/usr/bin/env node`, so its own Node must come first on PATH.
|
|
@@ -64,8 +72,7 @@ export function npmOf(ctx, windows) {
|
|
|
64
72
|
return { path: beside, env: { ...ctx.env, PATH } };
|
|
65
73
|
}
|
|
66
74
|
// A step without a signal must finish, so it leaves the terminal's process group and its Ctrl-C.
|
|
67
|
-
function spawnNpm(args, ctx, signal) {
|
|
68
|
-
const npm = npmOf(ctx, process.platform === "win32");
|
|
75
|
+
function spawnNpm(npm, args, ctx, signal) {
|
|
69
76
|
return spawnChild(npm.path, args, {
|
|
70
77
|
cwd: ctx.cwd,
|
|
71
78
|
env: npm.env,
|
|
@@ -140,7 +147,8 @@ function noLatest(ctx, message) {
|
|
|
140
147
|
export async function runNpm(call, args, ctx, signal = ctx.signal) {
|
|
141
148
|
const cache = await mkdtemp(join(tmpdir(), `${ctx.cliName}-npm-`));
|
|
142
149
|
try {
|
|
143
|
-
const
|
|
150
|
+
const npm = await npmOf(ctx);
|
|
151
|
+
const answer = await spawnNpm(npm, [...args, `--cache=${join(cache, "cache")}`, "--logs-max=0"], ctx, signal).catch((error) => {
|
|
144
152
|
if (signal?.aborted === true)
|
|
145
153
|
throw signal.reason;
|
|
146
154
|
throw new CliError({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../src/built-ins/npm.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../src/built-ins/npm.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
import type { Files } from "../context/files.js";
|
|
2
3
|
declare const MANAGERS: readonly ["pnpm", "npm", "yarn", "bun"];
|
|
3
4
|
export type PackageManager = (typeof MANAGERS)[number];
|
|
4
5
|
/** The folder whose lockfile pins the project's packages, and the package manager that writes it. */
|
|
@@ -14,11 +15,10 @@ declare const manifestSchema: z.ZodObject<{
|
|
|
14
15
|
type Manifest = z.infer<typeof manifestSchema>;
|
|
15
16
|
/** `dir` and every folder above it, nearest first. */
|
|
16
17
|
export declare function ancestorsOf(dir: string): string[];
|
|
17
|
-
export declare function exists(path: string): Promise<boolean>;
|
|
18
18
|
/** Whether `path` lies strictly inside `dir`. */
|
|
19
19
|
export declare function isInside(dir: string, path: string): boolean;
|
|
20
|
-
export declare function manifestIn(dir: string): Promise<Manifest | undefined>;
|
|
21
|
-
export declare function lockfileRootOf(cwd: string): Promise<LockfileRoot | undefined>;
|
|
20
|
+
export declare function manifestIn(files: Files, dir: string): Promise<Manifest | undefined>;
|
|
21
|
+
export declare function lockfileRootOf(files: Files, cwd: string): Promise<LockfileRoot | undefined>;
|
|
22
22
|
/** The package manager's project root: the folder of the nearest lockfile, or `cwd` without one. */
|
|
23
|
-
export declare function projectRootOf(cwd: string): Promise<string>;
|
|
23
|
+
export declare function projectRootOf(files: Files, cwd: string): Promise<string>;
|
|
24
24
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { readFile, stat } from "node:fs/promises";
|
|
2
1
|
import { dirname, isAbsolute, join, relative } from "node:path";
|
|
3
2
|
import * as z from "zod";
|
|
4
|
-
import {
|
|
3
|
+
import { readIfAny } from "./read.js";
|
|
5
4
|
const MANAGERS = ["pnpm", "npm", "yarn", "bun"];
|
|
6
5
|
const LOCKFILES = [
|
|
7
6
|
["pnpm-lock.yaml", "pnpm"],
|
|
@@ -20,25 +19,16 @@ export function ancestorsOf(dir) {
|
|
|
20
19
|
const parent = dirname(dir);
|
|
21
20
|
return parent === dir ? [dir] : [dir, ...ancestorsOf(parent)];
|
|
22
21
|
}
|
|
23
|
-
export async function exists(path) {
|
|
24
|
-
return (await orMissing(stat(path))) !== undefined;
|
|
25
|
-
}
|
|
26
22
|
/** Whether `path` lies strictly inside `dir`. */
|
|
27
23
|
export function isInside(dir, path) {
|
|
28
24
|
const inner = relative(dir, path);
|
|
29
25
|
return inner !== "" && !inner.startsWith("..") && !isAbsolute(inner);
|
|
30
26
|
}
|
|
31
27
|
// An unreadable package.json names no package manager and lists no package; the lockfile still names the manager.
|
|
32
|
-
export async function manifestIn(dir) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
if (isMissingFile(error))
|
|
39
|
-
return undefined;
|
|
40
|
-
throw error;
|
|
41
|
-
}
|
|
28
|
+
export async function manifestIn(files, dir) {
|
|
29
|
+
const text = await readIfAny(files, join(dir, "package.json"));
|
|
30
|
+
if (text === undefined)
|
|
31
|
+
return undefined;
|
|
42
32
|
let manifest;
|
|
43
33
|
try {
|
|
44
34
|
manifest = JSON.parse(text);
|
|
@@ -48,22 +38,22 @@ export async function manifestIn(dir) {
|
|
|
48
38
|
}
|
|
49
39
|
return manifestSchema.safeParse(manifest).data;
|
|
50
40
|
}
|
|
51
|
-
async function declaredManager(dir) {
|
|
52
|
-
const name = (await manifestIn(dir))?.packageManager?.split("@")[0];
|
|
41
|
+
async function declaredManager(files, dir) {
|
|
42
|
+
const name = (await manifestIn(files, dir))?.packageManager?.split("@")[0];
|
|
53
43
|
return MANAGERS.find((manager) => manager === name);
|
|
54
44
|
}
|
|
55
|
-
export async function lockfileRootOf(cwd) {
|
|
45
|
+
export async function lockfileRootOf(files, cwd) {
|
|
56
46
|
for (const dir of ancestorsOf(cwd)) {
|
|
57
47
|
for (const [file, kind] of LOCKFILES) {
|
|
58
|
-
if (await exists(join(dir, file))) {
|
|
59
|
-
return { dir, manager: (await declaredManager(dir)) ?? kind };
|
|
48
|
+
if (await files.exists(join(dir, file))) {
|
|
49
|
+
return { dir, manager: (await declaredManager(files, dir)) ?? kind };
|
|
60
50
|
}
|
|
61
51
|
}
|
|
62
52
|
}
|
|
63
53
|
return undefined;
|
|
64
54
|
}
|
|
65
55
|
/** The package manager's project root: the folder of the nearest lockfile, or `cwd` without one. */
|
|
66
|
-
export async function projectRootOf(cwd) {
|
|
67
|
-
return (await lockfileRootOf(cwd))?.dir ?? cwd;
|
|
56
|
+
export async function projectRootOf(files, cwd) {
|
|
57
|
+
return (await lockfileRootOf(files, cwd))?.dir ?? cwd;
|
|
68
58
|
}
|
|
69
59
|
//# sourceMappingURL=project-root.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-root.js","sourceRoot":"","sources":["../../src/built-ins/project-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"project-root.js","sourceRoot":"","sources":["../../src/built-ins/project-root.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Files } from "../context/files.js";
|
|
2
|
+
/** The text of the file at `path`, or `undefined` when nothing is there. */
|
|
3
|
+
export declare function readIfAny(files: Files, path: string): Promise<string | undefined>;
|
|
4
|
+
/** The text of a file the CLI's own package ships, whose absence is the release's bug. */
|
|
5
|
+
export declare function readRequired(files: Files, path: string): Promise<string>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { NOT_FOUND } from "../context/errno.js";
|
|
2
|
+
import { CliError } from "../errors.js";
|
|
3
|
+
function isNotFound(error) {
|
|
4
|
+
return error instanceof CliError && error.code === NOT_FOUND;
|
|
5
|
+
}
|
|
6
|
+
const decoder = new TextDecoder();
|
|
7
|
+
/** The text of the file at `path`, or `undefined` when nothing is there. */
|
|
8
|
+
export async function readIfAny(files, path) {
|
|
9
|
+
try {
|
|
10
|
+
return decoder.decode(await files.read(path));
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (isNotFound(error))
|
|
14
|
+
return undefined;
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** The text of a file the CLI's own package ships, whose absence is the release's bug. */
|
|
19
|
+
export async function readRequired(files, path) {
|
|
20
|
+
try {
|
|
21
|
+
return decoder.decode(await files.read(path));
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
if (!isNotFound(error))
|
|
25
|
+
throw error;
|
|
26
|
+
throw new Error(`the package is missing its own file ${path}`, { cause: error });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/built-ins/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,KAAK,YAAY,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;AAC/D,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAY,EAAE,IAAY;IACxD,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,UAAU,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QACxC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAY,EAAE,IAAY;IAC3D,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,MAAM,KAAK,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,uCAAuC,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Command, GlobalInstall } from "../define.js";
|
|
2
2
|
import type { Launch } from "./commands.js";
|
|
3
3
|
import type { SkillCli } from "./skill/skill.js";
|
|
4
|
-
export declare const NOT_ON_PATH = "NOT_ON_PATH";
|
|
5
4
|
/** The built-in `setup`, which runs from any copy, such as npx's, so it never asks to be the global one. */
|
|
6
|
-
export declare function setupCommand(cli: SkillCli, install: GlobalInstall,
|
|
5
|
+
export declare function setupCommand(cli: SkillCli, install: GlobalInstall, launch: Launch): Command;
|
package/dist/built-ins/setup.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { lstat, readFile, realpath } from "node:fs/promises";
|
|
2
1
|
import { delimiter, join, normalize } from "node:path";
|
|
3
2
|
import * as z from "zod";
|
|
4
3
|
import { DISK_FULL, PERMISSION_DENIED } from "../context/errno.js";
|
|
5
4
|
import { INTERRUPTED } from "../context/interrupts.js";
|
|
6
5
|
import { pathOf } from "../context/tools.js";
|
|
7
6
|
import { defineCommand } from "../define-command.js";
|
|
8
|
-
import { CliError,
|
|
7
|
+
import { CliError, errnoOf, runtimeError } from "../errors.js";
|
|
9
8
|
import { wholeLine } from "../next-step.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { INSTALL_FAILED, NOT_GLOBAL_INSTALL, NOT_ON_PATH } from "../runtime-codes.js";
|
|
10
|
+
import { globalModulesDir, globalNpm, isLink, setupLineOf } from "./install/global-npm.js";
|
|
11
|
+
import { globalPrefix, installGlobally, latestVersion, NPM_ERRORS, } from "./npm.js";
|
|
12
|
+
import { readIfAny } from "./read.js";
|
|
12
13
|
import { standingOf } from "./semver.js";
|
|
13
14
|
import { homeCopiesOf, homeSyncSchema, renderHomeSync, renderPlannedSync, syncHome, } from "./skill/home.js";
|
|
14
15
|
import { renderUpgrade, upgradeSchema, upgradesOf } from "./upgrades.js";
|
|
15
|
-
export const NOT_ON_PATH = "NOT_ON_PATH";
|
|
16
16
|
const setupSchema = z.object({
|
|
17
17
|
version: z.string(),
|
|
18
18
|
prefix: z.string(),
|
|
@@ -22,8 +22,8 @@ const setupSchema = z.object({
|
|
|
22
22
|
docs: z.string().nullable(),
|
|
23
23
|
});
|
|
24
24
|
const installedManifest = z.object({ version: z.string() });
|
|
25
|
-
async function versionAt(packageDir) {
|
|
26
|
-
const text = await
|
|
25
|
+
async function versionAt(files, packageDir) {
|
|
26
|
+
const text = await readIfAny(files, join(packageDir, "package.json"));
|
|
27
27
|
if (text === undefined)
|
|
28
28
|
return null;
|
|
29
29
|
try {
|
|
@@ -38,25 +38,30 @@ async function versionAt(packageDir) {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
// The Run-as would not run yet, so every Next step is the line that started this.
|
|
41
|
-
function npmOfSetup(cli, install, ctx,
|
|
42
|
-
return { ...globalNpm(cli, install, ctx,
|
|
41
|
+
function npmOfSetup(cli, install, ctx, launch) {
|
|
42
|
+
return { ...globalNpm(cli, install, ctx, launch), rerun: wholeLine(setupLineOf(install)) };
|
|
43
43
|
}
|
|
44
44
|
function needsInstall({ from, latest }) {
|
|
45
45
|
return from === null || standingOf(from, latest) === "behind";
|
|
46
46
|
}
|
|
47
|
-
function binDirOf(prefix) {
|
|
48
|
-
return
|
|
47
|
+
function binDirOf(prefix, platform) {
|
|
48
|
+
return platform === "win32" ? prefix : join(prefix, "bin");
|
|
49
49
|
}
|
|
50
50
|
// A PATH entry that cannot be resolved still compares as written, so it only fails to match.
|
|
51
|
-
async function canonical(path) {
|
|
52
|
-
|
|
51
|
+
async function canonical(files, path) {
|
|
52
|
+
const real = await files.realPath(path).catch((error) => {
|
|
53
|
+
if (!(error instanceof CliError) && errnoOf(error) === undefined)
|
|
54
|
+
throw error;
|
|
55
|
+
return undefined;
|
|
56
|
+
});
|
|
57
|
+
return normalize(real ?? path);
|
|
53
58
|
}
|
|
54
59
|
// npx puts its own copy's bin on PATH, so only the global folder's place there tells a later shell finds it.
|
|
55
|
-
async function assertOnPath(cli, prefix, node, ctx) {
|
|
56
|
-
const binDir = binDirOf(prefix);
|
|
57
|
-
const wanted = await canonical(binDir);
|
|
60
|
+
async function assertOnPath(cli, prefix, { node, platform }, ctx) {
|
|
61
|
+
const binDir = binDirOf(prefix, platform);
|
|
62
|
+
const wanted = await canonical(ctx.files, binDir);
|
|
58
63
|
const entries = pathOf(ctx.env).split(delimiter).filter(Boolean);
|
|
59
|
-
const found = await Promise.all(entries.map(canonical));
|
|
64
|
+
const found = await Promise.all(entries.map((entry) => canonical(ctx.files, entry)));
|
|
60
65
|
if (found.includes(wanted))
|
|
61
66
|
return;
|
|
62
67
|
throw runtimeError({
|
|
@@ -92,7 +97,7 @@ function renderSetup(cli, install, setup) {
|
|
|
92
97
|
].join("\n");
|
|
93
98
|
}
|
|
94
99
|
/** The built-in `setup`, which runs from any copy, such as npx's, so it never asks to be the global one. */
|
|
95
|
-
export function setupCommand(cli, install,
|
|
100
|
+
export function setupCommand(cli, install, launch) {
|
|
96
101
|
return defineCommand({
|
|
97
102
|
description: "install this CLI and its skill on this machine",
|
|
98
103
|
examples: [
|
|
@@ -100,13 +105,14 @@ export function setupCommand(cli, install, { node }) {
|
|
|
100
105
|
{ command: `${cli.name} setup --dry-run`, note: "show what it would change" },
|
|
101
106
|
],
|
|
102
107
|
effect: "write",
|
|
108
|
+
errors: [NOT_GLOBAL_INSTALL, NOT_ON_PATH, ...NPM_ERRORS],
|
|
103
109
|
output: setupSchema,
|
|
104
110
|
plan: async (_input, ctx) => {
|
|
105
|
-
const npm = npmOfSetup(cli, install, ctx,
|
|
111
|
+
const npm = npmOfSetup(cli, install, ctx, launch);
|
|
106
112
|
const prefix = await globalPrefix(npm);
|
|
107
|
-
const packageDir = join(globalModulesDir(prefix), install.package);
|
|
113
|
+
const packageDir = join(globalModulesDir(prefix, launch.platform), install.package);
|
|
108
114
|
// `npm link` puts a symlink to a source checkout where the install would be.
|
|
109
|
-
if (
|
|
115
|
+
if (await isLink(ctx.files, packageDir)) {
|
|
110
116
|
throw runtimeError({
|
|
111
117
|
code: NOT_GLOBAL_INSTALL,
|
|
112
118
|
message: `${packageDir} is a link (npm link), which an install would replace`,
|
|
@@ -116,11 +122,11 @@ export function setupCommand(cli, install, { node }) {
|
|
|
116
122
|
}
|
|
117
123
|
return {
|
|
118
124
|
package: install.package,
|
|
119
|
-
from: await versionAt(packageDir),
|
|
125
|
+
from: await versionAt(ctx.files, packageDir),
|
|
120
126
|
latest: await latestVersion(npm),
|
|
121
127
|
prefix,
|
|
122
128
|
packageDir,
|
|
123
|
-
copies: cli.skill === undefined ? [] : await homeCopiesOf(cli.name, ctx.env),
|
|
129
|
+
copies: cli.skill === undefined ? [] : await homeCopiesOf(ctx.files, cli.name, ctx.env),
|
|
124
130
|
};
|
|
125
131
|
},
|
|
126
132
|
apply: async (plan, ctx) => {
|
|
@@ -130,7 +136,7 @@ export function setupCommand(cli, install, { node }) {
|
|
|
130
136
|
.runToEnd(`installing ${plan.package}@${latest}`, async () => {
|
|
131
137
|
if (installs) {
|
|
132
138
|
ctx.progress(`installing ${plan.package}@${latest} with the npm under ${prefix}…`);
|
|
133
|
-
await installGlobally(latest, npmOfSetup(cli, install, ctx,
|
|
139
|
+
await installGlobally(latest, npmOfSetup(cli, install, ctx, launch));
|
|
134
140
|
}
|
|
135
141
|
return syncHome(cli, packageDir, ctx);
|
|
136
142
|
})
|
|
@@ -142,7 +148,7 @@ export function setupCommand(cli, install, { node }) {
|
|
|
142
148
|
prefix,
|
|
143
149
|
installed: installs,
|
|
144
150
|
skill,
|
|
145
|
-
upgrades: installs && from !== null ? await upgradesOf(packageDir, from, latest) : [],
|
|
151
|
+
upgrades: installs && from !== null ? await upgradesOf(ctx.files, packageDir, from, latest) : [],
|
|
146
152
|
docs: cli.docs === undefined ? null : join(packageDir, cli.docs),
|
|
147
153
|
};
|
|
148
154
|
ctx.deliver(setup);
|
|
@@ -153,7 +159,7 @@ export function setupCommand(cli, install, { node }) {
|
|
|
153
159
|
hint: "nothing to run again",
|
|
154
160
|
});
|
|
155
161
|
}
|
|
156
|
-
await assertOnPath(cli, prefix,
|
|
162
|
+
await assertOnPath(cli, prefix, launch, ctx);
|
|
157
163
|
return setup;
|
|
158
164
|
},
|
|
159
165
|
render: (setup) => renderSetup(cli, install, setup),
|