padrone 1.7.0 → 1.8.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 (54) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +2 -1
  3. package/dist/{args-Cnq0nwSM.mjs → args-DrCXxXeP.mjs} +20 -4
  4. package/dist/args-DrCXxXeP.mjs.map +1 -0
  5. package/dist/codegen/index.mjs +1 -1
  6. package/dist/{commands-B_gufyR9.mjs → commands-DLR0rFgq.mjs} +2 -2
  7. package/dist/{commands-B_gufyR9.mjs.map → commands-DLR0rFgq.mjs.map} +1 -1
  8. package/dist/{completion-BEuflbDO.mjs → completion-UnBKfGuk.mjs} +2 -2
  9. package/dist/{completion-BEuflbDO.mjs.map → completion-UnBKfGuk.mjs.map} +1 -1
  10. package/dist/docs/index.d.mts +1 -1
  11. package/dist/docs/index.mjs +2 -2
  12. package/dist/{formatter-DrvhDMrq.d.mts → formatter-CY3KrOEd.d.mts} +3 -2
  13. package/dist/formatter-CY3KrOEd.d.mts.map +1 -0
  14. package/dist/{help-BtxLgrF_.mjs → help-B-ZMYyn-.mjs} +16 -6
  15. package/dist/help-B-ZMYyn-.mjs.map +1 -0
  16. package/dist/{index-D6-7dz0l.d.mts → index-C2n3k4e8.d.mts} +332 -116
  17. package/dist/index-C2n3k4e8.d.mts.map +1 -0
  18. package/dist/index.d.mts +17 -160
  19. package/dist/index.d.mts.map +1 -1
  20. package/dist/index.mjs +78 -65
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/{mcp-6-Jw4Bpq.mjs → mcp-D6PdtjIs.mjs} +4 -4
  23. package/dist/{mcp-6-Jw4Bpq.mjs.map → mcp-D6PdtjIs.mjs.map} +1 -1
  24. package/dist/{serve-YVTPzBCl.mjs → serve-PaCLsNoD.mjs} +4 -4
  25. package/dist/{serve-YVTPzBCl.mjs.map → serve-PaCLsNoD.mjs.map} +1 -1
  26. package/dist/test.d.mts +1 -1
  27. package/dist/zod.d.mts +1 -1
  28. package/package.json +3 -3
  29. package/src/core/args.ts +24 -1
  30. package/src/core/create.ts +21 -14
  31. package/src/core/exec.ts +4 -3
  32. package/src/core/interceptors.ts +12 -6
  33. package/src/core/program-methods.ts +12 -2
  34. package/src/core/validate.ts +26 -7
  35. package/src/extension/auto-output.ts +1 -1
  36. package/src/extension/config.ts +2 -1
  37. package/src/extension/env.ts +5 -4
  38. package/src/extension/index.ts +1 -0
  39. package/src/extension/interactive.ts +2 -1
  40. package/src/extension/logger.ts +1 -1
  41. package/src/extension/progress.ts +2 -2
  42. package/src/extension/tracing.ts +1 -1
  43. package/src/index.ts +5 -1
  44. package/src/output/formatter.ts +6 -1
  45. package/src/output/help.ts +15 -3
  46. package/src/types/args-meta.ts +10 -0
  47. package/src/types/builder.ts +140 -38
  48. package/src/types/index.ts +2 -0
  49. package/src/types/interceptor.ts +12 -12
  50. package/src/util/type-utils.ts +22 -0
  51. package/dist/args-Cnq0nwSM.mjs.map +0 -1
  52. package/dist/formatter-DrvhDMrq.d.mts.map +0 -1
  53. package/dist/help-BtxLgrF_.mjs.map +0 -1
  54. package/dist/index-D6-7dz0l.d.mts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { _ as resolveStdin, c as getCommandRuntime, d as repathCommandTree, f as resolveAllCommands, g as createTerminalReplSession, h as suggestSimilar, i as commandSymbol, l as lazyResolver, n as buildReplCompleter, o as findCommandByName, p as resolveCommand, u as mergeCommands, v as resolveStdinAlways, y as REPL_SIGINT } from "./commands-B_gufyR9.mjs";
2
- import { a as getJsonSchema, c as parsePositionalConfig, i as extractSchemaMetadata, l as preprocessArgs, n as coerceArgs, o as isArrayField, r as detectUnknownArgs, s as isAsyncStreamField, t as applyValues } from "./args-Cnq0nwSM.mjs";
1
+ import { _ as resolveStdin, c as getCommandRuntime, d as repathCommandTree, f as resolveAllCommands, g as createTerminalReplSession, h as suggestSimilar, i as commandSymbol, l as lazyResolver, n as buildReplCompleter, o as findCommandByName, p as resolveCommand, u as mergeCommands, v as resolveStdinAlways, y as REPL_SIGINT } from "./commands-DLR0rFgq.mjs";
2
+ import { a as getJsonSchema, c as parsePositionalConfig, i as extractSchemaMetadata, l as preprocessArgs, n as coerceArgs, o as isArrayField, r as detectUnknownArgs, s as isAsyncStreamField, t as applyValues } from "./args-DrCXxXeP.mjs";
3
3
  import { i as createStdinStream, r as concatBytes, t as asyncStream } from "./stream-DC4H8YTx.mjs";
4
- import { a as escapeHtml, i as getVersion, o as resolveOutputFormat, r as getRootCommand, s as colorThemes, t as generateHelp } from "./help-BtxLgrF_.mjs";
4
+ import { a as escapeHtml, i as getVersion, o as resolveOutputFormat, r as getRootCommand, s as colorThemes, t as generateHelp } from "./help-B-ZMYyn-.mjs";
5
5
  import { a as SignalError, i as RoutingError, n as ConfigError, o as ValidationError, r as PadroneError, s as signalExitCode, t as ActionError } from "./errors-DA4KzK1M.mjs";
6
6
  //#region src/core/results.ts
7
7
  /**
@@ -239,7 +239,14 @@ function runInterceptorChain(phase, interceptors, ctx, core) {
239
239
  for (let i = phaseInterceptors.length - 1; i >= 0; i--) {
240
240
  const handler = phaseInterceptors[i][phase];
241
241
  const prevNext = next;
242
- next = (currentCtx) => handler(currentCtx, (overrides) => prevNext(overrides ? Object.assign({}, currentCtx, overrides) : currentCtx));
242
+ next = (currentCtx) => handler(currentCtx, (overrides) => {
243
+ if (!overrides) return prevNext(currentCtx);
244
+ if (overrides.context != null && typeof overrides.context === "object") overrides = {
245
+ ...overrides,
246
+ context: Object.assign({}, currentCtx.context, overrides.context)
247
+ };
248
+ return prevNext(Object.assign({}, currentCtx, overrides));
249
+ });
243
250
  }
244
251
  return next(ctx);
245
252
  }
@@ -640,10 +647,7 @@ function createAutoOutputInterceptor(outputConfig) {
640
647
  if (collected instanceof Promise) return collected.then((v) => ({ result: v }));
641
648
  return { result: collected };
642
649
  };
643
- const executedOrPromise = next({ context: {
644
- ...ctx.context,
645
- output: indicator
646
- } });
650
+ const executedOrPromise = next({ context: { output: indicator } });
647
651
  if (executedOrPromise instanceof Promise) return executedOrPromise.then(handleResult);
648
652
  return handleResult(executedOrPromise);
649
653
  } }));
@@ -934,9 +938,11 @@ function parseCommand(input, rootCommand, findCommandByName) {
934
938
  unmatchedTerms
935
939
  };
936
940
  const argsMeta = curCommand.meta?.fields;
937
- const { flags, aliases } = curCommand.argsSchema ? extractSchemaMetadata(curCommand.argsSchema, argsMeta, curCommand.meta?.autoAlias) : {
941
+ const { flags, aliases, negatives, customNegation } = curCommand.argsSchema ? extractSchemaMetadata(curCommand.argsSchema, argsMeta, curCommand.meta?.autoAlias) : {
938
942
  flags: {},
939
- aliases: {}
943
+ aliases: {},
944
+ negatives: {},
945
+ customNegation: /* @__PURE__ */ new Set()
940
946
  };
941
947
  const arrayArguments = /* @__PURE__ */ new Set();
942
948
  if (curCommand.argsSchema) try {
@@ -951,9 +957,16 @@ function parseCommand(input, rootCommand, findCommandByName) {
951
957
  let key;
952
958
  if (arg.type === "alias" && arg.key.length === 1 && flags[arg.key[0]]) key = [flags[arg.key[0]]];
953
959
  else if (arg.type === "named" && arg.key.length === 1 && aliases[arg.key[0]]) key = [aliases[arg.key[0]]];
954
- else key = arg.key;
960
+ else if (arg.type === "named" && arg.key.length === 1 && negatives[arg.key[0]]) {
961
+ setNestedValue(rawArgs, [negatives[arg.key[0]]], false);
962
+ continue;
963
+ } else key = arg.key;
955
964
  const rootKey = key[0];
956
965
  if (arg.type === "named" && arg.negated) {
966
+ if (customNegation.has(rootKey)) {
967
+ setNestedValue(rawArgs, [`no-${key.join(".")}`], false);
968
+ continue;
969
+ }
957
970
  setNestedValue(rawArgs, key, false);
958
971
  continue;
959
972
  }
@@ -990,12 +1003,21 @@ function buildCommandArgs(command, rawArgs, positionalArgs) {
990
1003
  flags: {},
991
1004
  aliases: {}
992
1005
  });
1006
+ let issues;
993
1007
  const positionalConfig = command.meta?.positional ? parsePositionalConfig(command.meta.positional) : [];
994
1008
  if (positionalConfig.length > 0) {
995
1009
  let argIndex = 0;
996
1010
  for (let i = 0; i < positionalConfig.length; i++) {
997
1011
  const { name, variadic } = positionalConfig[i];
998
1012
  if (argIndex >= positionalArgs.length) break;
1013
+ if (name in preprocessedArgs) {
1014
+ issues ??= [];
1015
+ issues.push({
1016
+ path: [name],
1017
+ message: `Ambiguous argument "${name}": provided both positionally and as a named option`
1018
+ });
1019
+ continue;
1020
+ }
999
1021
  if (variadic) {
1000
1022
  const nonVariadicAfter = positionalConfig.slice(i + 1).filter((p) => !p.variadic).length;
1001
1023
  const variadicEnd = positionalArgs.length - nonVariadicAfter;
@@ -1011,7 +1033,10 @@ function buildCommandArgs(command, rawArgs, positionalArgs) {
1011
1033
  }
1012
1034
  }
1013
1035
  if (command.argsSchema) preprocessedArgs = coerceArgs(preprocessedArgs, command.argsSchema);
1014
- return preprocessedArgs;
1036
+ return {
1037
+ args: preprocessedArgs,
1038
+ issues
1039
+ };
1015
1040
  }
1016
1041
  /**
1017
1042
  * Detects unknown options in args that aren't defined in the schema.
@@ -1024,8 +1049,8 @@ function checkUnknownArgs(command, preprocessedArgs) {
1024
1049
  return unknowns;
1025
1050
  }
1026
1051
  const argsMeta = command.meta?.fields;
1027
- const { flags, aliases } = extractSchemaMetadata(command.argsSchema, argsMeta, command.meta?.autoAlias);
1028
- return detectUnknownArgs(preprocessedArgs, command.argsSchema, flags, aliases);
1052
+ const { flags, aliases, negatives } = extractSchemaMetadata(command.argsSchema, argsMeta, command.meta?.autoAlias);
1053
+ return detectUnknownArgs(preprocessedArgs, command.argsSchema, flags, aliases, negatives);
1029
1054
  }
1030
1055
  /**
1031
1056
  * Validates preprocessed arguments against the command's schema.
@@ -1071,7 +1096,12 @@ function formatIssueMessages(issues) {
1071
1096
  * External data sources (stdin, env, config) are not resolved here — use eval() for that.
1072
1097
  */
1073
1098
  function coreValidateForParse(command, rawArgs, positionalArgs) {
1074
- return thenMaybe(validateCommandArgs(command, buildCommandArgs(command, rawArgs, positionalArgs)), (v) => v);
1099
+ const { args: preprocessedArgs, issues } = buildCommandArgs(command, rawArgs, positionalArgs);
1100
+ if (issues) return {
1101
+ args: void 0,
1102
+ argsResult: { issues }
1103
+ };
1104
+ return thenMaybe(validateCommandArgs(command, preprocessedArgs), (v) => v);
1075
1105
  }
1076
1106
  //#endregion
1077
1107
  //#region src/extension/utils.ts
@@ -1429,7 +1459,11 @@ const interactiveInterceptor = defineInterceptor({
1429
1459
  const interactivitySuppressed = runtime.interactive === "unsupported" || effectiveInteractive === false || stdinIsPiped && effectiveInteractive !== true;
1430
1460
  const forceInteractive = !interactivitySuppressed && effectiveInteractive === true;
1431
1461
  if (!(!interactivitySuppressed && runtime.prompt && hasInteractiveConfig(command.meta))) return next();
1432
- const preprocessedArgs = buildCommandArgs(command, ctx.rawArgs, ctx.positionalArgs);
1462
+ const { args: preprocessedArgs, issues: positionalIssues } = buildCommandArgs(command, ctx.rawArgs, ctx.positionalArgs);
1463
+ if (positionalIssues) return {
1464
+ args: void 0,
1465
+ argsResult: { issues: positionalIssues }
1466
+ };
1433
1467
  const unknowns = checkUnknownArgs(command, preprocessedArgs);
1434
1468
  if (unknowns.length > 0) return {
1435
1469
  args: void 0,
@@ -1993,7 +2027,11 @@ function execCommand(resolvedInput, ctx, evalOptions, errorMode = "soft", caller
1993
2027
  evalInteractive: evalOptions?.interactive
1994
2028
  };
1995
2029
  const coreValidate = (validateCtx) => {
1996
- const preprocessedArgs = buildCommandArgs(validateCtx.command, validateCtx.rawArgs, validateCtx.positionalArgs);
2030
+ const { args: preprocessedArgs, issues } = buildCommandArgs(validateCtx.command, validateCtx.rawArgs, validateCtx.positionalArgs);
2031
+ if (issues) return {
2032
+ args: void 0,
2033
+ argsResult: { issues }
2034
+ };
1997
2035
  return thenMaybe(validateCommandArgs(validateCtx.command, preprocessedArgs), (v) => v);
1998
2036
  };
1999
2037
  const validatedOrPromise = runInterceptorChain("validate", commandInterceptors, validateCtx, coreValidate);
@@ -2260,6 +2298,11 @@ function createProgramMethods(ctx, evalCommand) {
2260
2298
  if (commandObj.path) parts.push(commandObj.path);
2261
2299
  const positionalConfig = commandObj.meta?.positional ? parsePositionalConfig(commandObj.meta.positional) : [];
2262
2300
  const positionalNames = new Set(positionalConfig.map((p) => p.name));
2301
+ const negativeKeyword = {};
2302
+ if (commandObj.argsSchema) {
2303
+ const { negatives } = extractSchemaMetadata(commandObj.argsSchema, commandObj.meta?.fields, commandObj.meta?.autoAlias);
2304
+ for (const [keyword, argName] of Object.entries(negatives)) if (!(argName in negativeKeyword)) negativeKeyword[argName] = keyword;
2305
+ }
2263
2306
  if (args && typeof args === "object") {
2264
2307
  for (const { name, variadic } of positionalConfig) {
2265
2308
  const value = args[name];
@@ -2278,6 +2321,7 @@ function createProgramMethods(ctx, evalCommand) {
2278
2321
  const stringifyValue = (key, value) => {
2279
2322
  if (value === void 0) return;
2280
2323
  if (typeof value === "boolean") if (value) parts.push(`--${key}`);
2324
+ else if (negativeKeyword[key]) parts.push(`--${negativeKeyword[key]}`);
2281
2325
  else parts.push(`--no-${key}`);
2282
2326
  else if (Array.isArray(value)) for (const v of value) {
2283
2327
  const vStr = String(v);
@@ -2457,17 +2501,17 @@ function createProgramMethods(ctx, evalCommand) {
2457
2501
  };
2458
2502
  const completion = async (shell) => {
2459
2503
  resolveAllCommands(rootCommand);
2460
- const { generateCompletionOutput } = await import("./completion-BEuflbDO.mjs");
2504
+ const { generateCompletionOutput } = await import("./completion-UnBKfGuk.mjs");
2461
2505
  return generateCompletionOutput(rootCommand, shell);
2462
2506
  };
2463
2507
  const mcp = async (prefs) => {
2464
2508
  resolveAllCommands(rootCommand);
2465
- const { startMcpServer } = await import("./mcp-6-Jw4Bpq.mjs");
2509
+ const { startMcpServer } = await import("./mcp-D6PdtjIs.mjs");
2466
2510
  return startMcpServer(ctx.builder, rootCommand, evalCommand, prefs);
2467
2511
  };
2468
2512
  const serve = async (prefs) => {
2469
2513
  resolveAllCommands(rootCommand);
2470
- const { startServeServer } = await import("./serve-YVTPzBCl.mjs");
2514
+ const { startServeServer } = await import("./serve-PaCLsNoD.mjs");
2471
2515
  return startServeServer(ctx.builder, rootCommand, evalCommand, prefs);
2472
2516
  };
2473
2517
  return {
@@ -2688,33 +2732,13 @@ function createPadroneBuilder(inputCommand) {
2688
2732
  execCtx.builder = builder;
2689
2733
  return builder;
2690
2734
  }
2691
- /**
2692
- * Identity helper that contextually types a command builder callback while preserving its full return type.
2693
- * Use this when defining commands in separate files — the parent program retains exact type information
2694
- * about the subcommand's args, result, and nested commands.
2695
- *
2696
- * @example
2697
- * ```ts
2698
- * // my-command.ts
2699
- * export const myCommand = defineCommand((c) =>
2700
- * c.arguments(z.object({ name: z.string() }))
2701
- * .action((args) => console.log(args.name))
2702
- * );
2703
- *
2704
- * // cli.ts
2705
- * createPadrone('test').command('my-command', myCommand)
2706
- * ```
2707
- *
2708
- * @example With context
2709
- * ```ts
2710
- * export const myCommand = defineCommand<{ db: Database }>((c) =>
2711
- * c.arguments(z.object({ id: z.string() }))
2712
- * .action((args, ctx) => ctx.context.db.find(args.id))
2713
- * );
2714
- * ```
2715
- */
2716
2735
  function defineCommand(fn) {
2717
- return fn;
2736
+ if (fn) return fn;
2737
+ const builder = {
2738
+ requires: () => builder,
2739
+ define: (f) => f
2740
+ };
2741
+ return builder;
2718
2742
  }
2719
2743
  //#endregion
2720
2744
  //#region src/extension/completion.ts
@@ -2736,7 +2760,7 @@ function padroneCompletion() {
2736
2760
  }), { positional: ["shell"] }).async().action(async (args, ctx) => {
2737
2761
  const rootCommand = getRootCommand(ctx.command);
2738
2762
  resolveAllCommands(rootCommand);
2739
- const { detectShell, generateCompletionOutput, setupCompletions } = await import("./completion-BEuflbDO.mjs");
2763
+ const { detectShell, generateCompletionOutput, setupCompletions } = await import("./completion-UnBKfGuk.mjs");
2740
2764
  const shell = args.shell;
2741
2765
  if (args.setup) {
2742
2766
  const resolvedShell = shell ?? await detectShell();
@@ -3310,11 +3334,7 @@ function loggerInterceptor(rawConfig) {
3310
3334
  prefix: rawConfig?.prefix ?? "",
3311
3335
  timestamps: rawConfig?.timestamps ?? ctxCfg?.timestamps ?? false
3312
3336
  };
3313
- const logger = createLogger(ctx.runtime, resolved.level, resolved, ctx.context?.tracing);
3314
- return next({ context: {
3315
- ...ctx.context,
3316
- logger
3317
- } });
3337
+ return next({ context: { logger: createLogger(ctx.runtime, resolved.level, resolved, ctx.context?.tracing) } });
3318
3338
  }
3319
3339
  };
3320
3340
  });
@@ -3414,7 +3434,7 @@ function padroneMcp(defaults) {
3414
3434
  }), { positional: ["transport"] }).async().action(async (args, ctx) => {
3415
3435
  const rootCommand = getRootCommand(ctx.command);
3416
3436
  resolveAllCommands(rootCommand);
3417
- const { startMcpServer } = await import("./mcp-6-Jw4Bpq.mjs");
3437
+ const { startMcpServer } = await import("./mcp-D6PdtjIs.mjs");
3418
3438
  const transport = args.transport === "stdio" || args.transport === "http" ? args.transport : void 0;
3419
3439
  const port = args.port ? parseInt(args.port, 10) : void 0;
3420
3440
  const prefs = {
@@ -3860,7 +3880,7 @@ function progressInterceptor(config) {
3860
3880
  };
3861
3881
  return next();
3862
3882
  },
3863
- execute(ctx, next) {
3883
+ execute(_ctx, next) {
3864
3884
  if (indicator && msgs.validation) indicator.update(msgs.progress);
3865
3885
  const effectiveIndicator = indicator ?? noopIndicator;
3866
3886
  const onSuccess = (value) => {
@@ -3876,10 +3896,7 @@ function progressInterceptor(config) {
3876
3896
  };
3877
3897
  let result;
3878
3898
  try {
3879
- result = next({ context: {
3880
- ...ctx.context,
3881
- progress: effectiveIndicator
3882
- } });
3899
+ result = next({ context: { progress: effectiveIndicator } });
3883
3900
  } catch (err) {
3884
3901
  onError(err);
3885
3902
  }
@@ -3951,7 +3968,7 @@ function padroneServe(defaults) {
3951
3968
  })).async().action(async (args, ctx) => {
3952
3969
  const rootCommand = getRootCommand(ctx.command);
3953
3970
  resolveAllCommands(rootCommand);
3954
- const { startServeServer } = await import("./serve-YVTPzBCl.mjs");
3971
+ const { startServeServer } = await import("./serve-PaCLsNoD.mjs");
3955
3972
  const port = args.port ? parseInt(args.port, 10) : void 0;
3956
3973
  const prefs = {
3957
3974
  ...defaults,
@@ -4046,7 +4063,7 @@ function tracingInterceptor(config) {
4046
4063
  },
4047
4064
  execute(ctx, next) {
4048
4065
  rootSpan = tracer.startSpan(`cli ${ctx.command.name}`);
4049
- const padroneTracer = {
4066
+ return next({ context: { tracing: {
4050
4067
  tracer,
4051
4068
  rootSpan,
4052
4069
  span(name, fn) {
@@ -4071,11 +4088,7 @@ function tracingInterceptor(config) {
4071
4088
  throw err;
4072
4089
  }
4073
4090
  }
4074
- };
4075
- return next({ context: {
4076
- ...ctx.context,
4077
- tracing: padroneTracer
4078
- } });
4091
+ } } });
4079
4092
  },
4080
4093
  error(ctx, next) {
4081
4094
  rootSpan?.recordException(ctx.error);