argsbarg 5.0.3 → 5.1.1

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/src/parse.ts CHANGED
@@ -249,21 +249,6 @@ function finishLeaf(
249
249
  optionDefs: CliOption[],
250
250
  forcePositionalsIn: boolean,
251
251
  ): ParseResult {
252
- /** Builds a parse error for positional consumption failures. */
253
- function errorResult(msg: string): ParseResult {
254
- const pr: ParseResult = {
255
- kind: ParseKind.Error,
256
- path: [],
257
- opts: {},
258
- args: [],
259
- helpExplicit: false,
260
- helpPath: [],
261
- errorMsg: msg,
262
- errorHelpPath: path,
263
- };
264
- return pr;
265
- }
266
-
267
252
  let idx = startIdx;
268
253
  const args: string[] = [];
269
254
  let forcePositionals = forcePositionalsIn;
@@ -273,7 +258,7 @@ function finishLeaf(
273
258
  if (argMax === 1) {
274
259
  if (argMin >= 1) {
275
260
  if (idx >= argv.length) {
276
- return errorResult(`Missing positional argument: ${p.name}`);
261
+ return errorResult(`Missing positional argument: ${p.name}`, path, []);
277
262
  }
278
263
  args.push(argv[idx]);
279
264
  idx += 1;
@@ -308,7 +293,7 @@ function finishLeaf(
308
293
  // MUST be false — lenient mode swallows unknown flags as positionals silently
309
294
  const tailRep = consumeOptions(optionDefs, false, argv, idx, opts);
310
295
  if (tailRep.report.err) {
311
- return errorResult(tailRep.report.err);
296
+ return errorResult(tailRep.report.err, path, []);
312
297
  }
313
298
  if (tailRep.report.sawDoubleDash) {
314
299
  forcePositionals = true;
@@ -317,7 +302,7 @@ function finishLeaf(
317
302
  idx = tailRep.nextIndex;
318
303
  continue;
319
304
  }
320
- return errorResult(`Unexpected option token: ${tok}`);
305
+ return errorResult(`Unexpected option token: ${tok}`, path, []);
321
306
  }
322
307
 
323
308
  args.push(tok);
@@ -332,13 +317,17 @@ function finishLeaf(
332
317
  }
333
318
  }
334
319
  if (count < argMin) {
335
- return errorResult(`Expected at least ${argMin} argument(s) for ${p.name}, got ${count}`);
320
+ return errorResult(
321
+ `Expected at least ${argMin} argument(s) for ${p.name}, got ${count}`,
322
+ path,
323
+ [],
324
+ );
336
325
  }
337
326
  }
338
327
 
339
328
  if (idx < argv.length) {
340
329
  if (forcePositionals) {
341
- return errorResult("Unexpected extra arguments");
330
+ return errorResult("Unexpected extra arguments", path, []);
342
331
  }
343
332
 
344
333
  if (isHelpTok(argv[idx])) {
@@ -347,12 +336,12 @@ function finishLeaf(
347
336
 
348
337
  const tailRep = consumeOptions(optionDefs, false, argv, idx, opts);
349
338
  if (tailRep.report.err) {
350
- return errorResult(tailRep.report.err);
339
+ return errorResult(tailRep.report.err, path, []);
351
340
  }
352
341
  idx = tailRep.nextIndex;
353
342
 
354
343
  if (idx < argv.length) {
355
- return errorResult("Unexpected extra arguments");
344
+ return errorResult("Unexpected extra arguments", path, []);
356
345
  }
357
346
  }
358
347
 
@@ -370,6 +359,24 @@ function finishLeaf(
370
359
 
371
360
  // ── Main Parser ───────────────────────────────────────────────────────────────
372
361
 
362
+ /** Builds a user-error parse result; `path` defaults to `errorHelpPath`. */
363
+ function errorResult(
364
+ errorMsg: string,
365
+ errorHelpPath: string[] = [],
366
+ path: string[] = errorHelpPath,
367
+ ): ParseResult {
368
+ return {
369
+ kind: ParseKind.Error,
370
+ path,
371
+ opts: {},
372
+ args: [],
373
+ helpExplicit: false,
374
+ helpPath: [],
375
+ errorMsg,
376
+ errorHelpPath,
377
+ };
378
+ }
379
+
373
380
  /** Builds a help-request result for the current routing path. */
374
381
  function helpResult(p: string[], explicit: boolean): ParseResult {
375
382
  return {
@@ -401,16 +408,7 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
401
408
  // Consume root-level options first
402
409
  const rootRep = consumeOptions(root.options ?? [], rootLenient, argv, i, opts);
403
410
  if (rootRep.report.err) {
404
- return {
405
- kind: ParseKind.Error,
406
- path: [],
407
- opts: {},
408
- args: [],
409
- helpExplicit: false,
410
- helpPath: [],
411
- errorMsg: rootRep.report.err,
412
- errorHelpPath: [],
413
- };
411
+ return errorResult(rootRep.report.err);
414
412
  }
415
413
  i = rootRep.nextIndex;
416
414
  let forcePositionals = rootRep.report.sawDoubleDash;
@@ -436,16 +434,7 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
436
434
  cmdName = root.fallbackCommand;
437
435
  node = findChild(root.commands, cmdName);
438
436
  if (!node) {
439
- return {
440
- kind: ParseKind.Error,
441
- path: [],
442
- opts: {},
443
- args: [],
444
- helpExplicit: false,
445
- helpPath: [],
446
- errorMsg: `Unknown command: ${cmdName}`,
447
- errorHelpPath: path,
448
- };
437
+ return errorResult(`Unknown command: ${cmdName}`, path, []);
449
438
  }
450
439
  } else {
451
440
  return helpResult([], false);
@@ -469,34 +458,20 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
469
458
  cmdName = fallbackCommand;
470
459
  node = findChild(root.commands, cmdName);
471
460
  if (!node) {
472
- return {
473
- kind: ParseKind.Error,
474
- path: [],
475
- opts: {},
476
- args: [],
477
- helpExplicit: false,
478
- helpPath: [],
479
- errorMsg: `Unknown command: ${cmdName}`,
480
- errorHelpPath: path,
481
- };
461
+ return errorResult(`Unknown command: ${cmdName}`, path, []);
482
462
  }
483
463
  } else {
484
464
  cmdName = peek;
485
465
  if (!forcePositionals) i += 1;
486
466
  node = findChild(root.commands, cmdName);
487
467
  if (!node) {
488
- return {
489
- kind: ParseKind.Error,
490
- path: [],
491
- opts: {},
492
- args: [],
493
- helpExplicit: false,
494
- helpPath: [],
495
- errorMsg: forcePositionals
468
+ return errorResult(
469
+ forcePositionals
496
470
  ? `Expected subcommand but got positional: ${cmdName}`
497
471
  : `Unknown command: ${cmdName}`,
498
- errorHelpPath: path,
499
- };
472
+ path,
473
+ [],
474
+ );
500
475
  }
501
476
  }
502
477
  }
@@ -504,16 +479,7 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
504
479
 
505
480
  path.push(cmdName);
506
481
  if (!node) {
507
- return {
508
- kind: ParseKind.Error,
509
- path,
510
- opts: {},
511
- args: [],
512
- helpExplicit: false,
513
- helpPath: [],
514
- errorMsg: `Unknown command: ${cmdName}`,
515
- errorHelpPath: path,
516
- };
482
+ return errorResult(`Unknown command: ${cmdName}`, path);
517
483
  }
518
484
  let current = node;
519
485
 
@@ -522,16 +488,7 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
522
488
  if (!forcePositionals) {
523
489
  const orep = consumeOptions(collectOptionDefs(root, path), false, argv, i, opts);
524
490
  if (orep.report.err) {
525
- return {
526
- kind: ParseKind.Error,
527
- path,
528
- opts: {},
529
- args: [],
530
- helpExplicit: false,
531
- helpPath: [],
532
- errorMsg: orep.report.err,
533
- errorHelpPath: path,
534
- };
491
+ return errorResult(orep.report.err, path);
535
492
  }
536
493
  i = orep.nextIndex;
537
494
  if (orep.report.sawDoubleDash) {
@@ -576,16 +533,7 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
576
533
 
577
534
  const tok = argv[i];
578
535
  if (!forcePositionals && tok.startsWith("-")) {
579
- return {
580
- kind: ParseKind.Error,
581
- path,
582
- opts: {},
583
- args: [],
584
- helpExplicit: false,
585
- helpPath: [],
586
- errorMsg: `Unexpected option token: ${tok}`,
587
- errorHelpPath: path,
588
- };
536
+ return errorResult(`Unexpected option token: ${tok}`, path);
589
537
  }
590
538
 
591
539
  if (!forcePositionals && isCliRouter(current)) {
@@ -614,18 +562,12 @@ export function parse(root: CliNode, argv: string[]): ParseResult {
614
562
  }
615
563
  }
616
564
 
617
- return {
618
- kind: ParseKind.Error,
619
- path,
620
- opts: {},
621
- args: [],
622
- helpExplicit: false,
623
- helpPath: [],
624
- errorMsg: forcePositionals
565
+ return errorResult(
566
+ forcePositionals
625
567
  ? `Expected subcommand but got positional: ${tok}`
626
568
  : `Unknown subcommand: ${tok}`,
627
- errorHelpPath: path,
628
- };
569
+ path,
570
+ );
629
571
  }
630
572
 
631
573
  if (!isCliLeaf(current)) {
@@ -656,29 +598,11 @@ export function postParseValidate(root: CliNode, pr: ParseResult): ParseResult {
656
598
 
657
599
  for (const seg of pr.path) {
658
600
  if (!isCliRouter(node)) {
659
- return {
660
- kind: ParseKind.Error,
661
- path: pr.path,
662
- opts: {},
663
- args: [],
664
- helpExplicit: false,
665
- helpPath: [],
666
- errorMsg: "Internal path error",
667
- errorHelpPath: pr.path,
668
- };
601
+ return errorResult("Internal path error", pr.path);
669
602
  }
670
603
  const ch = findChild(node.commands, seg);
671
604
  if (!ch) {
672
- return {
673
- kind: ParseKind.Error,
674
- path: pr.path,
675
- opts: {},
676
- args: [],
677
- helpExplicit: false,
678
- helpPath: [],
679
- errorMsg: "Internal path error",
680
- errorHelpPath: pr.path,
681
- };
605
+ return errorResult("Internal path error", pr.path);
682
606
  }
683
607
  defs.push(...(ch.options ?? []));
684
608
  node = ch;
@@ -693,60 +617,24 @@ export function postParseValidate(root: CliNode, pr: ParseResult): ParseResult {
693
617
 
694
618
  for (const d of defs) {
695
619
  if (d.required && !(d.name in opts)) {
696
- return {
697
- kind: ParseKind.Error,
698
- path: pr.path,
699
- opts: {},
700
- args: [],
701
- helpExplicit: false,
702
- helpPath: [],
703
- errorMsg: `Missing required option: --${d.name}`,
704
- errorHelpPath: pr.path,
705
- };
620
+ return errorResult(`Missing required option: --${d.name}`, pr.path);
706
621
  }
707
622
  }
708
623
 
709
624
  for (const [k, v] of Object.entries(opts)) {
710
625
  const d = findOptionByName(defs, k);
711
626
  if (!d) {
712
- return {
713
- kind: ParseKind.Error,
714
- path: pr.path,
715
- opts: {},
716
- args: [],
717
- helpExplicit: false,
718
- helpPath: [],
719
- errorMsg: `Unknown option key: ${k}`,
720
- errorHelpPath: pr.path,
721
- };
627
+ return errorResult(`Unknown option key: ${k}`, pr.path);
722
628
  }
723
629
  if (d.kind === CliOptionKind.Number) {
724
630
  if (!fullStringIsDouble(v)) {
725
- return {
726
- kind: ParseKind.Error,
727
- path: pr.path,
728
- opts: {},
729
- args: [],
730
- helpExplicit: false,
731
- helpPath: [],
732
- errorMsg: `Invalid number for option --${k}: ${v}`,
733
- errorHelpPath: pr.path,
734
- };
631
+ return errorResult(`Invalid number for option --${k}: ${v}`, pr.path);
735
632
  }
736
633
  }
737
634
  if (d.kind === CliOptionKind.Enum) {
738
635
  const choices = d.choices ?? [];
739
636
  if (!choices.includes(v)) {
740
- return {
741
- kind: ParseKind.Error,
742
- path: pr.path,
743
- opts: {},
744
- args: [],
745
- helpExplicit: false,
746
- helpPath: [],
747
- errorMsg: `Option --${k}: '${v}' is not one of: ${choices.join(", ")}`,
748
- errorHelpPath: pr.path,
749
- };
637
+ return errorResult(`Option --${k}: '${v}' is not one of: ${choices.join(", ")}`, pr.path);
750
638
  }
751
639
  }
752
640
  if (d.kind === CliOptionKind.String && (d.format !== undefined || d.pattern !== undefined)) {
@@ -759,16 +647,7 @@ export function postParseValidate(root: CliNode, pr: ParseResult): ParseResult {
759
647
  : err instanceof Error
760
648
  ? err.message
761
649
  : String(err);
762
- return {
763
- kind: ParseKind.Error,
764
- path: pr.path,
765
- opts: {},
766
- args: [],
767
- helpExplicit: false,
768
- helpPath: [],
769
- errorMsg: `Invalid value for option --${k}: ${msg}`,
770
- errorHelpPath: pr.path,
771
- };
650
+ return errorResult(`Invalid value for option --${k}: ${msg}`, pr.path);
772
651
  }
773
652
  }
774
653
  }
package/src/schema.ts CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  leafOutputSchema,
14
14
  } from "./types.ts";
15
15
 
16
- const RESERVED = new Set(["completion", "configure", "docs", "mcp", "version", "config"]);
16
+ const RESERVED = new Set(["completion", "configure", "docs", "mcp", "version"]);
17
17
 
18
18
  function exportCommand(cmd: CliNode, root: CliProgram): CliSchemaExport | null {
19
19
  if (cmd.hidden) {
package/src/types.ts CHANGED
@@ -236,7 +236,7 @@ export interface CliAppConfigEntry {
236
236
  /** When `false`, optional for bootstrap and MCP enforcement. Default: `true`. */
237
237
  required?: boolean;
238
238
  /**
239
- * Mask stdin during prompts and redact on `config get`.
239
+ * Mask stdin during prompts and redact on `configure get`.
240
240
  * Default: `/key|token|secret|password/i.test(name)`.
241
241
  */
242
242
  sensitive?: boolean;
@@ -253,7 +253,7 @@ export interface CliAppConfigEntry {
253
253
  * App configuration block on the program root ({@link CliProgram.appConfig}).
254
254
  */
255
255
  export interface CliAppConfig {
256
- /** Built-in `config get` / `config set`. Default: enabled when `appConfig` is set. */
256
+ /** Built-in `configure get` / `configure set`. Default: enabled when `appConfig` is set. */
257
257
  commands?: boolean | { enabled?: boolean; mcpSet?: boolean };
258
258
  /** Block JSON Schema (draft-07). When omitted, synthesize all-string schema from `entries`. */
259
259
  jsonSchema?: Record<string, unknown>;
package/src/validate.ts CHANGED
@@ -6,7 +6,7 @@ import { reservedCommandNames, resolveCapabilities } from "./capabilities.ts";
6
6
  import { reservedDocsTopicResourceUris } from "./docs/mcp-resources.ts";
7
7
  import { DOCS_BUILTIN_TOPIC_KEYS } from "./docs/resolve.ts";
8
8
  import { validateFormatValue } from "./formats.ts";
9
- import { AGENT_PAIRS } from "./install/target-registry.ts";
9
+ import { AGENT_PAIRS, MCP_KEYS, mcpServerRequiredForArtifact } from "./install/target-registry.ts";
10
10
  import { resolveMcpSchemaUri } from "./mcp/tools.ts";
11
11
  import {
12
12
  type CliLeaf,
@@ -150,6 +150,8 @@ function validateConfigureConfig(program: CliProgram): void {
150
150
  const integration: InstallAgentIntegration =
151
151
  configure.agentIntegration ?? (program.mcpServer?.enabled === true ? "mcp" : "skill");
152
152
 
153
+ const mcpEnabled = program.mcpServer?.enabled === true;
154
+
153
155
  for (const [mcpKey, skillKey] of AGENT_PAIRS) {
154
156
  const mcpSpec = targets[mcpKey];
155
157
  const skillSpec = targets[skillKey];
@@ -174,6 +176,15 @@ function validateConfigureConfig(program: CliProgram): void {
174
176
  );
175
177
  }
176
178
  }
179
+
180
+ for (const mcpKey of MCP_KEYS) {
181
+ if (
182
+ !mcpServerRequiredForArtifact(mcpKey, mcpEnabled) &&
183
+ installTargetExplicitTruthy(targets[mcpKey])
184
+ ) {
185
+ throw new CliSchemaValidationError(`configure.targets.${mcpKey} requires mcpServer.enabled`);
186
+ }
187
+ }
177
188
  }
178
189
 
179
190
  /** Validates a program schema. */