argsbarg 5.0.1 → 5.0.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +15 -1
  2. package/docs/distribution-homebrew.md +2 -0
  3. package/examples/full-example/scripts/formula-shared.ts +1 -0
  4. package/index.d.ts +10 -5
  5. package/package.json +1 -1
  6. package/src/builtins/builtins.test.ts +12 -0
  7. package/src/builtins/config.test.ts +8 -0
  8. package/src/cli-tool/cli-smoke.test.ts +5 -0
  9. package/src/cli-tool/create.test.ts +10 -0
  10. package/src/cli-tool/full-example-capabilities.test.ts +6 -0
  11. package/src/cli-tool/main.ts +0 -0
  12. package/src/config/context.test.ts +7 -0
  13. package/src/config/file.test.ts +7 -0
  14. package/src/config/resolve.test.ts +11 -0
  15. package/src/config/validate.test.ts +5 -0
  16. package/src/config.integration.test.ts +5 -0
  17. package/src/configure/configure.test.ts +11 -0
  18. package/src/configure/index.ts +14 -0
  19. package/src/configure/prompt.ts +7 -0
  20. package/src/docs/api-guide.test.ts +6 -0
  21. package/src/docs/docs.test.ts +7 -0
  22. package/src/docs/mcp-resources.test.ts +4 -0
  23. package/src/formats.test.ts +4 -0
  24. package/src/headless.test.ts +6 -0
  25. package/src/headless.ts +5 -4
  26. package/src/hidden-mcpb.test.ts +10 -0
  27. package/src/install/binary-placement.test.ts +9 -0
  28. package/src/install/gh-release-update.test.ts +4 -0
  29. package/src/install/install-validate.test.ts +5 -0
  30. package/src/install/mcp-codex.test.ts +7 -0
  31. package/src/install/mcp-openclaw.test.ts +6 -0
  32. package/src/install/mcp-opencode.test.ts +6 -0
  33. package/src/install/status.test.ts +9 -0
  34. package/src/install/targets.test.ts +9 -0
  35. package/src/invoke.test.ts +7 -0
  36. package/src/mcp/claude.test.ts +6 -0
  37. package/src/mcp/env.test.ts +7 -0
  38. package/src/mcp/zip.test.ts +4 -0
  39. package/src/mcp.integration.test.ts +17 -0
  40. package/src/parse.test.ts +43 -0
package/src/parse.test.ts CHANGED
@@ -31,6 +31,7 @@ import {
31
31
  } from "./test-fixtures.ts";
32
32
  import { cliValidateProgram } from "./validate.ts";
33
33
 
34
+ /** Tests that bundled short presence flags. */
34
35
  test("bundled short presence flags", () => {
35
36
  const root = testProgram({
36
37
  key: "app",
@@ -64,6 +65,7 @@ test("bundled short presence flags", () => {
64
65
  expect(pr.opts.b).toBe("1");
65
66
  });
66
67
 
68
+ /** Tests that long option equals. */
67
69
  test("long option equals", () => {
68
70
  const root = testProgram({
69
71
  key: "app",
@@ -89,6 +91,7 @@ test("long option equals", () => {
89
91
  expect(pr.opts.name).toBe("pat");
90
92
  });
91
93
 
94
+ /** Tests that fallback missing or unknown root flags. */
92
95
  test("fallback missing or unknown root flags", () => {
93
96
  const root = testProgram({
94
97
  key: "app",
@@ -141,6 +144,7 @@ test("implicit help empty", () => {
141
144
  expect(pr.helpExplicit).toBe(false);
142
145
  });
143
146
 
147
+ /** Invalid number post validate. */
144
148
  test("invalid number post validate", () => {
145
149
  const root = testProgram({
146
150
  key: "app",
@@ -167,6 +171,7 @@ test("invalid number post validate", () => {
167
171
  expect(pr.errorMsg).toContain("Invalid number");
168
172
  });
169
173
 
174
+ /** Supports scientific notation in numbers. */
170
175
  test("supports scientific notation in numbers", () => {
171
176
  const root = testProgram({
172
177
  key: "app",
@@ -193,6 +198,7 @@ test("supports scientific notation in numbers", () => {
193
198
  expect(Number(pr.opts.n)).toBe(12300);
194
199
  });
195
200
 
201
+ /** Completion scripts contain app name. */
196
202
  test("completion scripts contain app name", () => {
197
203
  const root = testProgram({
198
204
  key: "myapp",
@@ -210,6 +216,7 @@ test("completion scripts contain app name", () => {
210
216
  expect(zsh).toContain("hello:Say hello.");
211
217
  });
212
218
 
219
+ /** Completion scripts do not emit invalid bash substitutions. */
213
220
  test("completion scripts do not emit invalid bash substitutions", () => {
214
221
  const root = testProgram({
215
222
  key: "app",
@@ -221,6 +228,7 @@ test("completion scripts do not emit invalid bash substitutions", () => {
221
228
  expect(bash).not.toContain("${${");
222
229
  });
223
230
 
231
+ /** Completion scripts escape shell-sensitive command text in zsh. */
224
232
  test("completion scripts escape shell-sensitive command text in zsh", () => {
225
233
  const root = testProgram({
226
234
  key: "app",
@@ -238,6 +246,7 @@ test("completion scripts escape shell-sensitive command text in zsh", () => {
238
246
  expect(zsh).toContain("quote'\\''cmd:Say '\\''hello'\\'' and keep going.");
239
247
  });
240
248
 
249
+ /** Completion scripts keep dotted app names in registration names. */
241
250
  test("completion scripts keep dotted app names in registration names", () => {
242
251
  const root = testProgram({
243
252
  key: "minimal.ts",
@@ -253,6 +262,7 @@ test("completion scripts keep dotted app names in registration names", () => {
253
262
  expect(zsh).toContain("compdef _minimal_ts minimal.ts");
254
263
  });
255
264
 
265
+ /** Tests that trailing options after bounded positionals. */
256
266
  test("trailing options after bounded positionals", () => {
257
267
  const root = testProgram({
258
268
  key: "app",
@@ -286,6 +296,7 @@ test("trailing options after bounded positionals", () => {
286
296
  expect(pr.opts.verbose).toBe("1");
287
297
  });
288
298
 
299
+ /** Tests that trailing options include parent-scoped flags. */
289
300
  test("trailing options include parent-scoped flags", () => {
290
301
  const root = testProgram({
291
302
  key: "app",
@@ -338,6 +349,7 @@ test("trailing options include parent-scoped flags", () => {
338
349
  expect(pr.opts.json).toBe("1");
339
350
  });
340
351
 
352
+ /** Varargs tail parses trailing options. */
341
353
  test("varargs tail parses trailing options", () => {
342
354
  const root = testProgram({
343
355
  key: "app",
@@ -373,6 +385,7 @@ test("varargs tail parses trailing options", () => {
373
385
  expect(pr.opts.json).toBe("1");
374
386
  });
375
387
 
388
+ /** Stops parsing options at --. */
376
389
  test("stops parsing options at --", () => {
377
390
  const root = testProgram({
378
391
  key: "app",
@@ -411,6 +424,7 @@ test("stops parsing options at --", () => {
411
424
  expect(pr.args).toEqual(["--name", "bob", "-x"]);
412
425
  });
413
426
 
427
+ /** Missing required option returns error. */
414
428
  test("missing required option returns error", () => {
415
429
  const root = testProgram({
416
430
  key: "app",
@@ -437,6 +451,7 @@ test("missing required option returns error", () => {
437
451
  expect(pr.errorMsg).toContain("Missing required option: --req");
438
452
  });
439
453
 
454
+ /** Provided required option parses ok. */
440
455
  test("provided required option parses ok", () => {
441
456
  const root = testProgram({
442
457
  key: "app",
@@ -463,6 +478,7 @@ test("provided required option parses ok", () => {
463
478
  expect(pr.opts.req).toBe("val");
464
479
  });
465
480
 
481
+ /** Tests that presence option cannot be required. */
466
482
  test("presence option cannot be required", () => {
467
483
  const root = testProgram({
468
484
  key: "app",
@@ -499,6 +515,7 @@ test("leaf completion help prints correctly", async () => {
499
515
  expect(stderr.toString()).toBe("");
500
516
  });
501
517
 
518
+ /** Docs schema exports JSON for nested CLIs. */
502
519
  test("docs schema exports JSON for nested CLIs", async () => {
503
520
  const { stdout, stderr, exitCode } = await $`bun run examples/nested.ts docs schema`
504
521
  .nothrow()
@@ -517,6 +534,7 @@ test("docs schema exports JSON for nested CLIs", async () => {
517
534
  expect(lookup.positionals[0].name).toBe("path");
518
535
  });
519
536
 
537
+ /** Docs schema exports JSON for leaf roots. */
520
538
  test("docs schema exports JSON for leaf roots", async () => {
521
539
  const { stdout, exitCode } = await $`bun run examples/minimal.ts docs schema`.nothrow().quiet();
522
540
  expect(exitCode).toBe(0);
@@ -545,6 +563,7 @@ test("leaf root help omits hidden completion built-in", async () => {
545
563
  expect(stdout.toString()).toContain("configure");
546
564
  });
547
565
 
566
+ /** Root --schema is no longer a flag. */
548
567
  test("root --schema is no longer a flag", () => {
549
568
  const root = testProgram({
550
569
  key: "app",
@@ -567,6 +586,7 @@ test("root --schema is no longer a flag", () => {
567
586
  expect(pr.kind).not.toBe(ParseKind.Ok);
568
587
  });
569
588
 
589
+ /** CliSchemaJson omits handlers and completion built-ins. */
570
590
  test("cliSchemaJson omits handlers and completion built-ins", () => {
571
591
  const root = testProgram({
572
592
  key: "app",
@@ -597,6 +617,7 @@ test("cliSchemaJson omits handlers and completion built-ins", () => {
597
617
  expect(schema).not.toHaveProperty("handler");
598
618
  });
599
619
 
620
+ /** CliSchemaExport resolves program key in install notes. */
600
621
  test("cliSchemaExport resolves program key in install notes", () => {
601
622
  const root = testProgram({
602
623
  key: "myapp",
@@ -616,6 +637,7 @@ test("cliSchemaExport resolves program key in install notes", () => {
616
637
  expect(json).toContain("brew install");
617
638
  });
618
639
 
640
+ /** CliSchemaExport resolves {argsbarg:program} in consumer notes. */
619
641
  test("cliSchemaExport resolves {argsbarg:program} in consumer notes", () => {
620
642
  const root = testProgram({
621
643
  key: "myapp",
@@ -635,6 +657,7 @@ test("cliSchemaExport resolves {argsbarg:program} in consumer notes", () => {
635
657
  expect(schema.commands[0].notes).toBe("Run `myapp run` to start.");
636
658
  });
637
659
 
660
+ /** Docs help lists schema, api, and skill subcommands. */
638
661
  test("docs help lists schema, api, and skill subcommands", () => {
639
662
  const root = testProgram({
640
663
  key: "app",
@@ -661,6 +684,7 @@ test("docs help lists schema, api, and skill subcommands", () => {
661
684
  expect(help).toContain("reference agent SKILL");
662
685
  });
663
686
 
687
+ /** Root help omits legacy --schema flag. */
664
688
  test("root help omits legacy --schema flag", () => {
665
689
  const root = testProgram({
666
690
  key: "app",
@@ -678,6 +702,7 @@ test("root help omits legacy --schema flag", () => {
678
702
  expect(help).not.toContain("--schema");
679
703
  });
680
704
 
705
+ /** Root help shows agent docs hint when docs enabled. */
681
706
  test("root help shows agent docs hint when docs enabled", () => {
682
707
  const root = testProgram({
683
708
  key: "myapp",
@@ -706,6 +731,7 @@ test("root help omits agent hint when docs disabled", () => {
706
731
  expect(help).not.toContain("docs skill");
707
732
  });
708
733
 
734
+ /** Root help includes program notes and agent hint. */
709
735
  test("root help includes program notes and agent hint", () => {
710
736
  const root = testProgram({
711
737
  key: "myapp",
@@ -750,6 +776,7 @@ test("cliValidateProgram rejects Enum with duplicate choices", () => {
750
776
  expect(() => cliValidateProgram(root)).toThrow(/choices must be distinct/);
751
777
  });
752
778
 
779
+ /** McpTool.description override wins without env suffix. */
753
780
  test("mcpTool.description override wins without env suffix", () => {
754
781
  const root = testProgram({
755
782
  key: "app",
@@ -778,6 +805,7 @@ test("cliValidateProgram requires program.appConfig description", () => {
778
805
  expect(() => cliValidateProgram(root)).toThrow(/description must be a non-empty string/);
779
806
  });
780
807
 
808
+ /** CliValidateProgram rejects duplicate mcpResources URIs. */
781
809
  test("cliValidateProgram rejects duplicate mcpResources URIs", () => {
782
810
  const root = testProgram({
783
811
  key: "app",
@@ -837,6 +865,7 @@ test("cliValidateProgram rejects resource URI matching default schema URI", () =
837
865
  expect(() => cliValidateProgram(root)).toThrow(/conflicts with built-in schema resource/);
838
866
  });
839
867
 
868
+ /** CliValidateProgram rejects resource URI matching schemaResourceUri. */
840
869
  test("cliValidateProgram rejects resource URI matching schemaResourceUri", () => {
841
870
  const root = testProgram({
842
871
  key: "app",
@@ -851,6 +880,7 @@ test("cliValidateProgram rejects resource URI matching schemaResourceUri", () =>
851
880
  expect(() => cliValidateProgram(root)).toThrow(/conflicts with built-in schema resource/);
852
881
  });
853
882
 
883
+ /** CliValidateProgram rejects resource URI matching auto docs topic. */
854
884
  test("cliValidateProgram rejects resource URI matching auto docs topic", () => {
855
885
  const root = testProgram({
856
886
  key: "app",
@@ -865,6 +895,7 @@ test("cliValidateProgram rejects resource URI matching auto docs topic", () => {
865
895
  expect(() => cliValidateProgram(root)).toThrow(/conflicts with auto docs topic resource/);
866
896
  });
867
897
 
898
+ /** AllMcpResources includes custom resources. */
868
899
  test("allMcpResources includes custom resources", () => {
869
900
  const root = testProgram({
870
901
  key: "app",
@@ -880,6 +911,7 @@ test("allMcpResources includes custom resources", () => {
880
911
  expect(resources.map((r) => r.uri)).toContain("test://x");
881
912
  });
882
913
 
914
+ /** AllMcpResources includes docs topic resources. */
883
915
  test("allMcpResources includes docs topic resources", () => {
884
916
  const root = testProgram({
885
917
  key: "app",
@@ -894,6 +926,7 @@ test("allMcpResources includes docs topic resources", () => {
894
926
  expect(readme?.load()).toBe("# hi\n");
895
927
  });
896
928
 
929
+ /** ApplyShellEnv merges PATH and preserves host vars. */
897
930
  test("applyShellEnv merges PATH and preserves host vars", () => {
898
931
  const origPath = process.env.PATH ?? "";
899
932
  const origHome = process.env.HOME;
@@ -913,6 +946,7 @@ test("applyShellEnv merges PATH and preserves host vars", () => {
913
946
  delete process.env.NEWVAR;
914
947
  });
915
948
 
949
+ /** Enum completions list choices in bash script. */
916
950
  test("Enum completions list choices in bash script", () => {
917
951
  const root = testProgram({
918
952
  key: "app",
@@ -942,6 +976,7 @@ test("nested fallback routes to default when argv exhausted at router", () => {
942
976
  expect(pr.path).toEqual(["docs", "guide"]);
943
977
  });
944
978
 
979
+ /** Nested fallback MissingOrUnknown routes unknown token to default. */
945
980
  test("nested fallback MissingOrUnknown routes unknown token to default", () => {
946
981
  const root = testProgram({
947
982
  key: "app",
@@ -991,6 +1026,7 @@ test("nested fallback MissingOnly errors on unknown subcommand", () => {
991
1026
  expect(pr.errorMsg).toContain("Unknown subcommand");
992
1027
  });
993
1028
 
1029
+ /** CliValidateProgram rejects invalid nested fallbackCommand. */
994
1030
  test("cliValidateProgram rejects invalid nested fallbackCommand", () => {
995
1031
  const root = testProgram({
996
1032
  key: "app",
@@ -1106,6 +1142,7 @@ test("mcpToolCallToArgv empty array varargs errors when required", () => {
1106
1142
 
1107
1143
  // ── Skills ────────────────────────────────────────────────────────────────────
1108
1144
 
1145
+ /** Configure config on non-root node is rejected. */
1109
1146
  test("configure config on non-root node is rejected", () => {
1110
1147
  const root = {
1111
1148
  key: "app",
@@ -1134,6 +1171,7 @@ test("configure.prefix is rejected", () => {
1134
1171
  expect(() => cliValidateProgram(root)).toThrow(/configure\.prefix removed/);
1135
1172
  });
1136
1173
 
1174
+ /** Tests that generateSkillBundle includes frontmatter and compact command index. */
1137
1175
  test("generateSkillBundle includes frontmatter and compact command index", () => {
1138
1176
  const bundle = generateSkillBundle(nestedMcpFixture, "cursor");
1139
1177
  expect(bundle.dirName).toBe("nested_ts");
@@ -1154,6 +1192,7 @@ test("generateSkillBundle includes frontmatter and compact command index", () =>
1154
1192
  expect(bundle.referenceMd).not.toContain("```json");
1155
1193
  });
1156
1194
 
1195
+ /** Tests that generatePluginSkillBundle is MCP routing stub without shell catalog. */
1157
1196
  test("generatePluginSkillBundle is MCP routing stub without shell catalog", () => {
1158
1197
  const bundle = generatePluginSkillBundle(nestedMcpFixture);
1159
1198
  expect(bundle.dirName).toBe("nested_ts");
@@ -1168,6 +1207,7 @@ test("generatePluginSkillBundle is MCP routing stub without shell catalog", () =
1168
1207
  expect(bundle.skillMd).not.toContain("## Commands");
1169
1208
  });
1170
1209
 
1210
+ /** CliSkillInstall writes project Cursor skill files. */
1171
1211
  test("cliSkillInstall writes project Cursor skill files", () => {
1172
1212
  const cwd = mkdtempSync(join(tmpdir(), "argsbarg-skill-"));
1173
1213
  const prev = process.cwd();
@@ -1192,6 +1232,7 @@ test("cliSkillInstall writes project Cursor skill files", () => {
1192
1232
  }
1193
1233
  });
1194
1234
 
1235
+ /** CliSkillInstall global uses HOME skills directory. */
1195
1236
  test("cliSkillInstall global uses HOME skills directory", () => {
1196
1237
  const home = mkdtempSync(join(tmpdir(), "argsbarg-home-"));
1197
1238
  const prevHome = process.env.HOME;
@@ -1210,6 +1251,7 @@ test("cliSkillInstall global uses HOME skills directory", () => {
1210
1251
  }
1211
1252
  });
1212
1253
 
1254
+ /** CliSkillInstall rimraf overwrites existing directory. */
1213
1255
  test("cliSkillInstall rimraf overwrites existing directory", () => {
1214
1256
  const cwd = mkdtempSync(join(tmpdir(), "argsbarg-skill-dup-"));
1215
1257
  const prev = process.cwd();
@@ -1228,6 +1270,7 @@ test("cliSkillInstall rimraf overwrites existing directory", () => {
1228
1270
  }
1229
1271
  });
1230
1272
 
1273
+ /** CliSkillInstall claude target uses .claude/skills. */
1231
1274
  test("cliSkillInstall claude target uses .claude/skills", () => {
1232
1275
  const cwd = mkdtempSync(join(tmpdir(), "argsbarg-skill-claude-"));
1233
1276
  const prev = process.cwd();