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.
Files changed (82) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +105 -284
  3. package/dist/{args-CVDbyyzG.mjs → args-D5PNDyNu.mjs} +41 -18
  4. package/dist/args-D5PNDyNu.mjs.map +1 -0
  5. package/dist/chunk-CjcI7cDX.mjs +15 -0
  6. package/dist/codegen/index.d.mts +28 -3
  7. package/dist/codegen/index.d.mts.map +1 -1
  8. package/dist/codegen/index.mjs +169 -19
  9. package/dist/codegen/index.mjs.map +1 -1
  10. package/dist/command-utils-B1D-HqCd.mjs +1117 -0
  11. package/dist/command-utils-B1D-HqCd.mjs.map +1 -0
  12. package/dist/completion.d.mts +1 -1
  13. package/dist/completion.d.mts.map +1 -1
  14. package/dist/completion.mjs +77 -29
  15. package/dist/completion.mjs.map +1 -1
  16. package/dist/docs/index.d.mts +22 -2
  17. package/dist/docs/index.d.mts.map +1 -1
  18. package/dist/docs/index.mjs +94 -7
  19. package/dist/docs/index.mjs.map +1 -1
  20. package/dist/errors-BiVrBgi6.mjs +114 -0
  21. package/dist/errors-BiVrBgi6.mjs.map +1 -0
  22. package/dist/{formatter-ClUK5hcQ.d.mts → formatter-DtHzbP22.d.mts} +34 -5
  23. package/dist/formatter-DtHzbP22.d.mts.map +1 -0
  24. package/dist/help-bbmu9-qd.mjs +735 -0
  25. package/dist/help-bbmu9-qd.mjs.map +1 -0
  26. package/dist/index.d.mts +32 -3
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +493 -265
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/mcp-mLWIdUIu.mjs +379 -0
  31. package/dist/mcp-mLWIdUIu.mjs.map +1 -0
  32. package/dist/serve-B0u43DK7.mjs +404 -0
  33. package/dist/serve-B0u43DK7.mjs.map +1 -0
  34. package/dist/stream-BcC146Ud.mjs +56 -0
  35. package/dist/stream-BcC146Ud.mjs.map +1 -0
  36. package/dist/test.d.mts +1 -1
  37. package/dist/test.mjs +4 -15
  38. package/dist/test.mjs.map +1 -1
  39. package/dist/{types-DjIdJN5G.d.mts → types-Ch8Mk6Qb.d.mts} +310 -62
  40. package/dist/types-Ch8Mk6Qb.d.mts.map +1 -0
  41. package/dist/{update-check-EbNDkzyV.mjs → update-check-CFX1FV3v.mjs} +2 -2
  42. package/dist/{update-check-EbNDkzyV.mjs.map → update-check-CFX1FV3v.mjs.map} +1 -1
  43. package/dist/zod.d.mts +32 -0
  44. package/dist/zod.d.mts.map +1 -0
  45. package/dist/zod.mjs +50 -0
  46. package/dist/zod.mjs.map +1 -0
  47. package/package.json +10 -2
  48. package/src/args.ts +68 -40
  49. package/src/cli/docs.ts +1 -7
  50. package/src/cli/doctor.ts +195 -10
  51. package/src/cli/index.ts +1 -1
  52. package/src/cli/init.ts +2 -3
  53. package/src/cli/link.ts +2 -2
  54. package/src/codegen/discovery.ts +80 -28
  55. package/src/codegen/index.ts +2 -1
  56. package/src/codegen/parsers/bash.ts +179 -0
  57. package/src/codegen/schema-to-code.ts +2 -1
  58. package/src/colorizer.ts +126 -13
  59. package/src/command-utils.ts +380 -30
  60. package/src/completion.ts +120 -47
  61. package/src/create.ts +480 -128
  62. package/src/docs/index.ts +122 -8
  63. package/src/formatter.ts +171 -125
  64. package/src/help.ts +45 -12
  65. package/src/index.ts +29 -1
  66. package/src/interactive.ts +45 -4
  67. package/src/mcp.ts +390 -0
  68. package/src/repl-loop.ts +16 -3
  69. package/src/runtime.ts +195 -2
  70. package/src/serve.ts +442 -0
  71. package/src/stream.ts +75 -0
  72. package/src/test.ts +7 -16
  73. package/src/type-utils.ts +28 -4
  74. package/src/types.ts +212 -30
  75. package/src/wrap.ts +23 -25
  76. package/src/zod.ts +50 -0
  77. package/dist/args-CVDbyyzG.mjs.map +0 -1
  78. package/dist/chunk-y_GBKt04.mjs +0 -5
  79. package/dist/formatter-ClUK5hcQ.d.mts.map +0 -1
  80. package/dist/help-CcBe91bV.mjs +0 -1254
  81. package/dist/help-CcBe91bV.mjs.map +0 -1
  82. package/dist/types-DjIdJN5G.d.mts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,116 +1,8 @@
1
- import { a as parsePositionalConfig, i as extractSchemaMetadata, n as coerceArgs, o as parseStdinConfig, r as detectUnknownArgs, s as preprocessArgs } from "./args-CVDbyyzG.mjs";
2
- import { C as getVersion, S as resolveStdin, _ as thenMaybe, a as commandSymbol, b as REPL_SIGINT, c as hasInteractiveConfig, d as mergeCommands, f as noop, g as suggestSimilar, h as runPluginChain, i as buildReplCompleter, l as isAsyncBranded, m as repathCommandTree, o as findCommandByName, p as outputValue, r as asyncSchema, s as getCommandRuntime, t as generateHelp, u as makeThenable, v as warnIfUnexpectedAsync, x as createTerminalReplSession, y as wrapWithLifecycle } from "./help-CcBe91bV.mjs";
3
- //#region src/errors.ts
4
- /**
5
- * Base error class for all Padrone errors.
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({ target: "draft-2020-12" });
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 runtime.prompt(config);
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 runtime.prompt(config);
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.argsResult?.issues) {
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
- return replIterator();
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 proc = Bun.spawn([command, ...allArgs], {
676
- stdout: inheritStdio ? "inherit" : "pipe",
677
- stderr: inheritStdio ? "inherit" : "pipe",
678
- stdin: inheritStdio ? "inherit" : "ignore"
679
- });
680
- const exitCode = await proc.exited;
681
- let stdout;
682
- let stderr;
683
- if (!inheritStdio) {
684
- if (proc.stdout) {
685
- const stdoutBuffer = await new Response(proc.stdout).arrayBuffer();
686
- stdout = new TextDecoder().decode(stdoutBuffer);
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
- if (proc.stderr) {
689
- const stderrBuffer = await new Response(proc.stderr).arrayBuffer();
690
- stderr = new TextDecoder().decode(stderrBuffer);
691
- }
692
- }
693
- return {
694
- exitCode,
695
- stdout,
696
- stderr,
697
- success: exitCode === 0
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
- runtime: getCommandRuntime(cmd),
721
- command: cmd,
722
- program: builder
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({ target: "draft-2020-12" });
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 { field, as } = parseStdinConfig(stdinConfig);
858
+ const field = parseStdinConfig(stdinConfig);
923
859
  if (field in validateCtx.rawArgs && validateCtx.rawArgs[field] !== void 0) return {};
924
- const stdin = resolveStdin(getCommandRuntime(existingCommand));
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 (as === "lines") return (async () => {
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") && typeof arg.value === "string") {
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") && typeof arg.value === "string") {
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
- const runtime = evalOptions?.runtime ? Object.assign({}, baseRuntime, Object.fromEntries(Object.entries(evalOptions.runtime).filter(([, v]) => v !== void 0))) : baseRuntime;
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") return import("./completion.mjs").then(({ detectShell, generateCompletionOutput, setupCompletions }) => {
1154
- if (builtin.setup) {
1155
- const shell = builtin.shell ?? detectShell();
1156
- if (!shell) throw new Error("Could not detect shell. Specify one: completion bash --setup");
1157
- const result = setupCompletions(existingCommand.name, shell);
1158
- const message = `${result.updated ? "Updated" : "Added"} ${existingCommand.name} completions in ${result.file}`;
1159
- runtime.output(message);
1160
- return {
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: message
1164
- };
1165
- }
1166
- const completionScript = generateCompletionOutput(existingCommand, builtin.shell);
1167
- runtime.output(completionScript);
1168
- return {
1169
- command: existingCommand,
1170
- args: void 0,
1171
- result: completionScript
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
- const helpText = generateHelp(existingCommand, command, { format: runtime.format });
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
- const helpText = generateHelp(existingCommand, isRootCommand ? existingCommand : command, { format: runtime.format });
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 { field, as } = parseStdinConfig(stdinConfig);
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 (as === "lines") return (async () => {
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({ target: "draft-2020-12" });
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
- const helpText = generateHelp(existingCommand, command, { format: runtime.format });
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 = evalOptions?.runtime ? {
1541
+ const ctx = {
1439
1542
  ...createActionContext(command),
1440
- runtime
1441
- } : createActionContext(command);
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 commandResult = {
1446
- command,
1447
- args: v.args,
1448
- argsResult: v.argsResult,
1449
- result: e.result
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 (command.autoOutput ?? evalOptions?.autoOutput ?? true) {
1452
- const outputOrPromise = outputValue(e.result, runtime.output);
1453
- if (outputOrPromise instanceof Promise) return outputOrPromise.then(() => commandResult);
1454
- }
1455
- return commandResult;
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
- return makeThenable(execCommand(input, evalOptions, "soft"));
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
- let replFn;
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
- const runtime = getCommandRuntime(existingCommand);
1497
- const resolvedInput = runtime.argv().join(" ") || void 0;
1498
- if (cliOptions?.repl !== false) {
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 replPrefs = {
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
- for await (const _ of replFn(replPrefs));
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 drainRepl();
1679
+ return withPromiseDrain(startMcp());
1515
1680
  }
1516
- }
1517
- let updateCheckPromise;
1518
- if (existingCommand.updateCheck) {
1519
- if (!(resolvedInput && parseCliInputToParts(resolvedInput).some((p) => p.type === "named" && p.key.length === 1 && p.key[0] === "no-update-check"))) {
1520
- const currentVersion = getVersion(existingCommand.version);
1521
- updateCheckPromise = import("./update-check-EbNDkzyV.mjs").then(({ createUpdateChecker }) => createUpdateChecker(existingCommand.name, currentVersion, existingCommand.updateCheck, runtime));
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
- const commandObj = typeof command === "string" ? findCommandByName(command, existingCommand.commands) : command;
1536
- if (!commandObj) throw new RoutingError(`Command "${command ?? ""}" not found`);
1537
- if (!commandObj.action) throw new RoutingError(`Command "${commandObj.path}" has no action`, { command: commandObj.path });
1538
- const executeCtx = {
1539
- command: commandObj,
1540
- args,
1541
- state: {}
1542
- };
1543
- const coreExecute = () => {
1544
- return { result: commandObj.action(executeCtx.args, createActionContext(commandObj)) };
1545
- };
1546
- const executedOrPromise = runPluginChain("execute", collectPlugins(commandObj), executeCtx, coreExecute);
1547
- const toResult = (e) => ({
1548
- command: commandObj,
1549
- args,
1550
- result: e.result
1551
- });
1552
- if (executedOrPromise instanceof Promise) return executedOrPromise.then(toResult);
1553
- return toResult(executedOrPromise);
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
- const builder = createPadroneBuilder(initialCommand);
1690
- const commandObj = (builderFn?.(builder))?.[commandSymbol] ?? initialCommand;
1691
- const mergedCommandObj = existingSubcommand ? mergeCommands(existingSubcommand, commandObj) : commandObj;
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
- mergedCommandObj,
1916
+ initialCommand,
1697
1917
  ...commands.slice(existingIndex + 1)
1698
- ] : [...commands, mergedCommandObj];
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 = (options) => {
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