@duyquangnvx/agent-cli 0.4.0 → 0.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/CHANGELOG.md +46 -0
- package/dist/agent-cli.js +1 -1
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent.d.ts +5 -3
- package/dist/agent.js +31 -10
- package/dist/agent.js.map +1 -1
- package/dist/built-ins.d.ts +6 -1
- package/dist/built-ins.js +3 -3
- package/dist/built-ins.js.map +1 -1
- package/dist/command-spec.d.ts +5 -0
- package/dist/command-spec.js +7 -0
- package/dist/command-spec.js.map +1 -1
- package/dist/confirm.js +6 -2
- package/dist/confirm.js.map +1 -1
- package/dist/context.d.ts +102 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/cost.js +2 -2
- package/dist/cost.js.map +1 -1
- package/dist/define.d.ts +35 -80
- package/dist/define.js +3 -1
- package/dist/define.js.map +1 -1
- package/dist/doctor-rows.d.ts +2 -1
- package/dist/doctor-rows.js +15 -10
- package/dist/doctor-rows.js.map +1 -1
- package/dist/doctor.d.ts +2 -1
- package/dist/doctor.js +24 -17
- package/dist/doctor.js.map +1 -1
- package/dist/errno.d.ts +8 -4
- package/dist/errno.js +21 -4
- package/dist/errno.js.map +1 -1
- package/dist/errors.d.ts +2 -1
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -1
- package/dist/execute.d.ts +9 -2
- package/dist/execute.js +10 -3
- package/dist/execute.js.map +1 -1
- package/dist/exit-classes.js +4 -1
- package/dist/exit-classes.js.map +1 -1
- package/dist/files.d.ts +23 -6
- package/dist/files.js +100 -14
- package/dist/files.js.map +1 -1
- package/dist/help-json.d.ts +1 -1
- package/dist/help-json.js +4 -1
- package/dist/help-json.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.js +11 -7
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +7 -1
- package/dist/input.js +33 -4
- package/dist/input.js.map +1 -1
- package/dist/interrupts.d.ts +3 -1
- package/dist/interrupts.js +4 -3
- package/dist/interrupts.js.map +1 -1
- package/dist/invocation.d.ts +10 -5
- package/dist/invocation.js +24 -11
- package/dist/invocation.js.map +1 -1
- package/dist/list.js +5 -2
- package/dist/list.js.map +1 -1
- package/dist/npm.d.ts +5 -2
- package/dist/npm.js +23 -31
- package/dist/npm.js.map +1 -1
- package/dist/operator.d.ts +5 -0
- package/dist/operator.js +15 -0
- package/dist/operator.js.map +1 -0
- package/dist/output.d.ts +4 -1
- package/dist/output.js +4 -0
- package/dist/output.js.map +1 -1
- package/dist/outputs.d.ts +24 -1
- package/dist/outputs.js +58 -2
- package/dist/outputs.js.map +1 -1
- package/dist/parse-input.d.ts +11 -2
- package/dist/parse-input.js +68 -26
- package/dist/parse-input.js.map +1 -1
- package/dist/project.d.ts +1 -1
- package/dist/route.d.ts +1 -1
- package/dist/route.js +2 -1
- package/dist/route.js.map +1 -1
- package/dist/run-cli.d.ts +16 -2
- package/dist/run-cli.js +89 -34
- package/dist/run-cli.js.map +1 -1
- package/dist/run-process.js +3 -2
- package/dist/run-process.js.map +1 -1
- package/dist/secrets.d.ts +5 -4
- package/dist/secrets.js +4 -5
- package/dist/secrets.js.map +1 -1
- package/dist/skill-source.d.ts +4 -0
- package/dist/skill-source.js +42 -0
- package/dist/skill-source.js.map +1 -0
- package/dist/skills.d.ts +2 -1
- package/dist/skills.js +4 -0
- package/dist/skills.js.map +1 -1
- package/dist/spawn.d.ts +22 -5
- package/dist/spawn.js +126 -29
- package/dist/spawn.js.map +1 -1
- package/dist/spill.d.ts +4 -3
- package/dist/spill.js +1 -7
- package/dist/spill.js.map +1 -1
- package/dist/stdin.d.ts +13 -0
- package/dist/stdin.js +55 -0
- package/dist/stdin.js.map +1 -0
- package/dist/style.d.ts +1 -1
- package/dist/tokenize.d.ts +3 -0
- package/dist/tokenize.js +5 -4
- package/dist/tokenize.js.map +1 -1
- package/dist/tools.d.ts +6 -3
- package/dist/tools.js +18 -11
- package/dist/tools.js.map +1 -1
- package/dist/update.d.ts +2 -1
- package/dist/update.js +3 -3
- package/dist/update.js.map +1 -1
- package/package.json +1 -1
package/dist/secrets.js
CHANGED
|
@@ -2,13 +2,12 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { parseEnv } from "node:util";
|
|
5
|
-
import { classifyErrno } from "./errno.js";
|
|
6
5
|
import { isMissingFile } from "./errors.js";
|
|
7
6
|
function dotenvPath(cliName, env) {
|
|
8
7
|
const config = env.XDG_CONFIG_HOME || join(env.HOME || homedir(), ".config");
|
|
9
8
|
return join(config, cliName, ".env");
|
|
10
9
|
}
|
|
11
|
-
function readDotenv(path,
|
|
10
|
+
function readDotenv(path, fileError) {
|
|
12
11
|
let text;
|
|
13
12
|
try {
|
|
14
13
|
text = readFileSync(path, "utf8");
|
|
@@ -16,17 +15,17 @@ function readDotenv(path, env, callerLine) {
|
|
|
16
15
|
catch (error) {
|
|
17
16
|
if (isMissingFile(error))
|
|
18
17
|
return {};
|
|
19
|
-
throw
|
|
18
|
+
throw fileError(error, { path, access: "read" });
|
|
20
19
|
}
|
|
21
20
|
return parseEnv(text);
|
|
22
21
|
}
|
|
23
22
|
/** Looks `name` up in the env, then in `$XDG_CONFIG_HOME/<cli>/.env`; an empty value counts as unset. */
|
|
24
|
-
export function secretOf({ cliName, env,
|
|
23
|
+
export function secretOf({ cliName, env, fileError }, name) {
|
|
25
24
|
const fromEnv = env[name];
|
|
26
25
|
if (fromEnv)
|
|
27
26
|
return { value: fromEnv, origin: { kind: "env" } };
|
|
28
27
|
const path = dotenvPath(cliName, env);
|
|
29
|
-
const fromFile = readDotenv(path,
|
|
28
|
+
const fromFile = readDotenv(path, fileError)[name];
|
|
30
29
|
return fromFile ? { value: fromFile, origin: { kind: "file", path } } : undefined;
|
|
31
30
|
}
|
|
32
31
|
//# sourceMappingURL=secrets.js.map
|
package/dist/secrets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAW5C,SAAS,UAAU,CAAC,OAAe,EAAE,GAAQ;IAC3C,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC7E,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,UAAU,CACjB,IAAY,EACZ,SAAoB;IAEpB,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,aAAa,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACpC,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AASD,yGAAyG;AACzG,MAAM,UAAU,QAAQ,CACtB,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAe,EACxC,IAAY;IAEZ,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;IAChE,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import * as z from "zod";
|
|
4
|
+
/** The branch a release moves to the released commit, which holds the skill of that version. */
|
|
5
|
+
const RELEASE_BRANCH = "release";
|
|
6
|
+
const GITHUB_SHORTHAND = /^[\w.-]+\/[\w.-]+$/;
|
|
7
|
+
const GIT_URL_PROTOCOLS = new Set(["https:", "http:", "ssh:", "git:"]);
|
|
8
|
+
const SCP_STYLE = /^[\w.-]+@[\w.-]+:[\w./-]+$/;
|
|
9
|
+
const manifestSchema = z.object({
|
|
10
|
+
repository: z.union([z.string(), z.object({ url: z.string() })]).optional(),
|
|
11
|
+
});
|
|
12
|
+
// skills@1.7.2 clones a non-GitHub source only when it ends in `.git`, and takes the branch from `#ref`.
|
|
13
|
+
function sourceFromRepository(repository) {
|
|
14
|
+
if (GITHUB_SHORTHAND.test(repository))
|
|
15
|
+
return repository;
|
|
16
|
+
const url = repository.replace(/^git\+/, "");
|
|
17
|
+
const isGitUrl = URL.canParse(url) && GIT_URL_PROTOCOLS.has(new URL(url).protocol);
|
|
18
|
+
if (!isGitUrl && !SCP_STYLE.test(url))
|
|
19
|
+
return undefined;
|
|
20
|
+
return `${url.endsWith(".git") ? url : `${url}.git`}#${RELEASE_BRANCH}`;
|
|
21
|
+
}
|
|
22
|
+
// The fix only helps, so a package.json that cannot be read or parsed gives none and the row stays ok.
|
|
23
|
+
async function repositoryAt(packageRoot) {
|
|
24
|
+
let manifest;
|
|
25
|
+
try {
|
|
26
|
+
manifest = JSON.parse(await readFile(join(packageRoot, "package.json"), "utf8"));
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const parsed = manifestSchema.safeParse(manifest);
|
|
32
|
+
const repository = parsed.success ? parsed.data.repository : undefined;
|
|
33
|
+
return typeof repository === "object" ? repository.url : repository;
|
|
34
|
+
}
|
|
35
|
+
/** What `npx skills add` installs the CLI's skill from: the declared source, else the package's repository. */
|
|
36
|
+
export async function skillSource(declared, packageRoot) {
|
|
37
|
+
if (declared !== undefined)
|
|
38
|
+
return declared.source;
|
|
39
|
+
const repository = await repositoryAt(packageRoot);
|
|
40
|
+
return repository === undefined ? undefined : sourceFromRepository(repository);
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=skill-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-source.js","sourceRoot":"","sources":["../src/skill-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,gGAAgG;AAChG,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAC9C,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACvE,MAAM,SAAS,GAAG,4BAA4B,CAAC;AAE/C,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC5E,CAAC,CAAC;AAEH,yGAAyG;AACzG,SAAS,oBAAoB,CAAC,UAAkB;IAC9C,IAAI,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IACzD,MAAM,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IACnF,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACxD,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC;AAC1E,CAAC;AAED,uGAAuG;AACvG,KAAK,UAAU,YAAY,CAAC,WAAmB;IAC7C,IAAI,QAAiB,CAAC;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,OAAO,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;AACtE,CAAC;AAED,+GAA+G;AAC/G,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAiD,EACjD,WAAmB;IAEnB,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC,MAAM,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;IACnD,OAAO,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;AACjF,CAAC"}
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { Env } from "./
|
|
1
|
+
import type { Env } from "./context.js";
|
|
2
2
|
import { type Standing } from "./semver.js";
|
|
3
3
|
export declare function skillUpdateCommand(cliName: string): string;
|
|
4
|
+
export declare function skillAddCommand(source: string, cliName: string): string;
|
|
4
5
|
export type SkillState = Standing | "unversioned" | "unreadable";
|
|
5
6
|
export interface SkillCopy {
|
|
6
7
|
readonly path: string;
|
package/dist/skills.js
CHANGED
|
@@ -11,6 +11,10 @@ const SKILL_DIRS = [
|
|
|
11
11
|
export function skillUpdateCommand(cliName) {
|
|
12
12
|
return `npx -y skills update ${cliName}`;
|
|
13
13
|
}
|
|
14
|
+
// `--skill` installs only this CLI's skill from a repo that holds several.
|
|
15
|
+
export function skillAddCommand(source, cliName) {
|
|
16
|
+
return `npx -y skills add ${source} --skill ${cliName} -g`;
|
|
17
|
+
}
|
|
14
18
|
const FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
15
19
|
const METADATA_VERSION = /^metadata:[ \t]*\r?\n(?:[ \t]+.*\r?\n)*?[ \t]+version:[ \t]*["']?([^"'\s]+)["']?[ \t]*$/m;
|
|
16
20
|
/** The version a SKILL.md's frontmatter `metadata.version` states. */
|
package/dist/skills.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"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"}
|
package/dist/spawn.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
import type { Env } from "./
|
|
1
|
+
import type { Env } from "./context.js";
|
|
2
|
+
import type { FileError } from "./errno.js";
|
|
2
3
|
export declare const TOOL_FAILED = "TOOL_FAILED";
|
|
3
4
|
export interface SpawnResult {
|
|
4
5
|
readonly stdout: string;
|
|
5
6
|
readonly stderr: string;
|
|
6
7
|
readonly exitCode: number;
|
|
7
8
|
}
|
|
8
|
-
/**
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Runs a child process to its end; a test replaces it through `runCli`. `onLine`, when given,
|
|
11
|
+
* receives each line of the child's stdout and stderr as it arrives, without its line ending.
|
|
12
|
+
*/
|
|
13
|
+
export type Spawn = (command: string, args: readonly string[], options: ChildOptions) => Promise<SpawnResult>;
|
|
14
|
+
interface ChildOptions {
|
|
10
15
|
readonly cwd: string;
|
|
11
16
|
readonly env: Env;
|
|
12
17
|
readonly signal: AbortSignal;
|
|
13
|
-
|
|
18
|
+
readonly onLine?: (line: string) => void;
|
|
19
|
+
}
|
|
14
20
|
export interface SpawnOptions {
|
|
15
21
|
/** `ctx.cwd` when absent. */
|
|
16
22
|
readonly cwd?: string;
|
|
@@ -18,12 +24,23 @@ export interface SpawnOptions {
|
|
|
18
24
|
readonly env?: Env;
|
|
19
25
|
/** Fails the run with `TOOL_FAILED` and the tail of the child's stderr when it exits non-zero. */
|
|
20
26
|
readonly check?: boolean;
|
|
27
|
+
/** Passes each line of the child's stdout and stderr through `ctx.progress` as it arrives. */
|
|
28
|
+
readonly progress?: boolean;
|
|
21
29
|
}
|
|
22
30
|
export type ContextSpawn = (command: string, args?: readonly string[], options?: SpawnOptions) => Promise<SpawnResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Runs a child process to its end; it is killed on abort, and the promise settles only once it has
|
|
33
|
+
* exited. A `detached` child leaves the terminal's process group on POSIX, and so its Ctrl-C.
|
|
34
|
+
*/
|
|
35
|
+
export declare function spawnChild(command: string, args: readonly string[], { cwd, env, signal, onLine, detached }: ChildOptions & {
|
|
36
|
+
readonly detached?: boolean;
|
|
37
|
+
}): Promise<SpawnResult>;
|
|
23
38
|
export declare const realSpawn: Spawn;
|
|
24
39
|
/** `ctx.spawn`: `spawn` bound to the run, its start failures classified by errno. */
|
|
25
40
|
export declare function contextSpawn(run: Spawn, defaults: {
|
|
26
41
|
readonly cwd: string;
|
|
27
42
|
readonly env: Env;
|
|
28
43
|
readonly signal: AbortSignal;
|
|
29
|
-
|
|
44
|
+
readonly progress: (message: string) => void;
|
|
45
|
+
}, fileError: FileError): ContextSpawn;
|
|
46
|
+
export {};
|
package/dist/spawn.js
CHANGED
|
@@ -1,42 +1,138 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { constants } from "node:os";
|
|
3
|
-
import { classifyErrno } from "./errno.js";
|
|
4
3
|
import { CliError, isMissingFile } from "./errors.js";
|
|
5
4
|
import { lastLines } from "./tail.js";
|
|
6
|
-
import { TOOL_MISSING } from "./tools.js";
|
|
5
|
+
import { findTool, TOOL_MISSING } from "./tools.js";
|
|
7
6
|
export const TOOL_FAILED = "TOOL_FAILED";
|
|
8
7
|
const STDERR_TAIL_LINES = 20;
|
|
9
8
|
// A shell reports a child killed by a signal as 128 plus the signal's number.
|
|
10
9
|
const SIGNAL_EXIT_BASE = 128;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
const BATCH_FILE = /\.(?:cmd|bat)$/i;
|
|
11
|
+
const CMD_SHIM = /\.cmd$/i;
|
|
12
|
+
// What cmd.exe acts on even inside quotes, as cross-spawn escapes it.
|
|
13
|
+
const CMD_META = /([()\][%!^"`<>&|;, *?])/g;
|
|
14
|
+
const PATH_SEPARATOR = /[\\/]/;
|
|
15
|
+
const TRAILING_CR = /\r$/;
|
|
16
|
+
function escapedForCmd(text) {
|
|
17
|
+
return text.replace(CMD_META, "^$1");
|
|
18
|
+
}
|
|
19
|
+
// Quoted as the C runtime splits a command line, then escaped for cmd.exe (BatBadBut). npm's .cmd
|
|
20
|
+
// shims hand `%*` to a second cmd.exe parse, so their arguments are escaped twice, as cross-spawn does.
|
|
21
|
+
function batchArgument(arg, shim) {
|
|
22
|
+
const quoted = `"${arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1")}"`;
|
|
23
|
+
const escaped = escapedForCmd(quoted);
|
|
24
|
+
return shim ? escapedForCmd(escaped) : escaped;
|
|
25
|
+
}
|
|
26
|
+
// A batch file runs only through cmd.exe, so it and its arguments go escaped on one command line.
|
|
27
|
+
// The command is never quoted: cmd.exe resolves %~dp0 against the working directory for a quoted
|
|
28
|
+
// batch name found on PATH.
|
|
29
|
+
function batchCommandLine(command, file, args) {
|
|
30
|
+
const shim = CMD_SHIM.test(file);
|
|
31
|
+
return [escapedForCmd(command), ...args.map((arg) => batchArgument(arg, shim))].join(" ");
|
|
32
|
+
}
|
|
33
|
+
async function windowsLaunch(command, args, env) {
|
|
34
|
+
const file = PATH_SEPARATOR.test(command) ? command : await findTool(command, env);
|
|
35
|
+
if (file === undefined || !BATCH_FILE.test(file))
|
|
36
|
+
return { command, args, shell: false };
|
|
37
|
+
return { command: batchCommandLine(command, file, args), args: [], shell: true };
|
|
38
|
+
}
|
|
39
|
+
// On Windows, killing cmd.exe or a launcher leaves its children running; only a tree kill reaches them.
|
|
40
|
+
function stop(child) {
|
|
41
|
+
if (process.platform !== "win32" || child.pid === undefined) {
|
|
20
42
|
child.kill();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
child.
|
|
24
|
-
|
|
25
|
-
|
|
43
|
+
return Promise.resolve();
|
|
44
|
+
}
|
|
45
|
+
const pid = String(child.pid);
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
const taskkill = spawn("taskkill", ["/pid", pid, "/t", "/f"], {
|
|
48
|
+
stdio: "ignore",
|
|
49
|
+
windowsHide: true,
|
|
50
|
+
});
|
|
51
|
+
taskkill.once("error", () => {
|
|
52
|
+
// Without taskkill, killing the child itself is the most that can be done.
|
|
53
|
+
child.kill();
|
|
54
|
+
resolve();
|
|
55
|
+
});
|
|
56
|
+
taskkill.once("exit", () => resolve());
|
|
26
57
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
58
|
+
}
|
|
59
|
+
/** Calls `onLine` with each complete line pushed, and with the unterminated rest at the end. */
|
|
60
|
+
function lineSplitter(onLine) {
|
|
61
|
+
let rest = "";
|
|
62
|
+
const emit = (line) => onLine?.(line.replace(TRAILING_CR, ""));
|
|
63
|
+
return {
|
|
64
|
+
push(text) {
|
|
65
|
+
if (onLine === undefined)
|
|
66
|
+
return;
|
|
67
|
+
const lines = (rest + text).split("\n");
|
|
68
|
+
rest = lines.pop() ?? "";
|
|
69
|
+
for (const line of lines)
|
|
70
|
+
emit(line);
|
|
71
|
+
},
|
|
72
|
+
end() {
|
|
73
|
+
if (rest !== "")
|
|
74
|
+
emit(rest);
|
|
75
|
+
rest = "";
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Runs a child process to its end; it is killed on abort, and the promise settles only once it has
|
|
81
|
+
* exited. A `detached` child leaves the terminal's process group on POSIX, and so its Ctrl-C.
|
|
82
|
+
*/
|
|
83
|
+
export async function spawnChild(command, args, { cwd, env, signal, onLine, detached = false }) {
|
|
84
|
+
signal.throwIfAborted();
|
|
85
|
+
const launch = process.platform === "win32"
|
|
86
|
+
? await windowsLaunch(command, args, env)
|
|
87
|
+
: { command, args, shell: false };
|
|
88
|
+
signal.throwIfAborted();
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
const child = spawn(launch.command, launch.args, {
|
|
91
|
+
cwd,
|
|
92
|
+
env,
|
|
93
|
+
shell: launch.shell,
|
|
94
|
+
windowsHide: true,
|
|
95
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
96
|
+
detached: detached && process.platform !== "win32",
|
|
97
|
+
});
|
|
98
|
+
let stdout = "";
|
|
99
|
+
let stderr = "";
|
|
100
|
+
const stdoutLines = lineSplitter(onLine);
|
|
101
|
+
const stderrLines = lineSplitter(onLine);
|
|
102
|
+
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
103
|
+
stdout += chunk;
|
|
104
|
+
stdoutLines.push(chunk);
|
|
105
|
+
});
|
|
106
|
+
child.stderr.setEncoding("utf8").on("data", (chunk) => {
|
|
107
|
+
stderr += chunk;
|
|
108
|
+
stderrLines.push(chunk);
|
|
109
|
+
});
|
|
110
|
+
let stopped = Promise.resolve();
|
|
111
|
+
const kill = () => {
|
|
112
|
+
stopped = stop(child);
|
|
113
|
+
};
|
|
114
|
+
signal.addEventListener("abort", kill, { once: true });
|
|
115
|
+
child.on("error", (error) => {
|
|
116
|
+
signal.removeEventListener("abort", kill);
|
|
117
|
+
reject(error);
|
|
118
|
+
});
|
|
119
|
+
child.on("close", (code, killedBy) => {
|
|
120
|
+
signal.removeEventListener("abort", kill);
|
|
121
|
+
if (signal.aborted) {
|
|
122
|
+
void stopped.then(() => reject(signal.reason));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
stdoutLines.end();
|
|
126
|
+
stderrLines.end();
|
|
127
|
+
resolve({
|
|
128
|
+
stdout,
|
|
129
|
+
stderr,
|
|
130
|
+
exitCode: code ?? SIGNAL_EXIT_BASE + (killedBy === null ? 0 : constants.signals[killedBy]),
|
|
131
|
+
});
|
|
37
132
|
});
|
|
38
133
|
});
|
|
39
|
-
}
|
|
134
|
+
}
|
|
135
|
+
export const realSpawn = (command, args, options) => spawnChild(command, args, options);
|
|
40
136
|
function failedError(command, { exitCode, stderr }) {
|
|
41
137
|
const tail = lastLines(stderr, STDERR_TAIL_LINES);
|
|
42
138
|
return new CliError({
|
|
@@ -55,7 +151,7 @@ function missingError(command, cause) {
|
|
|
55
151
|
}, { cause });
|
|
56
152
|
}
|
|
57
153
|
/** `ctx.spawn`: `spawn` bound to the run, its start failures classified by errno. */
|
|
58
|
-
export function contextSpawn(run, defaults,
|
|
154
|
+
export function contextSpawn(run, defaults, fileError) {
|
|
59
155
|
return async (command, args = [], options = {}) => {
|
|
60
156
|
let result;
|
|
61
157
|
try {
|
|
@@ -63,12 +159,13 @@ export function contextSpawn(run, defaults, callerLine) {
|
|
|
63
159
|
cwd: options.cwd ?? defaults.cwd,
|
|
64
160
|
env: options.env ?? defaults.env,
|
|
65
161
|
signal: defaults.signal,
|
|
162
|
+
onLine: options.progress === true ? defaults.progress : undefined,
|
|
66
163
|
});
|
|
67
164
|
}
|
|
68
165
|
catch (error) {
|
|
69
166
|
if (isMissingFile(error))
|
|
70
167
|
throw missingError(command, error);
|
|
71
|
-
throw
|
|
168
|
+
throw fileError(error, { path: command, access: "read" });
|
|
72
169
|
}
|
|
73
170
|
if (options.check === true && result.exitCode !== 0) {
|
|
74
171
|
throw failedError(command, result);
|
package/dist/spawn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../src/spawn.ts"],"names":[],"mappings":"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"}
|
package/dist/spill.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Clock } from "./clock.js";
|
|
2
|
-
import type { Env } from "./
|
|
2
|
+
import type { Env } from "./context.js";
|
|
3
|
+
import type { FileError } from "./errno.js";
|
|
3
4
|
import type { Files } from "./files.js";
|
|
4
5
|
export interface SpillTarget {
|
|
5
6
|
readonly cliName: string;
|
|
@@ -8,8 +9,8 @@ export interface SpillTarget {
|
|
|
8
9
|
readonly clock: Clock;
|
|
9
10
|
/** Writes the spill file; its failures are already classified. */
|
|
10
11
|
readonly files: Files;
|
|
11
|
-
/**
|
|
12
|
-
readonly
|
|
12
|
+
/** Classifies a failure to prepare the spill folder. */
|
|
13
|
+
readonly fileError: FileError;
|
|
13
14
|
}
|
|
14
15
|
/** Turns printed data into what stdout carries: the data itself, or where it was spilled. */
|
|
15
16
|
export type Spill = (printed: string, json: boolean) => Promise<string>;
|
package/dist/spill.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { mkdir, readdir, rm, stat } from "node:fs/promises";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { classifyErrno } from "./errno.js";
|
|
5
4
|
import { isMissingFile } from "./errors.js";
|
|
6
5
|
const STDOUT_BUDGET_CHARS = 30_000;
|
|
7
6
|
const SPILL_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;
|
|
@@ -33,12 +32,7 @@ async function prepare(folder, cutoff, target) {
|
|
|
33
32
|
await pruneOld(folder, cutoff);
|
|
34
33
|
}
|
|
35
34
|
catch (error) {
|
|
36
|
-
throw
|
|
37
|
-
path: folder,
|
|
38
|
-
access: "write",
|
|
39
|
-
callerLine: target.callerLine,
|
|
40
|
-
env: target.env,
|
|
41
|
-
});
|
|
35
|
+
throw target.fileError(error, { path: folder, access: "write" });
|
|
42
36
|
}
|
|
43
37
|
}
|
|
44
38
|
// An empty TMPDIR means unset, as it does to the shell.
|
package/dist/spill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spill.js","sourceRoot":"","sources":["../src/spill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"spill.js","sourceRoot":"","sources":["../src/spill.ts"],"names":[],"mappings":"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"}
|
package/dist/stdin.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
export declare const STDIN_OPERAND = "-";
|
|
4
|
+
/** Marks a string arg as also taking its text from stdin when the caller passes `-`. */
|
|
5
|
+
export declare function orStdin<Schema extends z.ZodType<unknown, string>>(schema: Schema): Schema;
|
|
6
|
+
export declare function isStdinSchema(schema: z.ZodType): boolean;
|
|
7
|
+
/** Where a `-` operand's text comes from: a test's text, or a stream such as `process.stdin`. */
|
|
8
|
+
export type StdinSource = string | Readable;
|
|
9
|
+
/** The progress line shown before reading a terminal, so a person isn't left facing silence. */
|
|
10
|
+
export declare function readingLine(name: string, platform: NodeJS.Platform): string;
|
|
11
|
+
export declare function isTerminal(source: StdinSource): boolean;
|
|
12
|
+
/** The whole of `source` as UTF-8; rejects with the signal's reason once it aborts. */
|
|
13
|
+
export declare function readStdin(source: StdinSource, signal: AbortSignal): Promise<string>;
|
package/dist/stdin.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
export const STDIN_OPERAND = "-";
|
|
3
|
+
const STDIN_META = "stdin";
|
|
4
|
+
/** Marks a string arg as also taking its text from stdin when the caller passes `-`. */
|
|
5
|
+
export function orStdin(schema) {
|
|
6
|
+
return schema.meta({ [STDIN_META]: true });
|
|
7
|
+
}
|
|
8
|
+
export function isStdinSchema(schema) {
|
|
9
|
+
return z.globalRegistry.get(schema)?.[STDIN_META] === true;
|
|
10
|
+
}
|
|
11
|
+
function endOfInputKeys(platform) {
|
|
12
|
+
return platform === "win32" ? "Ctrl-Z then Enter" : "Ctrl-D";
|
|
13
|
+
}
|
|
14
|
+
/** The progress line shown before reading a terminal, so a person isn't left facing silence. */
|
|
15
|
+
export function readingLine(name, platform) {
|
|
16
|
+
return `reading <${name}> from stdin; end it with ${endOfInputKeys(platform)}`;
|
|
17
|
+
}
|
|
18
|
+
export function isTerminal(source) {
|
|
19
|
+
return typeof source !== "string" && "isTTY" in source && source.isTTY === true;
|
|
20
|
+
}
|
|
21
|
+
/** The whole of `source` as UTF-8; rejects with the signal's reason once it aborts. */
|
|
22
|
+
export function readStdin(source, signal) {
|
|
23
|
+
if (typeof source === "string") {
|
|
24
|
+
return signal.aborted ? Promise.reject(signal.reason) : Promise.resolve(source);
|
|
25
|
+
}
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const chunks = [];
|
|
28
|
+
const onData = (chunk) => {
|
|
29
|
+
chunks.push(chunk instanceof Uint8Array ? chunk : Buffer.from(String(chunk)));
|
|
30
|
+
};
|
|
31
|
+
const onEnd = () => {
|
|
32
|
+
stop();
|
|
33
|
+
resolve(Buffer.concat(chunks).toString("utf8"));
|
|
34
|
+
};
|
|
35
|
+
const onError = (error) => {
|
|
36
|
+
stop();
|
|
37
|
+
reject(error);
|
|
38
|
+
};
|
|
39
|
+
const onAbort = () => {
|
|
40
|
+
stop();
|
|
41
|
+
reject(signal.reason);
|
|
42
|
+
};
|
|
43
|
+
const stop = () => {
|
|
44
|
+
source.off("data", onData).off("end", onEnd).off("error", onError).pause();
|
|
45
|
+
signal.removeEventListener("abort", onAbort);
|
|
46
|
+
};
|
|
47
|
+
if (signal.aborted) {
|
|
48
|
+
reject(signal.reason);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
52
|
+
source.on("data", onData).once("end", onEnd).once("error", onError);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=stdin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdin.js","sourceRoot":"","sources":["../src/stdin.ts"],"names":[],"mappings":"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"}
|
package/dist/style.d.ts
CHANGED
package/dist/tokenize.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export interface Words {
|
|
|
15
15
|
readonly unknownOptions: readonly string[];
|
|
16
16
|
/** The last value of each known flag passed; `true` for a switch or a flag given no value. */
|
|
17
17
|
readonly values: ReadonlyMap<string, string | true>;
|
|
18
|
+
/** Every value of each known flag passed, in order. */
|
|
19
|
+
readonly occurrences: ReadonlyMap<string, readonly (string | true)[]>;
|
|
18
20
|
}
|
|
21
|
+
export declare function isOptionLike(word: string | undefined): boolean;
|
|
19
22
|
/** Splits a Command's words into operands, unknown options and the values of known flags. */
|
|
20
23
|
export declare function tokenize(words: readonly string[], known: readonly KnownFlag[]): Words;
|
package/dist/tokenize.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseArgs } from "node:util";
|
|
2
2
|
const NEGATIVE_NUMBER = /^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/;
|
|
3
|
-
function isOptionLike(word) {
|
|
3
|
+
export function isOptionLike(word) {
|
|
4
4
|
return word !== undefined && word.length > 1 && word[0] === "-" && !NEGATIVE_NUMBER.test(word);
|
|
5
5
|
}
|
|
6
6
|
// A flag taking an optional value is declared a switch, so that parseArgs never swallows the next
|
|
@@ -46,7 +46,7 @@ export function tokenize(words, known) {
|
|
|
46
46
|
});
|
|
47
47
|
const operands = [];
|
|
48
48
|
const unknownOptions = [];
|
|
49
|
-
const
|
|
49
|
+
const occurrences = new Map();
|
|
50
50
|
// A short group such as `-abc` yields one token per letter, all at the same index.
|
|
51
51
|
const done = new Set();
|
|
52
52
|
let literal = false;
|
|
@@ -69,11 +69,12 @@ export function tokenize(words, known) {
|
|
|
69
69
|
afterUnknownOption = true;
|
|
70
70
|
}
|
|
71
71
|
else {
|
|
72
|
-
|
|
72
|
+
occurrences.set(item.flag, [...(occurrences.get(item.flag) ?? []), item.value]);
|
|
73
73
|
if (item.took !== undefined)
|
|
74
74
|
done.add(item.took);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
const values = new Map([...occurrences].map(([flag, all]) => [flag, all[all.length - 1] ?? true]));
|
|
78
|
+
return { operands, unknownOptions, values, occurrences };
|
|
78
79
|
}
|
|
79
80
|
//# sourceMappingURL=tokenize.js.map
|
package/dist/tokenize.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,eAAe,GAAG,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { Env } from "./context.js";
|
|
2
|
+
import { type Commands, type DoctorCheck, type Tool } from "./define.js";
|
|
2
3
|
export declare const TOOL_MISSING = "TOOL_MISSING";
|
|
4
|
+
/** Where `name` is found on `PATH` from `env`, or undefined. */
|
|
5
|
+
export declare function findTool(name: string, env: Env): Promise<string | undefined>;
|
|
3
6
|
/** Fails with `TOOL_MISSING`, naming every missing tool at once, unless all are on `PATH`. */
|
|
4
7
|
export declare function checkTools(tools: readonly Tool[], env: Env): Promise<void>;
|
|
5
|
-
/** One `doctor` row per distinct tool the Commands declare, with its install command as the fix. */
|
|
6
|
-
export declare function toolRows(commands: Commands): DoctorCheck[];
|
|
8
|
+
/** One `doctor` row per distinct tool the CLI and its Commands declare, with its install command as the fix. */
|
|
9
|
+
export declare function toolRows(tools: readonly Tool[], commands: Commands): DoctorCheck[];
|