@alcyone-labs/arg-parser 2.10.2 → 2.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1370,6 +1370,22 @@ const _DxtPathResolver = class _DxtPathResolver {
1370
1370
  };
1371
1371
  _DxtPathResolver._cachedContext = null;
1372
1372
  let DxtPathResolver = _DxtPathResolver;
1373
+ const FlagInheritance = {
1374
+ /**
1375
+ * No flags are inherited from the parent.
1376
+ */
1377
+ NONE: "none",
1378
+ /**
1379
+ * Inherits flags only from the direct parent at the time of attachment (Snapshot behavior).
1380
+ * Equivalent to `true` in legacy boolean config.
1381
+ */
1382
+ DirectParentOnly: "direct-parent-only",
1383
+ /**
1384
+ * Inherits flags from the entire parent chain, ensuring grandchildren receive root flags
1385
+ * even in bottom-up construction scenarios.
1386
+ */
1387
+ AllParents: "all-parents"
1388
+ };
1373
1389
  const zodDxtOptionsSchema = z.object({
1374
1390
  sensitive: z.boolean().optional().describe(
1375
1391
  "Whether this field should be marked as sensitive in DXT user_config"
@@ -3685,6 +3701,7 @@ class ArgParserBase {
3685
3701
  #dxtGenerator;
3686
3702
  #configurationManager;
3687
3703
  #fuzzyMode = false;
3704
+ #triggerAutoHelpIfNoHandler = false;
3688
3705
  // Track dynamically added flags so we can clean them between parses
3689
3706
  #dynamicFlagNames = /* @__PURE__ */ new Set();
3690
3707
  // MCP-related managers
@@ -3712,6 +3729,7 @@ class ArgParserBase {
3712
3729
  this.#handleErrors = options.handleErrors ?? true;
3713
3730
  this.#autoExit = options.autoExit ?? true;
3714
3731
  this.#inheritParentFlags = options.inheritParentFlags ?? false;
3732
+ this.#triggerAutoHelpIfNoHandler = options.triggerAutoHelpIfNoHandler ?? false;
3715
3733
  this.#description = options.description;
3716
3734
  this.#handler = options.handler;
3717
3735
  this.#appCommandName = options.appCommandName;
@@ -3916,7 +3934,9 @@ class ArgParserBase {
3916
3934
  subParser.#appCommandName = this.#appCommandName;
3917
3935
  }
3918
3936
  subParser.#autoExit = this.#autoExit;
3919
- if (subParser.#inheritParentFlags) {
3937
+ subParser.#triggerAutoHelpIfNoHandler = this.#triggerAutoHelpIfNoHandler;
3938
+ const shouldInherit = subParser.#inheritParentFlags === true || subParser.#inheritParentFlags === FlagInheritance.DirectParentOnly || subParser.#inheritParentFlags === FlagInheritance.AllParents;
3939
+ if (shouldInherit) {
3920
3940
  const parentFlags = this.#flagManager.flags;
3921
3941
  for (const parentFlag of parentFlags) {
3922
3942
  if (!subParser.#flagManager.hasFlag(parentFlag["name"])) {
@@ -3925,11 +3945,36 @@ class ArgParserBase {
3925
3945
  }
3926
3946
  }
3927
3947
  this.#subCommands.set(subCommandConfig.name, subCommandConfig);
3948
+ this.#propagateFlagsRecursive(subParser);
3928
3949
  if (subCommandConfig.handler) {
3929
3950
  subParser.setHandler(subCommandConfig.handler);
3930
3951
  }
3931
3952
  return this;
3932
3953
  }
3954
+ /**
3955
+ * Propagates available flags from the current parser to its subcommands,
3956
+ * if those subcommands are configured to inherit recursively (AllParents).
3957
+ */
3958
+ #propagateFlagsRecursive(parser) {
3959
+ for (const [_, subConfig] of parser.getSubCommands()) {
3960
+ const childParser = subConfig.parser;
3961
+ if (!(childParser instanceof ArgParserBase)) continue;
3962
+ const isAllParents = childParser.#inheritParentFlags === FlagInheritance.AllParents;
3963
+ if (isAllParents) {
3964
+ const parentFlags = parser.#flagManager.flags;
3965
+ let flagsAdded = false;
3966
+ for (const parentFlag of parentFlags) {
3967
+ if (!childParser.#flagManager.hasFlag(parentFlag["name"])) {
3968
+ childParser.#flagManager._setProcessedFlagForInheritance(parentFlag);
3969
+ flagsAdded = true;
3970
+ }
3971
+ }
3972
+ if (flagsAdded) {
3973
+ this.#propagateFlagsRecursive(childParser);
3974
+ }
3975
+ }
3976
+ }
3977
+ }
3933
3978
  /**
3934
3979
  * Sets the handler function for this specific parser instance.
3935
3980
  * This handler will be executed if this parser is the final one
@@ -4592,16 +4637,29 @@ class ArgParserBase {
4592
4637
  finalParseResultArgs["$commandChain"] = commandChainSoFar;
4593
4638
  }
4594
4639
  let handlerToExecute = void 0;
4640
+ const handlerContext = {
4641
+ args: currentLevelArgs,
4642
+ parentArgs: accumulatedParentArgs,
4643
+ commandChain: commandChainSoFar,
4644
+ parser: currentParser,
4645
+ parentParser,
4646
+ // displayHelp implementation that respects autoExit setting
4647
+ displayHelp: () => {
4648
+ console.log(currentParser.helpText());
4649
+ if (currentParser.getAutoExit() && typeof process === "object" && typeof process.exit === "function") {
4650
+ process.exit(0);
4651
+ }
4652
+ }
4653
+ };
4595
4654
  if (currentParser.#handler) {
4596
4655
  handlerToExecute = {
4597
4656
  handler: currentParser.#handler,
4598
- context: {
4599
- args: currentLevelArgs,
4600
- parentArgs: accumulatedParentArgs,
4601
- commandChain: commandChainSoFar,
4602
- parser: currentParser,
4603
- parentParser
4604
- }
4657
+ context: handlerContext
4658
+ };
4659
+ } else if (currentParser.#triggerAutoHelpIfNoHandler) {
4660
+ handlerToExecute = {
4661
+ handler: (ctx) => ctx.displayHelp(),
4662
+ context: handlerContext
4605
4663
  };
4606
4664
  }
4607
4665
  return { finalArgs: finalParseResultArgs, handlerToExecute };
@@ -5716,6 +5774,9 @@ ${simpleChalk.dim(`Try '${commandNameToSuggest} --help' for usage details.`)}`
5716
5774
  return options;
5717
5775
  }
5718
5776
  }
5777
+ const autoHelpHandler = async (ctx) => {
5778
+ ctx.displayHelp();
5779
+ };
5719
5780
  function sanitizeMcpToolName(name) {
5720
5781
  if (!name || typeof name !== "string") {
5721
5782
  throw new Error("Tool name must be a non-empty string");
@@ -6203,7 +6264,12 @@ function generateMcpToolsFromArgParser(rootParser, options) {
6203
6264
  parser: rootParser,
6204
6265
  parentArgs: void 0,
6205
6266
  isMcp: true,
6206
- getFlag
6267
+ getFlag,
6268
+ displayHelp: () => {
6269
+ console.error(
6270
+ "Help display is not supported in MCP mode."
6271
+ );
6272
+ }
6207
6273
  };
6208
6274
  const handlerResult = await toolConfig.handler(handlerContext);
6209
6275
  if (process.env["MCP_DEBUG"]) {
@@ -6444,7 +6510,12 @@ function generateMcpToolsFromArgParser(rootParser, options) {
6444
6510
  parser: finalParser,
6445
6511
  parentArgs: resolvedParentArgs,
6446
6512
  isMcp: true,
6447
- getFlag
6513
+ getFlag,
6514
+ displayHelp: () => {
6515
+ console.error(
6516
+ "Help display is not supported in MCP mode."
6517
+ );
6518
+ }
6448
6519
  };
6449
6520
  try {
6450
6521
  handlerResponse = await handlerToCall(handlerContext);
@@ -7129,7 +7200,10 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
7129
7200
  parentArgs: {},
7130
7201
  commandChain: [toolConfig.name],
7131
7202
  parser: this,
7132
- isMcp: true
7203
+ isMcp: true,
7204
+ displayHelp: () => {
7205
+ console.error("Help display is not supported in MCP mode.");
7206
+ }
7133
7207
  };
7134
7208
  const startTime = Date.now();
7135
7209
  const result = await toolConfig.handler(context);
@@ -26217,6 +26291,7 @@ export {
26217
26291
  ConfigPluginRegistry,
26218
26292
  DxtPathResolver,
26219
26293
  EnvConfigPlugin,
26294
+ FlagInheritance,
26220
26295
  JsonConfigPlugin,
26221
26296
  Logger,
26222
26297
  OutputSchemaPatterns,
@@ -26225,6 +26300,7 @@ export {
26225
26300
  index$2 as UI,
26226
26301
  YamlConfigPlugin,
26227
26302
  absolutePath,
26303
+ autoHelpHandler,
26228
26304
  convertFlagToJsonSchemaProperty,
26229
26305
  convertFlagsToJsonSchema,
26230
26306
  convertFlagsToZodSchema,