padrone 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/README.md +105 -284
- package/dist/{args-CVDbyyzG.mjs → args-D5PNDyNu.mjs} +41 -18
- package/dist/args-D5PNDyNu.mjs.map +1 -0
- package/dist/chunk-CjcI7cDX.mjs +15 -0
- package/dist/codegen/index.d.mts +28 -3
- package/dist/codegen/index.d.mts.map +1 -1
- package/dist/codegen/index.mjs +169 -19
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/command-utils-B1D-HqCd.mjs +1117 -0
- package/dist/command-utils-B1D-HqCd.mjs.map +1 -0
- package/dist/completion.d.mts +1 -1
- package/dist/completion.d.mts.map +1 -1
- package/dist/completion.mjs +77 -29
- package/dist/completion.mjs.map +1 -1
- package/dist/docs/index.d.mts +22 -2
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +94 -7
- package/dist/docs/index.mjs.map +1 -1
- package/dist/errors-BiVrBgi6.mjs +114 -0
- package/dist/errors-BiVrBgi6.mjs.map +1 -0
- package/dist/{formatter-ClUK5hcQ.d.mts → formatter-DtHzbP22.d.mts} +34 -5
- package/dist/formatter-DtHzbP22.d.mts.map +1 -0
- package/dist/help-bbmu9-qd.mjs +735 -0
- package/dist/help-bbmu9-qd.mjs.map +1 -0
- package/dist/index.d.mts +32 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +493 -265
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-mLWIdUIu.mjs +379 -0
- package/dist/mcp-mLWIdUIu.mjs.map +1 -0
- package/dist/serve-B0u43DK7.mjs +404 -0
- package/dist/serve-B0u43DK7.mjs.map +1 -0
- package/dist/stream-BcC146Ud.mjs +56 -0
- package/dist/stream-BcC146Ud.mjs.map +1 -0
- package/dist/test.d.mts +1 -1
- package/dist/test.mjs +4 -15
- package/dist/test.mjs.map +1 -1
- package/dist/{types-DjIdJN5G.d.mts → types-Ch8Mk6Qb.d.mts} +310 -62
- package/dist/types-Ch8Mk6Qb.d.mts.map +1 -0
- package/dist/{update-check-EbNDkzyV.mjs → update-check-CFX1FV3v.mjs} +2 -2
- package/dist/{update-check-EbNDkzyV.mjs.map → update-check-CFX1FV3v.mjs.map} +1 -1
- package/dist/zod.d.mts +32 -0
- package/dist/zod.d.mts.map +1 -0
- package/dist/zod.mjs +50 -0
- package/dist/zod.mjs.map +1 -0
- package/package.json +10 -2
- package/src/args.ts +68 -40
- package/src/cli/docs.ts +1 -7
- package/src/cli/doctor.ts +195 -10
- package/src/cli/index.ts +1 -1
- package/src/cli/init.ts +2 -3
- package/src/cli/link.ts +2 -2
- package/src/codegen/discovery.ts +80 -28
- package/src/codegen/index.ts +2 -1
- package/src/codegen/parsers/bash.ts +179 -0
- package/src/codegen/schema-to-code.ts +2 -1
- package/src/colorizer.ts +126 -13
- package/src/command-utils.ts +380 -30
- package/src/completion.ts +120 -47
- package/src/create.ts +480 -128
- package/src/docs/index.ts +122 -8
- package/src/formatter.ts +171 -125
- package/src/help.ts +45 -12
- package/src/index.ts +29 -1
- package/src/interactive.ts +45 -4
- package/src/mcp.ts +390 -0
- package/src/repl-loop.ts +16 -3
- package/src/runtime.ts +195 -2
- package/src/serve.ts +442 -0
- package/src/stream.ts +75 -0
- package/src/test.ts +7 -16
- package/src/type-utils.ts +28 -4
- package/src/types.ts +212 -30
- package/src/wrap.ts +23 -25
- package/src/zod.ts +50 -0
- package/dist/args-CVDbyyzG.mjs.map +0 -1
- package/dist/chunk-y_GBKt04.mjs +0 -5
- package/dist/formatter-ClUK5hcQ.d.mts.map +0 -1
- package/dist/help-CcBe91bV.mjs +0 -1254
- package/dist/help-CcBe91bV.mjs.map +0 -1
- package/dist/types-DjIdJN5G.d.mts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,116 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Carries structured metadata for user-friendly formatting and programmatic handling.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* throw new PadroneError('Something went wrong', {
|
|
11
|
-
* exitCode: 1,
|
|
12
|
-
* suggestions: ['Try --help for usage information'],
|
|
13
|
-
* });
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
var PadroneError = class extends Error {
|
|
17
|
-
exitCode;
|
|
18
|
-
suggestions;
|
|
19
|
-
command;
|
|
20
|
-
phase;
|
|
21
|
-
constructor(message, options) {
|
|
22
|
-
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
23
|
-
this.name = "PadroneError";
|
|
24
|
-
this.exitCode = options?.exitCode ?? 1;
|
|
25
|
-
this.suggestions = options?.suggestions ?? [];
|
|
26
|
-
this.command = options?.command;
|
|
27
|
-
this.phase = options?.phase;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Returns a serializable representation of the error,
|
|
31
|
-
* suitable for non-terminal runtimes (web UIs, APIs, etc.).
|
|
32
|
-
*/
|
|
33
|
-
toJSON() {
|
|
34
|
-
return {
|
|
35
|
-
name: this.name,
|
|
36
|
-
message: this.message,
|
|
37
|
-
exitCode: this.exitCode,
|
|
38
|
-
suggestions: this.suggestions,
|
|
39
|
-
command: this.command,
|
|
40
|
-
phase: this.phase
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Thrown when command routing fails — unknown command, unexpected arguments, etc.
|
|
46
|
-
*/
|
|
47
|
-
var RoutingError = class extends PadroneError {
|
|
48
|
-
constructor(message, options) {
|
|
49
|
-
super(message, {
|
|
50
|
-
phase: "parse",
|
|
51
|
-
...options
|
|
52
|
-
});
|
|
53
|
-
this.name = "RoutingError";
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Thrown when argument or schema validation fails.
|
|
58
|
-
* Carries the structured issues from the schema validator.
|
|
59
|
-
*/
|
|
60
|
-
var ValidationError = class extends PadroneError {
|
|
61
|
-
issues;
|
|
62
|
-
constructor(message, issues, options) {
|
|
63
|
-
super(message, {
|
|
64
|
-
phase: "validate",
|
|
65
|
-
...options
|
|
66
|
-
});
|
|
67
|
-
this.name = "ValidationError";
|
|
68
|
-
this.issues = issues;
|
|
69
|
-
}
|
|
70
|
-
toJSON() {
|
|
71
|
-
return {
|
|
72
|
-
...super.toJSON(),
|
|
73
|
-
issues: this.issues.map((i) => ({
|
|
74
|
-
path: i.path?.map(String),
|
|
75
|
-
message: i.message
|
|
76
|
-
}))
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
/**
|
|
81
|
-
* Thrown when config file loading or validation fails.
|
|
82
|
-
*/
|
|
83
|
-
var ConfigError = class extends PadroneError {
|
|
84
|
-
constructor(message, options) {
|
|
85
|
-
super(message, {
|
|
86
|
-
phase: "config",
|
|
87
|
-
...options
|
|
88
|
-
});
|
|
89
|
-
this.name = "ConfigError";
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Thrown from user action handlers to surface structured errors with exit codes and suggestions.
|
|
94
|
-
* This is the primary error class users should throw from their command actions.
|
|
95
|
-
*
|
|
96
|
-
* @example
|
|
97
|
-
* ```ts
|
|
98
|
-
* throw new ActionError('Missing environment', {
|
|
99
|
-
* exitCode: 1,
|
|
100
|
-
* suggestions: ['Use --env production or --env staging'],
|
|
101
|
-
* });
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
var ActionError = class extends PadroneError {
|
|
105
|
-
constructor(message, options) {
|
|
106
|
-
super(message, {
|
|
107
|
-
phase: "execute",
|
|
108
|
-
...options
|
|
109
|
-
});
|
|
110
|
-
this.name = "ActionError";
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
//#endregion
|
|
1
|
+
import { r as colorThemes, t as generateHelp } from "./help-bbmu9-qd.mjs";
|
|
2
|
+
import { r as createStdinStream, t as asyncStream } from "./stream-BcC146Ud.mjs";
|
|
3
|
+
import { a as extractSchemaMetadata, c as parsePositionalConfig, i as detectUnknownArgs, l as parseStdinConfig, o as isArrayField, r as coerceArgs, s as isAsyncStreamField, t as JSON_SCHEMA_OPTS, u as preprocessArgs } from "./args-D5PNDyNu.mjs";
|
|
4
|
+
import { A as withDrain, C as resolveCommand, D as suggestSimilar, F as resolveStdin, I as resolveStdinAlways, M as wrapWithLifecycle, N as REPL_SIGINT, O as thenMaybe, P as createTerminalReplSession, R as getVersion, S as resolveAllCommands, T as runPluginChain, _ as mergeCommands, a as commandSymbol, b as outputValue, c as createProgress, f as getCommandRuntime, g as makeThenable, h as lazyResolver, j as withPromiseDrain, k as warnIfUnexpectedAsync, l as errorResult, m as isAsyncBranded, p as hasInteractiveConfig, r as buildReplCompleter, s as createLazyIndicator, t as asyncSchema, u as findCommandByName, v as noop, w as resolveProgressMessage, x as repathCommandTree, y as noopIndicator } from "./command-utils-B1D-HqCd.mjs";
|
|
5
|
+
import { a as ValidationError, i as RoutingError, n as ConfigError, r as PadroneError, t as ActionError } from "./errors-BiVrBgi6.mjs";
|
|
114
6
|
//#region src/interactive.ts
|
|
115
7
|
/**
|
|
116
8
|
* Auto-detect the prompt type for a field based on its JSON schema property definition.
|
|
@@ -162,6 +54,34 @@ function detectPromptConfig(name, propSchema, description) {
|
|
|
162
54
|
};
|
|
163
55
|
}
|
|
164
56
|
/**
|
|
57
|
+
* Prompt a single field and validate it against the command's schema.
|
|
58
|
+
* Re-prompts with a warning until the user provides a valid value.
|
|
59
|
+
*/
|
|
60
|
+
async function promptWithValidation(field, config, currentData, command, runtime) {
|
|
61
|
+
let promptConfig = config;
|
|
62
|
+
while (true) {
|
|
63
|
+
const value = await runtime.prompt(promptConfig);
|
|
64
|
+
if (!command.argsSchema) return value;
|
|
65
|
+
const testData = {
|
|
66
|
+
...currentData,
|
|
67
|
+
[field]: value
|
|
68
|
+
};
|
|
69
|
+
const validated = await command.argsSchema["~standard"].validate(testData);
|
|
70
|
+
if (!validated.issues) return value;
|
|
71
|
+
const fieldIssues = validated.issues.filter((issue) => {
|
|
72
|
+
const rootKey = issue.path?.[0];
|
|
73
|
+
return rootKey !== void 0 && String(rootKey) === field;
|
|
74
|
+
});
|
|
75
|
+
if (fieldIssues.length === 0) return value;
|
|
76
|
+
const messages = fieldIssues.map((i) => i.message).join("; ");
|
|
77
|
+
runtime.error(`Invalid value for "${field}": ${messages}`);
|
|
78
|
+
promptConfig = {
|
|
79
|
+
...config,
|
|
80
|
+
default: value
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
165
85
|
* Prompt for missing interactive fields.
|
|
166
86
|
* Runs after env/config preprocessing and before schema validation.
|
|
167
87
|
*
|
|
@@ -177,7 +97,7 @@ async function promptInteractiveFields(data, command, runtime, force) {
|
|
|
177
97
|
let jsonProperties = {};
|
|
178
98
|
let requiredFields = /* @__PURE__ */ new Set();
|
|
179
99
|
if (command.argsSchema) try {
|
|
180
|
-
const jsonSchema = command.argsSchema["~standard"].jsonSchema.input(
|
|
100
|
+
const jsonSchema = command.argsSchema["~standard"].jsonSchema.input(JSON_SCHEMA_OPTS);
|
|
181
101
|
if (jsonSchema.type === "object" && jsonSchema.properties) jsonProperties = jsonSchema.properties;
|
|
182
102
|
if (Array.isArray(jsonSchema.required)) requiredFields = new Set(jsonSchema.required);
|
|
183
103
|
} catch {}
|
|
@@ -194,7 +114,7 @@ async function promptInteractiveFields(data, command, runtime, force) {
|
|
|
194
114
|
for (const field of fieldsToPrompt) {
|
|
195
115
|
const config = detectPromptConfig(field, jsonProperties[field], fieldDescriptions[field]);
|
|
196
116
|
if (force && result[field] !== void 0) config.default = result[field];
|
|
197
|
-
result[field] = await
|
|
117
|
+
result[field] = await promptWithValidation(field, config, result, command, runtime);
|
|
198
118
|
}
|
|
199
119
|
let optionalFields = [];
|
|
200
120
|
if (optionalInteractiveConfig === true) if (force) optionalFields = Object.keys(jsonProperties).filter((name) => !requiredFields.has(name));
|
|
@@ -218,7 +138,7 @@ async function promptInteractiveFields(data, command, runtime, force) {
|
|
|
218
138
|
if (Array.isArray(selected)) for (const field of selected) {
|
|
219
139
|
const config = detectPromptConfig(field, jsonProperties[field], fieldDescriptions[field]);
|
|
220
140
|
if (force && result[field] !== void 0) config.default = result[field];
|
|
221
|
-
result[field] = await
|
|
141
|
+
result[field] = await promptWithValidation(field, config, result, command, runtime);
|
|
222
142
|
}
|
|
223
143
|
}
|
|
224
144
|
return result;
|
|
@@ -607,7 +527,10 @@ function createReplIterator(deps, options) {
|
|
|
607
527
|
const scopedInput = scopePath ? evalInput ? `${scopePath} ${evalInput}` : scopePath : evalInput;
|
|
608
528
|
try {
|
|
609
529
|
const result = await evalCommand(scopedInput, options?.autoOutput === false ? { autoOutput: false } : void 0);
|
|
610
|
-
if (result.
|
|
530
|
+
if (result.error) {
|
|
531
|
+
const msg = result.error instanceof Error ? result.error.message : String(result.error);
|
|
532
|
+
runtime.error(prefixLines ? prefixLines(msg) : msg);
|
|
533
|
+
} else if (result.argsResult?.issues) {
|
|
611
534
|
const msg = `Validation error:\n${result.argsResult.issues.map((i) => ` - ${i.path?.join(".") || "root"}: ${i.message}`).join("\n")}`;
|
|
612
535
|
runtime.error(prefixLines ? prefixLines(msg) : msg);
|
|
613
536
|
}
|
|
@@ -625,7 +548,17 @@ function createReplIterator(deps, options) {
|
|
|
625
548
|
session?.close();
|
|
626
549
|
}
|
|
627
550
|
}
|
|
628
|
-
|
|
551
|
+
const iterable = replIterator();
|
|
552
|
+
iterable.drain = async () => {
|
|
553
|
+
try {
|
|
554
|
+
const results = [];
|
|
555
|
+
for await (const result of iterable) results.push(result);
|
|
556
|
+
return { value: results };
|
|
557
|
+
} catch (err) {
|
|
558
|
+
return { error: err };
|
|
559
|
+
}
|
|
560
|
+
};
|
|
561
|
+
return iterable;
|
|
629
562
|
}
|
|
630
563
|
//#endregion
|
|
631
564
|
//#region src/wrap.ts
|
|
@@ -672,30 +605,30 @@ function createWrapHandler(config, commandArguments, commandPositional) {
|
|
|
672
605
|
};
|
|
673
606
|
const regularArgs = argsToCliArgs(validationResult instanceof Promise ? await validationResult.then(processResult) : processResult(validationResult), positional);
|
|
674
607
|
const allArgs = [...fixedArgs, ...regularArgs];
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
if (
|
|
685
|
-
|
|
686
|
-
|
|
608
|
+
const { spawn } = await import("node:child_process");
|
|
609
|
+
return new Promise((resolve, reject) => {
|
|
610
|
+
const proc = spawn(command, allArgs, { stdio: inheritStdio ? "inherit" : [
|
|
611
|
+
"ignore",
|
|
612
|
+
"pipe",
|
|
613
|
+
"pipe"
|
|
614
|
+
] });
|
|
615
|
+
const stdoutChunks = [];
|
|
616
|
+
const stderrChunks = [];
|
|
617
|
+
if (!inheritStdio) {
|
|
618
|
+
proc.stdout.on("data", (chunk) => stdoutChunks.push(chunk));
|
|
619
|
+
proc.stderr.on("data", (chunk) => stderrChunks.push(chunk));
|
|
687
620
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
};
|
|
621
|
+
proc.on("error", reject);
|
|
622
|
+
proc.on("close", (code) => {
|
|
623
|
+
const exitCode = code ?? 1;
|
|
624
|
+
resolve({
|
|
625
|
+
exitCode,
|
|
626
|
+
stdout: inheritStdio ? void 0 : Buffer.concat(stdoutChunks).toString(),
|
|
627
|
+
stderr: inheritStdio ? void 0 : Buffer.concat(stderrChunks).toString(),
|
|
628
|
+
success: exitCode === 0
|
|
629
|
+
});
|
|
630
|
+
});
|
|
631
|
+
});
|
|
699
632
|
};
|
|
700
633
|
}
|
|
701
634
|
//#endregion
|
|
@@ -716,11 +649,14 @@ function createPadroneBuilder(inputCommand) {
|
|
|
716
649
|
} : c)
|
|
717
650
|
} : inputCommand;
|
|
718
651
|
/** Creates the action context passed to command handlers. References `builder` which is defined later but only called at runtime. */
|
|
719
|
-
const createActionContext = (cmd) =>
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
652
|
+
const createActionContext = (cmd) => {
|
|
653
|
+
return {
|
|
654
|
+
runtime: getCommandRuntime(cmd),
|
|
655
|
+
command: cmd,
|
|
656
|
+
program: builder,
|
|
657
|
+
progress: noopIndicator
|
|
658
|
+
};
|
|
659
|
+
};
|
|
724
660
|
const find = (command) => {
|
|
725
661
|
if (typeof command !== "string") return findCommandByName(command.path, existingCommand.commands);
|
|
726
662
|
return findCommandByName(command, existingCommand.commands);
|
|
@@ -777,7 +713,7 @@ function createPadroneBuilder(inputCommand) {
|
|
|
777
713
|
};
|
|
778
714
|
const arrayArguments = /* @__PURE__ */ new Set();
|
|
779
715
|
if (curCommand.argsSchema) try {
|
|
780
|
-
const jsonSchema = curCommand.argsSchema["~standard"].jsonSchema.input(
|
|
716
|
+
const jsonSchema = curCommand.argsSchema["~standard"].jsonSchema.input(JSON_SCHEMA_OPTS);
|
|
781
717
|
if (jsonSchema.type === "object" && jsonSchema.properties) {
|
|
782
718
|
for (const [key, prop] of Object.entries(jsonSchema.properties)) if (prop?.type === "array") arrayArguments.add(key);
|
|
783
719
|
}
|
|
@@ -919,11 +855,17 @@ function createPadroneBuilder(inputCommand) {
|
|
|
919
855
|
const readStdinForParse = () => {
|
|
920
856
|
const stdinConfig = command.meta?.stdin;
|
|
921
857
|
if (!stdinConfig) return {};
|
|
922
|
-
const
|
|
858
|
+
const field = parseStdinConfig(stdinConfig);
|
|
923
859
|
if (field in validateCtx.rawArgs && validateCtx.rawArgs[field] !== void 0) return {};
|
|
924
|
-
const
|
|
860
|
+
const runtime = getCommandRuntime(existingCommand);
|
|
861
|
+
const streamInfo = isAsyncStreamField(command.argsSchema, field);
|
|
862
|
+
if (streamInfo) {
|
|
863
|
+
const stdinForStream = resolveStdinAlways(runtime);
|
|
864
|
+
return { [field]: createStdinStream(stdinForStream, streamInfo.itemSchema) };
|
|
865
|
+
}
|
|
866
|
+
const stdin = resolveStdin(runtime);
|
|
925
867
|
if (!stdin) return {};
|
|
926
|
-
if (
|
|
868
|
+
if (isArrayField(command.argsSchema, field)) return (async () => {
|
|
927
869
|
const lines = [];
|
|
928
870
|
for await (const line of stdin.lines()) lines.push(line);
|
|
929
871
|
return { [field]: lines };
|
|
@@ -1015,11 +957,13 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1015
957
|
const hasHelpFlag = args.some((p) => p.type === "named" && keyIs(p.key, "help") || p.type === "alias" && keyIs(p.key, "h"));
|
|
1016
958
|
const getDetailLevel = () => {
|
|
1017
959
|
for (const arg of args) {
|
|
1018
|
-
if (arg.type === "named" && keyIs(arg.key, "detail")
|
|
1019
|
-
if (arg.value === "minimal" || arg.value === "standard" || arg.value === "full") return arg.value;
|
|
960
|
+
if (arg.type === "named" && keyIs(arg.key, "detail")) {
|
|
961
|
+
if (typeof arg.value === "string" && (arg.value === "minimal" || arg.value === "standard" || arg.value === "full")) return arg.value;
|
|
962
|
+
return "full";
|
|
1020
963
|
}
|
|
1021
|
-
if (arg.type === "alias" && keyIs(arg.key, "d")
|
|
1022
|
-
if (arg.value === "minimal" || arg.value === "standard" || arg.value === "full") return arg.value;
|
|
964
|
+
if (arg.type === "alias" && keyIs(arg.key, "d")) {
|
|
965
|
+
if (typeof arg.value === "string" && (arg.value === "minimal" || arg.value === "standard" || arg.value === "full")) return arg.value;
|
|
966
|
+
return "full";
|
|
1023
967
|
}
|
|
1024
968
|
}
|
|
1025
969
|
};
|
|
@@ -1044,6 +988,7 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1044
988
|
}
|
|
1045
989
|
};
|
|
1046
990
|
const format = getFormat();
|
|
991
|
+
const hasAllFlag = args.some((p) => p.type === "named" && keyIs(p.key, "all"));
|
|
1047
992
|
const hasVersionFlag = args.some((p) => p.type === "named" && keyIs(p.key, "version") || p.type === "alias" && (keyIs(p.key, "v") || keyIs(p.key, "V")));
|
|
1048
993
|
const normalizedTerms = [...terms];
|
|
1049
994
|
if (normalizedTerms[0] === existingCommand.name) normalizedTerms.shift();
|
|
@@ -1056,7 +1001,8 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1056
1001
|
type: "help",
|
|
1057
1002
|
command: commandName ? findCommandByName(commandName, existingCommand.commands) : void 0,
|
|
1058
1003
|
detail,
|
|
1059
|
-
format
|
|
1004
|
+
format,
|
|
1005
|
+
all: hasAllFlag || void 0
|
|
1060
1006
|
};
|
|
1061
1007
|
}
|
|
1062
1008
|
if (!userHelpCommand && normalizedTerms.length > 0 && normalizedTerms[normalizedTerms.length - 1] === "help") {
|
|
@@ -1074,7 +1020,8 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1074
1020
|
type: "help",
|
|
1075
1021
|
command: targetCommand,
|
|
1076
1022
|
detail,
|
|
1077
|
-
format
|
|
1023
|
+
format,
|
|
1024
|
+
all: hasAllFlag || void 0
|
|
1078
1025
|
};
|
|
1079
1026
|
}
|
|
1080
1027
|
if (!userVersionCommand && normalizedTerms[0] === "version") return { type: "version" };
|
|
@@ -1091,16 +1038,53 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1091
1038
|
setup: args.some((p) => p.type === "named" && keyIs(p.key, "setup"))
|
|
1092
1039
|
};
|
|
1093
1040
|
}
|
|
1041
|
+
if (!findCommandByName("man", existingCommand.commands) && normalizedTerms[0] === "man") return {
|
|
1042
|
+
type: "man",
|
|
1043
|
+
setup: args.some((p) => p.type === "named" && keyIs(p.key, "setup")),
|
|
1044
|
+
remove: args.some((p) => p.type === "named" && keyIs(p.key, "remove"))
|
|
1045
|
+
};
|
|
1094
1046
|
if (hasHelpFlag) {
|
|
1095
1047
|
const commandName = normalizedTerms.filter((t) => t !== "help").join(" ");
|
|
1096
1048
|
return {
|
|
1097
1049
|
type: "help",
|
|
1098
1050
|
command: commandName ? findCommandByName(commandName, existingCommand.commands) : void 0,
|
|
1099
1051
|
detail,
|
|
1100
|
-
format
|
|
1052
|
+
format,
|
|
1053
|
+
all: hasAllFlag || void 0
|
|
1101
1054
|
};
|
|
1102
1055
|
}
|
|
1103
1056
|
if (hasVersionFlag && normalizedTerms.length === 0) return { type: "version" };
|
|
1057
|
+
if (!findCommandByName("mcp", existingCommand.commands) && normalizedTerms[0] === "mcp") {
|
|
1058
|
+
const transportArg = normalizedTerms[1];
|
|
1059
|
+
const transport = transportArg === "stdio" || transportArg === "http" ? transportArg : void 0;
|
|
1060
|
+
const portArg = args.find((p) => p.type === "named" && keyIs(p.key, "port"));
|
|
1061
|
+
const port = typeof portArg?.value === "string" ? parseInt(portArg.value, 10) : void 0;
|
|
1062
|
+
const hostArg = args.find((p) => p.type === "named" && keyIs(p.key, "host"));
|
|
1063
|
+
const host = typeof hostArg?.value === "string" ? hostArg.value : void 0;
|
|
1064
|
+
const basePathArg = args.find((p) => p.type === "named" && keyIs(p.key, "base-path"));
|
|
1065
|
+
const mcpBasePath = typeof basePathArg?.value === "string" ? basePathArg.value : void 0;
|
|
1066
|
+
return {
|
|
1067
|
+
type: "mcp",
|
|
1068
|
+
transport,
|
|
1069
|
+
port: port && !Number.isNaN(port) ? port : void 0,
|
|
1070
|
+
host,
|
|
1071
|
+
basePath: mcpBasePath
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
if (!findCommandByName("serve", existingCommand.commands) && normalizedTerms[0] === "serve") {
|
|
1075
|
+
const portArg = args.find((p) => p.type === "named" && keyIs(p.key, "port"));
|
|
1076
|
+
const port = typeof portArg?.value === "string" ? parseInt(portArg.value, 10) : void 0;
|
|
1077
|
+
const hostArg = args.find((p) => p.type === "named" && keyIs(p.key, "host"));
|
|
1078
|
+
const host = typeof hostArg?.value === "string" ? hostArg.value : void 0;
|
|
1079
|
+
const basePathArg = args.find((p) => p.type === "named" && keyIs(p.key, "base-path"));
|
|
1080
|
+
const basePath = typeof basePathArg?.value === "string" ? basePathArg.value : void 0;
|
|
1081
|
+
return {
|
|
1082
|
+
type: "serve",
|
|
1083
|
+
port: port && !Number.isNaN(port) ? port : void 0,
|
|
1084
|
+
host,
|
|
1085
|
+
basePath
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1104
1088
|
if (args.some((p) => p.type === "named" && keyIs(p.key, "repl"))) return {
|
|
1105
1089
|
type: "repl",
|
|
1106
1090
|
scope: normalizedTerms.length > 0 ? normalizedTerms.join(" ") : void 0
|
|
@@ -1119,6 +1103,28 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1119
1103
|
}
|
|
1120
1104
|
};
|
|
1121
1105
|
/**
|
|
1106
|
+
* Extract --color flag from input.
|
|
1107
|
+
* - `--color` or `--color=true` → use default theme
|
|
1108
|
+
* - `--color=false` or `--no-color` → disable colors (text format)
|
|
1109
|
+
* - `--color=<theme>` → use the named theme
|
|
1110
|
+
* Returns `undefined` if no --color flag is present.
|
|
1111
|
+
*/
|
|
1112
|
+
const extractColorFlag = (input) => {
|
|
1113
|
+
if (!input) return void 0;
|
|
1114
|
+
const args = parseCliInputToParts(input).filter((p) => p.type === "named");
|
|
1115
|
+
const keyIs = (key, name) => key.length === 1 && key[0] === name;
|
|
1116
|
+
for (const arg of args) {
|
|
1117
|
+
if (arg.type === "named" && keyIs(arg.key, "no-color")) return { disableColor: true };
|
|
1118
|
+
if (arg.type === "named" && keyIs(arg.key, "color")) {
|
|
1119
|
+
if (arg.negated) return { disableColor: true };
|
|
1120
|
+
if (arg.value === void 0 || arg.value === "true") return { theme: "default" };
|
|
1121
|
+
if (arg.value === "false") return { disableColor: true };
|
|
1122
|
+
if (typeof arg.value === "string" && arg.value in colorThemes) return { theme: arg.value };
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
};
|
|
1127
|
+
/**
|
|
1122
1128
|
* Core execution logic shared by eval() and cli().
|
|
1123
1129
|
* errorMode controls validation error behavior:
|
|
1124
1130
|
* - 'soft': return result with issues (eval behavior)
|
|
@@ -1126,51 +1132,97 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1126
1132
|
*/
|
|
1127
1133
|
const execCommand = (resolvedInput, evalOptions, errorMode = "soft") => {
|
|
1128
1134
|
const baseRuntime = getCommandRuntime(existingCommand);
|
|
1129
|
-
|
|
1135
|
+
let runtime = evalOptions?.runtime ? Object.assign({}, baseRuntime, Object.fromEntries(Object.entries(evalOptions.runtime).filter(([, v]) => v !== void 0))) : baseRuntime;
|
|
1136
|
+
const colorFlag = extractColorFlag(resolvedInput);
|
|
1137
|
+
if (colorFlag) runtime = {
|
|
1138
|
+
...runtime,
|
|
1139
|
+
...colorFlag.disableColor ? {
|
|
1140
|
+
format: "text",
|
|
1141
|
+
theme: void 0
|
|
1142
|
+
} : { theme: colorFlag.theme }
|
|
1143
|
+
};
|
|
1130
1144
|
const builtin = checkBuiltinCommands(resolvedInput);
|
|
1131
1145
|
if (builtin) {
|
|
1132
1146
|
if (builtin.type === "help") {
|
|
1147
|
+
resolveAllCommands(existingCommand);
|
|
1133
1148
|
const helpText = generateHelp(existingCommand, builtin.command ?? existingCommand, {
|
|
1134
1149
|
detail: builtin.detail,
|
|
1135
|
-
format: builtin.format ?? runtime.format
|
|
1150
|
+
format: builtin.format ?? runtime.format,
|
|
1151
|
+
theme: runtime.theme,
|
|
1152
|
+
all: builtin.all
|
|
1136
1153
|
});
|
|
1137
1154
|
runtime.output(helpText);
|
|
1138
|
-
return {
|
|
1155
|
+
return withDrain({
|
|
1139
1156
|
command: existingCommand,
|
|
1140
1157
|
args: void 0,
|
|
1141
1158
|
result: helpText
|
|
1142
|
-
};
|
|
1159
|
+
});
|
|
1143
1160
|
}
|
|
1144
1161
|
if (builtin.type === "version") {
|
|
1145
1162
|
const version = getVersion(existingCommand.version);
|
|
1146
1163
|
runtime.output(version);
|
|
1147
|
-
return {
|
|
1164
|
+
return withDrain({
|
|
1148
1165
|
command: existingCommand,
|
|
1149
1166
|
args: void 0,
|
|
1150
1167
|
result: version
|
|
1151
|
-
};
|
|
1168
|
+
});
|
|
1152
1169
|
}
|
|
1153
|
-
if (builtin.type === "completion")
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
if (
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1170
|
+
if (builtin.type === "completion") {
|
|
1171
|
+
resolveAllCommands(existingCommand);
|
|
1172
|
+
return import("./completion.mjs").then(({ detectShell, generateCompletionOutput, setupCompletions }) => {
|
|
1173
|
+
if (builtin.setup) {
|
|
1174
|
+
const shell = builtin.shell ?? detectShell();
|
|
1175
|
+
if (!shell) throw new Error("Could not detect shell. Specify one: completion bash --setup");
|
|
1176
|
+
const result = setupCompletions(existingCommand.name, shell);
|
|
1177
|
+
const message = `${result.updated ? "Updated" : "Added"} ${existingCommand.name} completions in ${result.file}`;
|
|
1178
|
+
runtime.output(message);
|
|
1179
|
+
return withDrain({
|
|
1180
|
+
command: existingCommand,
|
|
1181
|
+
args: void 0,
|
|
1182
|
+
result: message
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
const completionScript = generateCompletionOutput(existingCommand, builtin.shell);
|
|
1186
|
+
runtime.output(completionScript);
|
|
1187
|
+
return withDrain({
|
|
1161
1188
|
command: existingCommand,
|
|
1162
1189
|
args: void 0,
|
|
1163
|
-
result:
|
|
1164
|
-
};
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1190
|
+
result: completionScript
|
|
1191
|
+
});
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
if (builtin.type === "man") {
|
|
1195
|
+
resolveAllCommands(existingCommand);
|
|
1196
|
+
return import("./docs/index.mjs").then(({ setupManPages, removeManPages, generateDocs }) => {
|
|
1197
|
+
if (builtin.setup) {
|
|
1198
|
+
const result = setupManPages(existingCommand);
|
|
1199
|
+
const message = `${result.updated ? "Updated" : "Installed"} ${result.written.length} man page(s) in ${result.dir}`;
|
|
1200
|
+
runtime.output(message);
|
|
1201
|
+
return withDrain({
|
|
1202
|
+
command: existingCommand,
|
|
1203
|
+
args: void 0,
|
|
1204
|
+
result: message
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
if (builtin.remove) {
|
|
1208
|
+
const result = removeManPages(existingCommand);
|
|
1209
|
+
const message = result.removed.length > 0 ? `Removed ${result.removed.length} man page(s) from ${result.dir}` : "No man pages found to remove.";
|
|
1210
|
+
runtime.output(message);
|
|
1211
|
+
return withDrain({
|
|
1212
|
+
command: existingCommand,
|
|
1213
|
+
args: void 0,
|
|
1214
|
+
result: message
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
const manPage = generateDocs(existingCommand, { format: "man" }).pages[0]?.content ?? "";
|
|
1218
|
+
runtime.output(manPage);
|
|
1219
|
+
return withDrain({
|
|
1220
|
+
command: existingCommand,
|
|
1221
|
+
args: void 0,
|
|
1222
|
+
result: manPage
|
|
1223
|
+
});
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1174
1226
|
}
|
|
1175
1227
|
const state = {};
|
|
1176
1228
|
const rootPlugins = existingCommand.plugins ?? [];
|
|
@@ -1185,7 +1237,11 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1185
1237
|
const hasSubcommands = command.commands && command.commands.length > 0;
|
|
1186
1238
|
const hasSchema = command.argsSchema != null;
|
|
1187
1239
|
if (!command.action && (hasSubcommands || !hasSchema) && unmatchedTerms.length === 0) {
|
|
1188
|
-
|
|
1240
|
+
resolveAllCommands(existingCommand);
|
|
1241
|
+
const helpText = generateHelp(existingCommand, command, {
|
|
1242
|
+
format: runtime.format,
|
|
1243
|
+
theme: runtime.theme
|
|
1244
|
+
});
|
|
1189
1245
|
runtime.output(helpText);
|
|
1190
1246
|
return {
|
|
1191
1247
|
command,
|
|
@@ -1222,7 +1278,11 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1222
1278
|
runtime.output(`\nAvailable commands: ${cmdList}`);
|
|
1223
1279
|
}
|
|
1224
1280
|
} else {
|
|
1225
|
-
|
|
1281
|
+
resolveAllCommands(existingCommand);
|
|
1282
|
+
const helpText = generateHelp(existingCommand, isRootCommand ? existingCommand : command, {
|
|
1283
|
+
format: runtime.format,
|
|
1284
|
+
theme: runtime.theme
|
|
1285
|
+
});
|
|
1226
1286
|
runtime.error(helpText);
|
|
1227
1287
|
}
|
|
1228
1288
|
throw new RoutingError(errorMsg, {
|
|
@@ -1251,6 +1311,36 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1251
1311
|
args: void 0,
|
|
1252
1312
|
result: parsed.rawArgs["~help"]
|
|
1253
1313
|
};
|
|
1314
|
+
const progressConfig = command.progress;
|
|
1315
|
+
if (progressConfig && runtime.progress) {
|
|
1316
|
+
const isObj = typeof progressConfig === "object";
|
|
1317
|
+
const defaultMsg = typeof progressConfig === "string" ? progressConfig : `Running ${command.name}...`;
|
|
1318
|
+
const progressMsg = isObj ? progressConfig.progress ?? defaultMsg : defaultMsg;
|
|
1319
|
+
const validationMsg = isObj ? progressConfig.validation ?? "" : "";
|
|
1320
|
+
state._progressSuccess = isObj ? progressConfig.success : void 0;
|
|
1321
|
+
state._progressError = isObj ? progressConfig.error : void 0;
|
|
1322
|
+
state._progressMsg = progressMsg;
|
|
1323
|
+
state._progressValidationMsg = validationMsg || void 0;
|
|
1324
|
+
const spinnerConfig = isObj ? progressConfig.spinner : void 0;
|
|
1325
|
+
const indicator = createProgress(runtime, validationMsg || progressMsg, spinnerConfig !== void 0 ? { spinner: spinnerConfig } : void 0);
|
|
1326
|
+
state._progress = indicator;
|
|
1327
|
+
const originalOutput = runtime.output;
|
|
1328
|
+
const originalError = runtime.error;
|
|
1329
|
+
runtime.output = (...args) => {
|
|
1330
|
+
indicator.pause();
|
|
1331
|
+
originalOutput(...args);
|
|
1332
|
+
indicator.resume();
|
|
1333
|
+
};
|
|
1334
|
+
runtime.error = (text) => {
|
|
1335
|
+
indicator.pause();
|
|
1336
|
+
originalError(text);
|
|
1337
|
+
indicator.resume();
|
|
1338
|
+
};
|
|
1339
|
+
state._restoreOutput = () => {
|
|
1340
|
+
runtime.output = originalOutput;
|
|
1341
|
+
runtime.error = originalError;
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1254
1344
|
const validateCtx = {
|
|
1255
1345
|
command,
|
|
1256
1346
|
rawArgs: parsed.rawArgs,
|
|
@@ -1269,6 +1359,8 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1269
1359
|
delete validateCtx.rawArgs.i;
|
|
1270
1360
|
}
|
|
1271
1361
|
}
|
|
1362
|
+
delete validateCtx.rawArgs.color;
|
|
1363
|
+
delete validateCtx.rawArgs["no-color"];
|
|
1272
1364
|
const runtimeDefault = runtime.interactive === "forced" ? true : runtime.interactive === "disabled" ? false : void 0;
|
|
1273
1365
|
const effectiveInteractive = flagInteractive ?? evalOptions?.interactive ?? runtimeDefault;
|
|
1274
1366
|
const stdinIsPiped = !!command.meta?.stdin && (runtime.stdin ? !runtime.stdin.isTTY : typeof process !== "undefined" && process.stdin?.isTTY !== true);
|
|
@@ -1317,11 +1409,16 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1317
1409
|
const readStdin = () => {
|
|
1318
1410
|
const stdinConfig = command.meta?.stdin;
|
|
1319
1411
|
if (!stdinConfig) return {};
|
|
1320
|
-
const
|
|
1412
|
+
const field = parseStdinConfig(stdinConfig);
|
|
1321
1413
|
if (field in validateCtx.rawArgs && validateCtx.rawArgs[field] !== void 0) return {};
|
|
1414
|
+
const streamInfo = isAsyncStreamField(command.argsSchema, field);
|
|
1415
|
+
if (streamInfo) {
|
|
1416
|
+
const stdinForStream = resolveStdinAlways(runtime);
|
|
1417
|
+
return { [field]: createStdinStream(stdinForStream, streamInfo.itemSchema) };
|
|
1418
|
+
}
|
|
1322
1419
|
const stdin = resolveStdin(runtime);
|
|
1323
1420
|
if (!stdin) return {};
|
|
1324
|
-
if (
|
|
1421
|
+
if (isArrayField(command.argsSchema, field)) return (async () => {
|
|
1325
1422
|
const lines = [];
|
|
1326
1423
|
for await (const line of stdin.lines()) lines.push(line);
|
|
1327
1424
|
return { [field]: lines };
|
|
@@ -1394,7 +1491,7 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1394
1491
|
if (knownOptions) return knownOptions;
|
|
1395
1492
|
knownOptions = [];
|
|
1396
1493
|
if (command.argsSchema) try {
|
|
1397
|
-
const js = command.argsSchema["~standard"].jsonSchema.input(
|
|
1494
|
+
const js = command.argsSchema["~standard"].jsonSchema.input(JSON_SCHEMA_OPTS);
|
|
1398
1495
|
if (js.type === "object" && js.properties) knownOptions = Object.keys(js.properties);
|
|
1399
1496
|
} catch {}
|
|
1400
1497
|
return knownOptions;
|
|
@@ -1409,7 +1506,11 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1409
1506
|
return base;
|
|
1410
1507
|
}).join("\n");
|
|
1411
1508
|
if (errorMode === "hard") {
|
|
1412
|
-
|
|
1509
|
+
resolveAllCommands(existingCommand);
|
|
1510
|
+
const helpText = generateHelp(existingCommand, command, {
|
|
1511
|
+
format: runtime.format,
|
|
1512
|
+
theme: runtime.theme
|
|
1513
|
+
});
|
|
1413
1514
|
runtime.error(`Validation error:\n${issueMessages}`);
|
|
1414
1515
|
runtime.error(helpText);
|
|
1415
1516
|
throw new ValidationError(`Validation error:\n${issueMessages}`, v.argsResult.issues, {
|
|
@@ -1421,13 +1522,15 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1421
1522
|
command: command.path || command.name
|
|
1422
1523
|
});
|
|
1423
1524
|
}
|
|
1424
|
-
return {
|
|
1525
|
+
return withDrain({
|
|
1425
1526
|
command,
|
|
1426
1527
|
args: void 0,
|
|
1427
1528
|
argsResult: v.argsResult,
|
|
1428
1529
|
result: void 0
|
|
1429
|
-
};
|
|
1530
|
+
});
|
|
1430
1531
|
}
|
|
1532
|
+
const activeIndicator = state._progress;
|
|
1533
|
+
if (activeIndicator && state._progressMsg && state._progressValidationMsg) activeIndicator.update(state._progressMsg);
|
|
1431
1534
|
const executeCtx = {
|
|
1432
1535
|
command,
|
|
1433
1536
|
args: v.args,
|
|
@@ -1435,31 +1538,61 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1435
1538
|
};
|
|
1436
1539
|
const coreExecute = () => {
|
|
1437
1540
|
const handler = command.action ?? noop;
|
|
1438
|
-
const ctx =
|
|
1541
|
+
const ctx = {
|
|
1439
1542
|
...createActionContext(command),
|
|
1440
|
-
runtime
|
|
1441
|
-
|
|
1543
|
+
runtime,
|
|
1544
|
+
progress: state._progress ?? createLazyIndicator(runtime, state)
|
|
1545
|
+
};
|
|
1442
1546
|
return { result: handler(executeCtx.args, ctx) };
|
|
1443
1547
|
};
|
|
1444
1548
|
return thenMaybe(runPluginChain("execute", commandPlugins, executeCtx, coreExecute), (e) => {
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1549
|
+
const finalize = (result) => {
|
|
1550
|
+
const indicator = state._progress;
|
|
1551
|
+
if (indicator) {
|
|
1552
|
+
if (!("_progressMsg" in state)) indicator.stop();
|
|
1553
|
+
else {
|
|
1554
|
+
const { message: successMsg, indicator: successIcon } = resolveProgressMessage(state._progressSuccess, result);
|
|
1555
|
+
indicator.succeed(successMsg, successIcon !== void 0 ? { indicator: successIcon } : void 0);
|
|
1556
|
+
}
|
|
1557
|
+
state._restoreOutput?.();
|
|
1558
|
+
state._progress = void 0;
|
|
1559
|
+
state._restoreOutput = void 0;
|
|
1560
|
+
}
|
|
1561
|
+
const commandResult = withDrain({
|
|
1562
|
+
command,
|
|
1563
|
+
args: v.args,
|
|
1564
|
+
argsResult: v.argsResult,
|
|
1565
|
+
result
|
|
1566
|
+
});
|
|
1567
|
+
if (command.autoOutput ?? evalOptions?.autoOutput ?? true) {
|
|
1568
|
+
const outputOrPromise = outputValue(result, runtime.output);
|
|
1569
|
+
if (outputOrPromise instanceof Promise) return outputOrPromise.then(() => commandResult);
|
|
1570
|
+
}
|
|
1571
|
+
return commandResult;
|
|
1450
1572
|
};
|
|
1451
|
-
if (
|
|
1452
|
-
const
|
|
1453
|
-
if (
|
|
1454
|
-
|
|
1455
|
-
|
|
1573
|
+
if (e.result instanceof Promise) return e.result.then(finalize, (err) => {
|
|
1574
|
+
const indicator = state._progress;
|
|
1575
|
+
if (indicator) {
|
|
1576
|
+
if (!("_progressMsg" in state)) indicator.stop();
|
|
1577
|
+
else {
|
|
1578
|
+
const fallback = err instanceof Error ? err.message : String(err);
|
|
1579
|
+
const { message: errorMsg, indicator: errorIcon } = resolveProgressMessage(state._progressError, err, fallback);
|
|
1580
|
+
indicator.fail(errorMsg, errorIcon !== void 0 ? { indicator: errorIcon } : void 0);
|
|
1581
|
+
}
|
|
1582
|
+
state._restoreOutput?.();
|
|
1583
|
+
state._progress = void 0;
|
|
1584
|
+
state._restoreOutput = void 0;
|
|
1585
|
+
}
|
|
1586
|
+
throw err;
|
|
1587
|
+
});
|
|
1588
|
+
return finalize(e.result);
|
|
1456
1589
|
});
|
|
1457
1590
|
};
|
|
1458
1591
|
return thenMaybe(warnIfUnexpectedAsync(validatedOrPromise, command), continueAfterValidate);
|
|
1459
1592
|
};
|
|
1460
1593
|
return thenMaybe(parsedOrPromise, continueAfterParse);
|
|
1461
1594
|
};
|
|
1462
|
-
return wrapWithLifecycle(rootPlugins, existingCommand, state, resolvedInput, runPipeline, (result) => ({
|
|
1595
|
+
return wrapWithLifecycle(rootPlugins, existingCommand, state, resolvedInput, runPipeline, (result) => withDrain({
|
|
1463
1596
|
command: existingCommand,
|
|
1464
1597
|
args: void 0,
|
|
1465
1598
|
argsResult: void 0,
|
|
@@ -1467,7 +1600,13 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1467
1600
|
}));
|
|
1468
1601
|
};
|
|
1469
1602
|
const evalCommand = (input, evalOptions) => {
|
|
1470
|
-
|
|
1603
|
+
try {
|
|
1604
|
+
const result = execCommand(input, evalOptions, "soft");
|
|
1605
|
+
if (result instanceof Promise) return withPromiseDrain(result.catch((err) => errorResult(err)));
|
|
1606
|
+
return makeThenable(result);
|
|
1607
|
+
} catch (err) {
|
|
1608
|
+
return makeThenable(errorResult(err));
|
|
1609
|
+
}
|
|
1471
1610
|
};
|
|
1472
1611
|
/**
|
|
1473
1612
|
* Collects plugins from the command's parent chain (root → ... → target).
|
|
@@ -1490,69 +1629,125 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1490
1629
|
}
|
|
1491
1630
|
return chain.flat();
|
|
1492
1631
|
};
|
|
1493
|
-
|
|
1632
|
+
const replFn = (options) => {
|
|
1633
|
+
return createReplIterator({
|
|
1634
|
+
existingCommand,
|
|
1635
|
+
evalCommand,
|
|
1636
|
+
replActiveRef
|
|
1637
|
+
}, options);
|
|
1638
|
+
};
|
|
1494
1639
|
const replActiveRef = { value: false };
|
|
1495
1640
|
const cli = (cliOptions) => {
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1641
|
+
try {
|
|
1642
|
+
const runtime = getCommandRuntime(existingCommand);
|
|
1643
|
+
const resolvedInput = runtime.argv().join(" ") || void 0;
|
|
1499
1644
|
const builtin = checkBuiltinCommands(resolvedInput);
|
|
1500
|
-
if (builtin?.type === "repl") {
|
|
1501
|
-
const
|
|
1645
|
+
if (cliOptions?.repl !== false && builtin?.type === "repl") {
|
|
1646
|
+
const repl = replFn({
|
|
1502
1647
|
...typeof cliOptions?.repl === "object" ? cliOptions.repl : {},
|
|
1503
1648
|
scope: builtin.scope,
|
|
1504
1649
|
autoOutput: (typeof cliOptions?.repl === "object" ? cliOptions.repl.autoOutput : void 0) ?? cliOptions?.autoOutput
|
|
1505
|
-
};
|
|
1650
|
+
});
|
|
1506
1651
|
const drainRepl = async () => {
|
|
1507
|
-
|
|
1508
|
-
return {
|
|
1652
|
+
const { value } = await repl.drain();
|
|
1653
|
+
return withDrain({
|
|
1654
|
+
command: existingCommand,
|
|
1655
|
+
args: void 0,
|
|
1656
|
+
result: value
|
|
1657
|
+
});
|
|
1658
|
+
};
|
|
1659
|
+
return withPromiseDrain(drainRepl());
|
|
1660
|
+
}
|
|
1661
|
+
if (cliOptions?.mcp !== false && builtin?.type === "mcp") {
|
|
1662
|
+
const basePrefs = typeof cliOptions?.mcp === "object" ? cliOptions.mcp : {};
|
|
1663
|
+
const mcpPrefs = {
|
|
1664
|
+
...basePrefs,
|
|
1665
|
+
transport: builtin.transport ?? basePrefs.transport,
|
|
1666
|
+
port: builtin.port ?? basePrefs.port,
|
|
1667
|
+
host: builtin.host ?? basePrefs.host,
|
|
1668
|
+
basePath: builtin.basePath ?? basePrefs.basePath
|
|
1669
|
+
};
|
|
1670
|
+
const startMcp = async () => {
|
|
1671
|
+
const { startMcpServer } = await import("./mcp-mLWIdUIu.mjs");
|
|
1672
|
+
await startMcpServer(builder, existingCommand, evalCommand, mcpPrefs);
|
|
1673
|
+
return withDrain({
|
|
1509
1674
|
command: existingCommand,
|
|
1510
1675
|
args: void 0,
|
|
1511
1676
|
result: void 0
|
|
1512
|
-
};
|
|
1677
|
+
});
|
|
1513
1678
|
};
|
|
1514
|
-
return
|
|
1679
|
+
return withPromiseDrain(startMcp());
|
|
1515
1680
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1681
|
+
if (cliOptions?.serve !== false && builtin?.type === "serve") {
|
|
1682
|
+
const basePrefs = typeof cliOptions?.serve === "object" ? cliOptions.serve : {};
|
|
1683
|
+
const servePrefs = {
|
|
1684
|
+
...basePrefs,
|
|
1685
|
+
port: builtin.port ?? basePrefs.port,
|
|
1686
|
+
host: builtin.host ?? basePrefs.host,
|
|
1687
|
+
basePath: builtin.basePath ?? basePrefs.basePath
|
|
1688
|
+
};
|
|
1689
|
+
const startServe = async () => {
|
|
1690
|
+
const { startServeServer } = await import("./serve-B0u43DK7.mjs");
|
|
1691
|
+
await startServeServer(builder, existingCommand, evalCommand, servePrefs);
|
|
1692
|
+
return withDrain({
|
|
1693
|
+
command: existingCommand,
|
|
1694
|
+
args: void 0,
|
|
1695
|
+
result: void 0
|
|
1696
|
+
});
|
|
1697
|
+
};
|
|
1698
|
+
return withPromiseDrain(startServe());
|
|
1522
1699
|
}
|
|
1700
|
+
let updateCheckPromise;
|
|
1701
|
+
if (existingCommand.updateCheck) {
|
|
1702
|
+
if (!(resolvedInput && parseCliInputToParts(resolvedInput).some((p) => p.type === "named" && p.key.length === 1 && p.key[0] === "no-update-check"))) {
|
|
1703
|
+
const currentVersion = getVersion(existingCommand.version);
|
|
1704
|
+
updateCheckPromise = import("./update-check-CFX1FV3v.mjs").then(({ createUpdateChecker }) => createUpdateChecker(existingCommand.name, currentVersion, existingCommand.updateCheck, runtime));
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
const result = execCommand(resolvedInput, cliOptions, "hard");
|
|
1708
|
+
if (updateCheckPromise) {
|
|
1709
|
+
if (result instanceof Promise) return withPromiseDrain(result.then(async (r) => {
|
|
1710
|
+
(await updateCheckPromise)?.();
|
|
1711
|
+
return r;
|
|
1712
|
+
}).catch((err) => errorResult(err)));
|
|
1713
|
+
updateCheckPromise.then((show) => show?.());
|
|
1714
|
+
}
|
|
1715
|
+
if (result instanceof Promise) return withPromiseDrain(result.catch((err) => errorResult(err)));
|
|
1716
|
+
return makeThenable(result);
|
|
1717
|
+
} catch (err) {
|
|
1718
|
+
return makeThenable(errorResult(err));
|
|
1523
1719
|
}
|
|
1524
|
-
const result = execCommand(resolvedInput, cliOptions, "hard");
|
|
1525
|
-
if (updateCheckPromise) {
|
|
1526
|
-
if (result instanceof Promise) return result.then(async (r) => {
|
|
1527
|
-
(await updateCheckPromise)?.();
|
|
1528
|
-
return r;
|
|
1529
|
-
});
|
|
1530
|
-
updateCheckPromise.then((show) => show?.());
|
|
1531
|
-
}
|
|
1532
|
-
return makeThenable(result);
|
|
1533
1720
|
};
|
|
1534
1721
|
const run = (command, args) => {
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1722
|
+
try {
|
|
1723
|
+
const commandObj = typeof command === "string" ? findCommandByName(command, existingCommand.commands) : command;
|
|
1724
|
+
if (!commandObj) throw new RoutingError(`Command "${command ?? ""}" not found`);
|
|
1725
|
+
if (!commandObj.action) throw new RoutingError(`Command "${commandObj.path}" has no action`, { command: commandObj.path });
|
|
1726
|
+
const executeCtx = {
|
|
1727
|
+
command: commandObj,
|
|
1728
|
+
args,
|
|
1729
|
+
state: {}
|
|
1730
|
+
};
|
|
1731
|
+
const coreExecute = () => {
|
|
1732
|
+
return { result: commandObj.action(executeCtx.args, createActionContext(commandObj)) };
|
|
1733
|
+
};
|
|
1734
|
+
const executedOrPromise = runPluginChain("execute", collectPlugins(commandObj), executeCtx, coreExecute);
|
|
1735
|
+
const toResult = (e) => withDrain({
|
|
1736
|
+
command: commandObj,
|
|
1737
|
+
args,
|
|
1738
|
+
result: e.result
|
|
1739
|
+
});
|
|
1740
|
+
if (executedOrPromise instanceof Promise) return executedOrPromise.then(toResult).catch((err) => errorResult(err, {
|
|
1741
|
+
command: commandObj,
|
|
1742
|
+
args
|
|
1743
|
+
}));
|
|
1744
|
+
return toResult(executedOrPromise);
|
|
1745
|
+
} catch (err) {
|
|
1746
|
+
return errorResult(err);
|
|
1747
|
+
}
|
|
1554
1748
|
};
|
|
1555
1749
|
const tool = () => {
|
|
1750
|
+
resolveAllCommands(existingCommand);
|
|
1556
1751
|
const description = `Run a command. Pass the full command string including arguments. Use "help <command>" for detailed usage.\n\n${generateHelp(existingCommand, void 0, { format: "text" })}`;
|
|
1557
1752
|
return {
|
|
1558
1753
|
type: "function",
|
|
@@ -1584,7 +1779,8 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1584
1779
|
needsApproval: async (input) => {
|
|
1585
1780
|
const parsed = await parse(input.command);
|
|
1586
1781
|
if (typeof parsed.command.needsApproval === "function") return parsed.command.needsApproval(parsed.args);
|
|
1587
|
-
return !!parsed.command.needsApproval;
|
|
1782
|
+
if (parsed.command.needsApproval != null) return !!parsed.command.needsApproval;
|
|
1783
|
+
return !!parsed.command.mutation;
|
|
1588
1784
|
},
|
|
1589
1785
|
execute: async (input) => {
|
|
1590
1786
|
const output = [];
|
|
@@ -1657,6 +1853,13 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1657
1853
|
isAsync
|
|
1658
1854
|
});
|
|
1659
1855
|
},
|
|
1856
|
+
progress(config = true) {
|
|
1857
|
+
const progress = typeof config === "boolean" || typeof config === "string" ? config : { ...config };
|
|
1858
|
+
return createPadroneBuilder({
|
|
1859
|
+
...existingCommand,
|
|
1860
|
+
progress
|
|
1861
|
+
});
|
|
1862
|
+
},
|
|
1660
1863
|
action(handler = noop) {
|
|
1661
1864
|
const baseHandler = existingCommand.action ?? noop;
|
|
1662
1865
|
return createPadroneBuilder({
|
|
@@ -1675,6 +1878,7 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1675
1878
|
const name = Array.isArray(nameOrNames) ? nameOrNames[0] : nameOrNames;
|
|
1676
1879
|
const aliases = Array.isArray(nameOrNames) && nameOrNames.length > 1 ? nameOrNames.slice(1) : void 0;
|
|
1677
1880
|
const existingSubcommand = existingCommand.commands?.find((c) => c.name === name);
|
|
1881
|
+
if (existingSubcommand) resolveCommand(existingSubcommand);
|
|
1678
1882
|
const initialCommand = existingSubcommand ? {
|
|
1679
1883
|
...existingSubcommand,
|
|
1680
1884
|
aliases: aliases ?? existingSubcommand.aliases,
|
|
@@ -1686,16 +1890,32 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1686
1890
|
parent: existingCommand,
|
|
1687
1891
|
"~types": {}
|
|
1688
1892
|
};
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1893
|
+
if (builderFn) {
|
|
1894
|
+
const lazyCmd = { ...initialCommand };
|
|
1895
|
+
lazyCmd[lazyResolver] = (target) => {
|
|
1896
|
+
const commandObj = builderFn(createPadroneBuilder(target))?.[commandSymbol] ?? target;
|
|
1897
|
+
const mergedCommandObj = existingSubcommand ? mergeCommands(existingSubcommand, commandObj) : commandObj;
|
|
1898
|
+
Object.assign(target, mergedCommandObj);
|
|
1899
|
+
};
|
|
1900
|
+
const commands = existingCommand.commands || [];
|
|
1901
|
+
const existingIndex = commands.findIndex((c) => c.name === name);
|
|
1902
|
+
const updatedCommands = existingIndex >= 0 ? [
|
|
1903
|
+
...commands.slice(0, existingIndex),
|
|
1904
|
+
lazyCmd,
|
|
1905
|
+
...commands.slice(existingIndex + 1)
|
|
1906
|
+
] : [...commands, lazyCmd];
|
|
1907
|
+
return createPadroneBuilder({
|
|
1908
|
+
...existingCommand,
|
|
1909
|
+
commands: updatedCommands
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1692
1912
|
const commands = existingCommand.commands || [];
|
|
1693
1913
|
const existingIndex = commands.findIndex((c) => c.name === name);
|
|
1694
1914
|
const updatedCommands = existingIndex >= 0 ? [
|
|
1695
1915
|
...commands.slice(0, existingIndex),
|
|
1696
|
-
|
|
1916
|
+
initialCommand,
|
|
1697
1917
|
...commands.slice(existingIndex + 1)
|
|
1698
|
-
] : [...commands,
|
|
1918
|
+
] : [...commands, initialCommand];
|
|
1699
1919
|
return createPadroneBuilder({
|
|
1700
1920
|
...existingCommand,
|
|
1701
1921
|
commands: updatedCommands
|
|
@@ -1741,14 +1961,9 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1741
1961
|
eval: evalCommand,
|
|
1742
1962
|
cli,
|
|
1743
1963
|
tool,
|
|
1744
|
-
repl: replFn
|
|
1745
|
-
return createReplIterator({
|
|
1746
|
-
existingCommand,
|
|
1747
|
-
evalCommand,
|
|
1748
|
-
replActiveRef
|
|
1749
|
-
}, options);
|
|
1750
|
-
},
|
|
1964
|
+
repl: replFn,
|
|
1751
1965
|
api() {
|
|
1966
|
+
resolveAllCommands(existingCommand);
|
|
1752
1967
|
function buildApi(command) {
|
|
1753
1968
|
const runCommand = ((args) => run(command, args).result);
|
|
1754
1969
|
if (!command.commands) return runCommand;
|
|
@@ -1758,24 +1973,37 @@ function createPadroneBuilder(inputCommand) {
|
|
|
1758
1973
|
return buildApi(existingCommand);
|
|
1759
1974
|
},
|
|
1760
1975
|
help(command, prefs) {
|
|
1976
|
+
resolveAllCommands(existingCommand);
|
|
1761
1977
|
const commandObj = !command ? existingCommand : typeof command === "string" ? findCommandByName(command, existingCommand.commands) : command;
|
|
1762
1978
|
if (!commandObj) throw new RoutingError(`Command "${command ?? ""}" not found`);
|
|
1763
1979
|
const runtime = getCommandRuntime(existingCommand);
|
|
1764
1980
|
return generateHelp(existingCommand, commandObj, {
|
|
1765
1981
|
...prefs,
|
|
1766
|
-
format: prefs?.format ?? runtime.format
|
|
1982
|
+
format: prefs?.format ?? runtime.format,
|
|
1983
|
+
theme: prefs?.theme ?? runtime.theme
|
|
1767
1984
|
});
|
|
1768
1985
|
},
|
|
1769
1986
|
async completion(shell) {
|
|
1987
|
+
resolveAllCommands(existingCommand);
|
|
1770
1988
|
const { generateCompletionOutput } = await import("./completion.mjs");
|
|
1771
1989
|
return generateCompletionOutput(existingCommand, shell);
|
|
1772
1990
|
},
|
|
1991
|
+
async mcp(prefs) {
|
|
1992
|
+
resolveAllCommands(existingCommand);
|
|
1993
|
+
const { startMcpServer } = await import("./mcp-mLWIdUIu.mjs");
|
|
1994
|
+
return startMcpServer(builder, existingCommand, evalCommand, prefs);
|
|
1995
|
+
},
|
|
1996
|
+
async serve(prefs) {
|
|
1997
|
+
resolveAllCommands(existingCommand);
|
|
1998
|
+
const { startServeServer } = await import("./serve-B0u43DK7.mjs");
|
|
1999
|
+
return startServeServer(builder, existingCommand, evalCommand, prefs);
|
|
2000
|
+
},
|
|
1773
2001
|
"~types": {},
|
|
1774
2002
|
[commandSymbol]: existingCommand
|
|
1775
2003
|
};
|
|
1776
2004
|
return builder;
|
|
1777
2005
|
}
|
|
1778
2006
|
//#endregion
|
|
1779
|
-
export { ActionError, ConfigError, PadroneError, REPL_SIGINT, RoutingError, ValidationError, asyncSchema, buildReplCompleter, createPadrone };
|
|
2007
|
+
export { ActionError, ConfigError, PadroneError, REPL_SIGINT, RoutingError, ValidationError, asyncSchema, asyncStream, buildReplCompleter, colorThemes, createPadrone };
|
|
1780
2008
|
|
|
1781
2009
|
//# sourceMappingURL=index.mjs.map
|