@kisev/agentomatic 11.0.0-dev.70.g8d00098df14b → 11.0.0-dev.71.gee4e37a5bb61
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/cli.js +128 -113
- package/dist/generated/cli.d.ts +28 -0
- package/dist/generated/cli.js +181 -0
- package/package.json +4 -3
package/dist/cli.js
CHANGED
|
@@ -9,123 +9,114 @@ import { LifecycleError } from "./lifecycle.js";
|
|
|
9
9
|
import { skillsInstallerSpec } from "./package-metadata.js";
|
|
10
10
|
import { applyReconcile, previewReconcile } from "./reconcile.js";
|
|
11
11
|
import { confirmQuestion, promptText, selectOption, selectOptions } from "./terminal-wizard.js";
|
|
12
|
+
import { Command, Option, common, applyConfig, configFileSync, reporter } from "./generated/cli.js";
|
|
13
|
+
let diagnostics;
|
|
14
|
+
let machineOutput = false;
|
|
15
|
+
let diagnosticJSON = false;
|
|
12
16
|
function parseOptions(values) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
throw new
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
else if (value === "--targets" || value === "--fragments") {
|
|
104
|
-
const raw = values[++index];
|
|
105
|
-
if (!raw)
|
|
106
|
-
throw new InstallerError("invalid_input", `${value} requires a comma-separated value or none`);
|
|
107
|
-
const names = raw === "none"
|
|
108
|
-
? []
|
|
109
|
-
: raw
|
|
110
|
-
.split(",")
|
|
111
|
-
.map((item) => item.trim())
|
|
112
|
-
.filter(Boolean);
|
|
113
|
-
options.selectionFlag = true;
|
|
114
|
-
if (value === "--targets")
|
|
115
|
-
options.configTargets = names;
|
|
116
|
-
else
|
|
117
|
-
options.configFragments = names;
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
throw new InstallerError("invalid_input", `Unknown argument: ${value}`);
|
|
121
|
-
}
|
|
17
|
+
const parser = common(new Command()
|
|
18
|
+
.exitOverride()
|
|
19
|
+
.helpOption(false)
|
|
20
|
+
.configureOutput({ writeErr: () => { } }), "AGENTOMATIC").argument("[name]");
|
|
21
|
+
for (const [flags, description] of [
|
|
22
|
+
["--global", "global user scope"],
|
|
23
|
+
["--dry-run", "preview changes"],
|
|
24
|
+
["--yes", "explicitly confirm the displayed operation"],
|
|
25
|
+
["--core", "activate core integration"],
|
|
26
|
+
["--no-core", "disable core integration"],
|
|
27
|
+
["--provider <value>", "provider"],
|
|
28
|
+
["--model <value>", "model"],
|
|
29
|
+
["--variant <value>", "reasoning variant"],
|
|
30
|
+
["--clear-variant", "clear the variant"],
|
|
31
|
+
["--no-dependency", "do not provision dependencies"],
|
|
32
|
+
["--commands <value>", "command selection"],
|
|
33
|
+
["--skill-commands <value>", "command selection alias"],
|
|
34
|
+
["--agents <value>", "agent selection"],
|
|
35
|
+
["--plugins <value>", "plugin selection"],
|
|
36
|
+
["--targets <value>", "config targets"],
|
|
37
|
+
["--fragments <value>", "config fragments"],
|
|
38
|
+
]) {
|
|
39
|
+
const option = new Option(flags, description);
|
|
40
|
+
if (!["--yes", "--core", "--no-core", "--clear-variant", "--no-dependency"].includes(flags))
|
|
41
|
+
option.env(`AGENTOMATIC_${option
|
|
42
|
+
.attributeName()
|
|
43
|
+
.replace(/[A-Z]/g, (char) => `_${char}`)
|
|
44
|
+
.toUpperCase()}`);
|
|
45
|
+
parser.addOption(option);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
for (const flag of ["--global", "--dry-run", "--yes", "--json", "--no-dependency"])
|
|
49
|
+
if (values.filter((value) => value === flag).length > 1)
|
|
50
|
+
throw new Error(`${flag} may be supplied once`);
|
|
51
|
+
if (values.includes("--core") && values.includes("--no-core"))
|
|
52
|
+
throw new Error("Use only one core integration option");
|
|
53
|
+
if (values.includes("--variant") && values.includes("--clear-variant"))
|
|
54
|
+
throw new Error("Use only one variant option");
|
|
55
|
+
parser.parse(values, { from: "user" });
|
|
56
|
+
applyConfig(parser, configFileSync(parser.opts().config));
|
|
57
|
+
const parsed = parser.opts();
|
|
58
|
+
machineOutput = parsed.json === true;
|
|
59
|
+
diagnosticJSON = parsed.logFormat === "json";
|
|
60
|
+
diagnostics ??= reporter({ ...parsed, progress: parsed.progress ?? "never" });
|
|
61
|
+
diagnostics.emit({
|
|
62
|
+
phase: "agentomatic",
|
|
63
|
+
message: "Validated command options",
|
|
64
|
+
level: "debug",
|
|
65
|
+
});
|
|
66
|
+
const list = (value) => value === undefined
|
|
67
|
+
? undefined
|
|
68
|
+
: Array.isArray(value)
|
|
69
|
+
? value.map(String)
|
|
70
|
+
: String(value) === "none"
|
|
71
|
+
? []
|
|
72
|
+
: String(value)
|
|
73
|
+
.split(",")
|
|
74
|
+
.map((item) => item.trim())
|
|
75
|
+
.filter(Boolean);
|
|
76
|
+
return {
|
|
77
|
+
scope: parsed.global ? "global" : "project",
|
|
78
|
+
global: parsed.global === true,
|
|
79
|
+
dryRun: parsed.dryRun === true,
|
|
80
|
+
json: parsed.json === true,
|
|
81
|
+
yes: parsed.yes === true,
|
|
82
|
+
name: parser.args[0],
|
|
83
|
+
core: ["cli", "env", "config"].includes(parser.getOptionValueSource("core") ?? "")
|
|
84
|
+
? parsed.core
|
|
85
|
+
: undefined,
|
|
86
|
+
provider: parsed.provider,
|
|
87
|
+
model: parsed.model,
|
|
88
|
+
variant: parsed.clearVariant ? null : parsed.variant,
|
|
89
|
+
noDependency: parsed.dependency === false,
|
|
90
|
+
commands: list(parsed.commands ?? parsed.skillCommands),
|
|
91
|
+
agents: list(parsed.agents),
|
|
92
|
+
plugins: list(parsed.plugins),
|
|
93
|
+
configTargets: list(parsed.targets),
|
|
94
|
+
configFragments: list(parsed.fragments),
|
|
95
|
+
selectionFlag: [
|
|
96
|
+
"commands",
|
|
97
|
+
"skillCommands",
|
|
98
|
+
"agents",
|
|
99
|
+
"plugins",
|
|
100
|
+
"targets",
|
|
101
|
+
"fragments",
|
|
102
|
+
].some((key) => parsed[key] !== undefined),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
throw new InstallerError("invalid_input", error instanceof Error ? error.message : String(error));
|
|
122
107
|
}
|
|
123
|
-
return options;
|
|
124
108
|
}
|
|
125
109
|
function helpRows(rows) {
|
|
126
110
|
const width = Math.max(...rows.map(([label]) => label.length));
|
|
127
111
|
return rows.map(([label, description]) => ` ${label.padEnd(width)} ${description}`);
|
|
128
112
|
}
|
|
113
|
+
function commonRows() {
|
|
114
|
+
const parser = common(new Command("agentomatic"), "AGENTOMATIC");
|
|
115
|
+
const help = parser.createHelp();
|
|
116
|
+
return parser.options
|
|
117
|
+
.filter((option) => option.attributeName() !== "json")
|
|
118
|
+
.map((option) => [help.optionTerm(option), help.optionDescription(option)]);
|
|
119
|
+
}
|
|
129
120
|
function rootHelp() {
|
|
130
121
|
return [
|
|
131
122
|
`agentomatic ${CATALOG.version}`,
|
|
@@ -164,6 +155,7 @@ function rootHelp() {
|
|
|
164
155
|
["--json", "Emit stable machine-readable output when supported."],
|
|
165
156
|
["--help", "Show this help and exit."],
|
|
166
157
|
["--version", "Show the package version and exit."],
|
|
158
|
+
...commonRows(),
|
|
167
159
|
]),
|
|
168
160
|
"",
|
|
169
161
|
"Install selection:",
|
|
@@ -234,7 +226,19 @@ function commandHelp(topic, summary, usage, options, behavior, examples) {
|
|
|
234
226
|
...usage.map((line) => ` ${line}`),
|
|
235
227
|
"",
|
|
236
228
|
"Options:",
|
|
237
|
-
...helpRows(options)
|
|
229
|
+
...helpRows(options.map(([flag, description]) => {
|
|
230
|
+
const match = /^--([a-z][a-z-]*)/.exec(flag);
|
|
231
|
+
const environment = match &&
|
|
232
|
+
!["yes", "core", "no-core", "no-dependency", "clear-variant", "help"].includes(match[1]);
|
|
233
|
+
return [
|
|
234
|
+
flag,
|
|
235
|
+
environment
|
|
236
|
+
? `${description} (env: AGENTOMATIC_${match[1].replaceAll("-", "_").toUpperCase()})`
|
|
237
|
+
: description,
|
|
238
|
+
];
|
|
239
|
+
})),
|
|
240
|
+
"",
|
|
241
|
+
...helpRows(commonRows()),
|
|
238
242
|
"",
|
|
239
243
|
"Behavior:",
|
|
240
244
|
...behavior.map((line) => ` ${line}`),
|
|
@@ -1227,17 +1231,28 @@ async function run(arguments_) {
|
|
|
1227
1231
|
}
|
|
1228
1232
|
async function main() {
|
|
1229
1233
|
try {
|
|
1230
|
-
|
|
1234
|
+
let args = process.argv
|
|
1235
|
+
.slice(2)
|
|
1236
|
+
.map((value) => (value === "-h" ? "--help" : value === "-V" ? "--version" : value));
|
|
1237
|
+
if (args[0] === "help")
|
|
1238
|
+
args = [...args.slice(1), "--help"];
|
|
1239
|
+
await run(args);
|
|
1231
1240
|
}
|
|
1232
1241
|
catch (error) {
|
|
1233
1242
|
const known = error instanceof LifecycleError
|
|
1234
1243
|
? error
|
|
1235
1244
|
: new InstallerError("internal_error", error instanceof Error ? error.message : String(error));
|
|
1236
|
-
if (process.argv.includes("--json"))
|
|
1245
|
+
if (process.argv.includes("--json") || machineOutput)
|
|
1237
1246
|
process.stdout.write(`${JSON.stringify({ status: "error", error: { code: known.code, message: known.message } })}\n`);
|
|
1247
|
+
else if (diagnosticJSON)
|
|
1248
|
+
process.stderr.write(`${JSON.stringify({ level: "error", phase: "agentomatic.error", code: known.code, message: known.message })}\n`);
|
|
1238
1249
|
else
|
|
1239
1250
|
process.stderr.write(`Error [${known.code}]: ${terminalSafe(known.message)}\n`);
|
|
1240
1251
|
process.exitCode = 2;
|
|
1241
1252
|
}
|
|
1253
|
+
finally {
|
|
1254
|
+
diagnostics?.emit({ phase: "agentomatic.done", message: "Command finished", level: "debug" });
|
|
1255
|
+
diagnostics?.close();
|
|
1256
|
+
}
|
|
1242
1257
|
}
|
|
1243
1258
|
void main();
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command, Option, CommanderError, InvalidArgumentError } from "commander";
|
|
2
|
+
export { Command, Option, CommanderError, InvalidArgumentError };
|
|
3
|
+
export declare function integer(value: string): number;
|
|
4
|
+
export declare function duration(value: string): number;
|
|
5
|
+
export declare function program(name: string, description: string, version: string): Command;
|
|
6
|
+
export declare function common(command: Command, prefix: string): Command;
|
|
7
|
+
export declare function configFile(path: string | undefined): Promise<Record<string, unknown>>;
|
|
8
|
+
export declare function configFileSync(path: string | undefined): Record<string, unknown>;
|
|
9
|
+
export declare function applyConfig(command: Command, config: Record<string, unknown>): void;
|
|
10
|
+
export type Event = {
|
|
11
|
+
phase: string;
|
|
12
|
+
message: string;
|
|
13
|
+
level?: "debug" | "info" | "warn" | "error";
|
|
14
|
+
completed?: number;
|
|
15
|
+
total?: number;
|
|
16
|
+
elapsedMs?: number;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
};
|
|
19
|
+
export type Observe = (event: Event) => void;
|
|
20
|
+
export declare function reporter(options?: Record<string, unknown>): {
|
|
21
|
+
emit: Observe;
|
|
22
|
+
close: () => void;
|
|
23
|
+
};
|
|
24
|
+
export declare function cancellation(): {
|
|
25
|
+
signal: AbortSignal;
|
|
26
|
+
dispose: () => void;
|
|
27
|
+
};
|
|
28
|
+
export declare function fail(name: string, error: unknown, json?: boolean): void;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { Command, Option, CommanderError, InvalidArgumentError } from "commander";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
export { Command, Option, CommanderError, InvalidArgumentError };
|
|
5
|
+
export function integer(value) {
|
|
6
|
+
if (!/^\d+$/.test(value) || !Number.isSafeInteger(Number(value)))
|
|
7
|
+
throw new InvalidArgumentError("expected a non-negative integer");
|
|
8
|
+
return Number(value);
|
|
9
|
+
}
|
|
10
|
+
export function duration(value) {
|
|
11
|
+
const match = /^(\d+)(ms|s|m|h)?$/.exec(value);
|
|
12
|
+
if (!match)
|
|
13
|
+
throw new InvalidArgumentError("expected a duration such as 500ms, 30s or 5m");
|
|
14
|
+
const result = Number(match[1]) * ({ ms: 1, s: 1000, m: 60000, h: 3600000 }[match[2] ?? "ms"] ?? 1);
|
|
15
|
+
if (!Number.isSafeInteger(result) || result < 0)
|
|
16
|
+
throw new InvalidArgumentError("duration is out of range");
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
export function program(name, description, version) {
|
|
20
|
+
return new Command(name)
|
|
21
|
+
.description(description)
|
|
22
|
+
.version(version)
|
|
23
|
+
.exitOverride()
|
|
24
|
+
.configureHelp({ showGlobalOptions: true })
|
|
25
|
+
.showHelpAfterError()
|
|
26
|
+
.configureOutput({ outputError: () => { } });
|
|
27
|
+
}
|
|
28
|
+
export function common(command, prefix) {
|
|
29
|
+
return command
|
|
30
|
+
.addOption(new Option("--config <file>", "JSON configuration file (CLI > env > file > defaults)").env(`${prefix}_CONFIG`))
|
|
31
|
+
.addOption(new Option("--json", "machine-readable result on stdout").env(`${prefix}_JSON`))
|
|
32
|
+
.addOption(new Option("--log-level <level>", "diagnostic verbosity on stderr")
|
|
33
|
+
.choices(["debug", "info", "warn", "error", "silent"])
|
|
34
|
+
.env(`${prefix}_LOG_LEVEL`))
|
|
35
|
+
.addOption(new Option("--log-format <format>", "diagnostic format on stderr")
|
|
36
|
+
.choices(["text", "json"])
|
|
37
|
+
.env(`${prefix}_LOG_FORMAT`))
|
|
38
|
+
.addOption(new Option("--progress <mode>", "terminal progress; never written to stdout")
|
|
39
|
+
.choices(["auto", "always", "never"])
|
|
40
|
+
.env(`${prefix}_PROGRESS`))
|
|
41
|
+
.addOption(new Option("--color <mode>", "color policy (NO_COLOR disables color)")
|
|
42
|
+
.choices(["auto", "always", "never"])
|
|
43
|
+
.env(`${prefix}_COLOR`));
|
|
44
|
+
}
|
|
45
|
+
export async function configFile(path) {
|
|
46
|
+
if (!path)
|
|
47
|
+
return {};
|
|
48
|
+
const value = JSON.parse(await readFile(path, "utf8"));
|
|
49
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
50
|
+
throw new InvalidArgumentError("configuration must be a JSON object");
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
export function configFileSync(path) {
|
|
54
|
+
if (!path)
|
|
55
|
+
return {};
|
|
56
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
57
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
58
|
+
throw new InvalidArgumentError("configuration must be a JSON object");
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
export function applyConfig(command, config) {
|
|
62
|
+
for (const option of command.options) {
|
|
63
|
+
const key = option.attributeName();
|
|
64
|
+
if (!(key in config) || ["cli", "env"].includes(command.getOptionValueSource(key) ?? ""))
|
|
65
|
+
continue;
|
|
66
|
+
if (["yes", "config"].includes(key))
|
|
67
|
+
continue;
|
|
68
|
+
const value = config[key];
|
|
69
|
+
if (option.required || option.optional) {
|
|
70
|
+
const raw = String(value);
|
|
71
|
+
if (option.argChoices && !option.argChoices.includes(raw))
|
|
72
|
+
throw new InvalidArgumentError(`invalid configuration value for ${key}`);
|
|
73
|
+
command.setOptionValueWithSource(key, option.parseArg ? option.parseArg(raw, undefined) : raw, "config");
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
if (typeof value !== "boolean")
|
|
77
|
+
throw new InvalidArgumentError(`${key} must be boolean`);
|
|
78
|
+
command.setOptionValueWithSource(key, value, "config");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export function reporter(options = {}) {
|
|
83
|
+
const started = Date.now();
|
|
84
|
+
const level = String(options.logLevel ?? "info");
|
|
85
|
+
const levels = ["debug", "info", "warn", "error", "silent"];
|
|
86
|
+
const json = options.logFormat === "json";
|
|
87
|
+
const interactive = !json &&
|
|
88
|
+
options.progress !== "never" &&
|
|
89
|
+
(options.progress === "always" || process.stderr.isTTY);
|
|
90
|
+
let current;
|
|
91
|
+
let painted = false;
|
|
92
|
+
let frame = 0;
|
|
93
|
+
let meter;
|
|
94
|
+
const bar = () => {
|
|
95
|
+
if (!meter || meter.total <= 0)
|
|
96
|
+
return "";
|
|
97
|
+
const ratio = Math.min(1, Math.max(0, meter.completed / meter.total));
|
|
98
|
+
const filled = Math.floor(ratio * 16);
|
|
99
|
+
return ` | ${meter.phase} [${"█".repeat(filled)}${"░".repeat(16 - filled)}] ${Math.floor(ratio * 100)}%`;
|
|
100
|
+
};
|
|
101
|
+
const clean = (text) => Array.from(text, (char) => {
|
|
102
|
+
const code = char.codePointAt(0);
|
|
103
|
+
return code < 32 || (code >= 127 && code <= 159) ? " " : char;
|
|
104
|
+
}).join("");
|
|
105
|
+
const line = (event) => `${event.phase}: ${event.message}${event.total !== undefined ? ` [${event.completed ?? 0}/${event.total}]` : ""} (${Math.floor((Date.now() - started) / 1000)}s)`;
|
|
106
|
+
const clear = () => {
|
|
107
|
+
if (painted) {
|
|
108
|
+
process.stderr.write("\r\x1b[2K");
|
|
109
|
+
painted = false;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const timer = interactive && level !== "silent"
|
|
113
|
+
? setInterval(() => {
|
|
114
|
+
if (current) {
|
|
115
|
+
const color = process.env.NO_COLOR === undefined &&
|
|
116
|
+
(options.color === "always" || (options.color !== "never" && process.stderr.isTTY));
|
|
117
|
+
process.stderr.write(`\r\x1b[2K${color ? "\x1b[36m" : ""}${["⠋", "⠙", "⠹", "⠸"][frame++ % 4]} ${clean(line(current))}${bar()}${color ? "\x1b[0m" : ""}`);
|
|
118
|
+
painted = true;
|
|
119
|
+
}
|
|
120
|
+
}, 120)
|
|
121
|
+
: undefined;
|
|
122
|
+
timer?.unref();
|
|
123
|
+
const emit = (event) => {
|
|
124
|
+
const severity = event.level ?? "info";
|
|
125
|
+
if (levels.indexOf(severity) < levels.indexOf(level))
|
|
126
|
+
return;
|
|
127
|
+
current = event;
|
|
128
|
+
if (event.total !== undefined)
|
|
129
|
+
meter =
|
|
130
|
+
event.total > 0
|
|
131
|
+
? {
|
|
132
|
+
phase: event.phase.split(".")[0],
|
|
133
|
+
completed: event.completed ?? 0,
|
|
134
|
+
total: event.total,
|
|
135
|
+
}
|
|
136
|
+
: undefined;
|
|
137
|
+
else if (meter && meter.completed >= meter.total)
|
|
138
|
+
meter = undefined;
|
|
139
|
+
clear();
|
|
140
|
+
process.stderr.write(json
|
|
141
|
+
? `${JSON.stringify({ at: new Date().toISOString(), elapsedMs: Date.now() - started, ...event })}\n`
|
|
142
|
+
: `${clean(line(event))}\n`);
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
emit,
|
|
146
|
+
close: () => {
|
|
147
|
+
if (timer)
|
|
148
|
+
clearInterval(timer);
|
|
149
|
+
clear();
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export function cancellation() {
|
|
154
|
+
const controller = new AbortController();
|
|
155
|
+
const interrupt = () => controller.abort(new Error("interrupted"));
|
|
156
|
+
process.on("SIGINT", interrupt);
|
|
157
|
+
process.on("SIGTERM", interrupt);
|
|
158
|
+
process.on("SIGHUP", interrupt);
|
|
159
|
+
return {
|
|
160
|
+
signal: controller.signal,
|
|
161
|
+
dispose: () => {
|
|
162
|
+
process.off("SIGINT", interrupt);
|
|
163
|
+
process.off("SIGTERM", interrupt);
|
|
164
|
+
process.off("SIGHUP", interrupt);
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export function fail(name, error, json = false) {
|
|
169
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
170
|
+
return;
|
|
171
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
172
|
+
const interrupted = /interrupted|aborted/i.test(message);
|
|
173
|
+
process.stderr.write(json ? `${JSON.stringify({ status: "error", message })}\n` : `${name}: ${message}\n`);
|
|
174
|
+
process.exitCode = /timeout|timed out|deadline/i.test(message)
|
|
175
|
+
? 124
|
|
176
|
+
: interrupted
|
|
177
|
+
? 130
|
|
178
|
+
: error instanceof CommanderError
|
|
179
|
+
? 2
|
|
180
|
+
: 1;
|
|
181
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kisev/agentomatic",
|
|
3
|
-
"version": "11.0.0-dev.
|
|
3
|
+
"version": "11.0.0-dev.71.gee4e37a5bb61",
|
|
4
4
|
"description": "OpenCode integration and opt-in installer for portable Agent Skills.",
|
|
5
5
|
"homepage": "https://github.com/kisev/skills#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@clack/prompts": "^1.8.1",
|
|
49
|
-
"@kisev/safe-fs": "1.0.0-dev.
|
|
49
|
+
"@kisev/safe-fs": "1.0.0-dev.71.gee4e37a5bb61",
|
|
50
|
+
"commander": "15.0.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@opencode-ai/plugin": "1.18.29",
|
|
@@ -62,7 +63,7 @@
|
|
|
62
63
|
}
|
|
63
64
|
},
|
|
64
65
|
"engines": {
|
|
65
|
-
"node": ">=22"
|
|
66
|
+
"node": ">=22.13"
|
|
66
67
|
},
|
|
67
68
|
"skillsInstallerVersion": "1.7.0"
|
|
68
69
|
}
|