stitchkit 0.90.3 → 0.90.5

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 (61) hide show
  1. package/CHANGELOG.md +142 -0
  2. package/dist/agent-runtime-coding-tools.js +4 -4
  3. package/dist/agent-runtime-harness.js +6 -6
  4. package/dist/agent-runtime-sandbox.js +4 -4
  5. package/dist/agent-runtime.js +9 -9
  6. package/dist/cli.d.ts +14 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +402 -11
  9. package/dist/{index-2hrfpw2c.js → index-1bnkzq95.js} +2 -2
  10. package/dist/{index-j7q0xj6d.js → index-3yqgj323.js} +3 -3
  11. package/dist/{index-gbqjt8jz.js → index-83fafqw8.js} +3 -3
  12. package/dist/{index-44ht2790.js → index-8pjqv3zh.js} +6 -6
  13. package/dist/{index-kc6h6hg0.js → index-8z9we758.js} +1 -1
  14. package/dist/{index-r159gjwy.js → index-fenaekmk.js} +94 -8
  15. package/dist/{index-1923shw9.js → index-fqg5mfk7.js} +339 -19
  16. package/dist/{index-f475yj00.js → index-s208wab5.js} +1 -1
  17. package/dist/{index-79hb1wyh.js → index-tgh3ksfh.js} +5 -5
  18. package/dist/{index-wb15909q.js → index-zsdgd1tz.js} +3 -3
  19. package/dist/index.js +7 -7
  20. package/dist/node.js +2 -2
  21. package/dist/observability/index.js +1 -1
  22. package/dist/remote.js +1 -1
  23. package/dist/server/index.js +6 -6
  24. package/dist/testing.js +3 -3
  25. package/dist/tool-invoker.js +6 -6
  26. package/dist/tools/cli-args.d.ts +30 -6
  27. package/dist/tools/cli-args.d.ts.map +1 -1
  28. package/dist/tools/cli-installer.d.ts +34 -0
  29. package/dist/tools/cli-installer.d.ts.map +1 -0
  30. package/dist/tools/cli-manifest.d.ts +83 -0
  31. package/dist/tools/cli-manifest.d.ts.map +1 -0
  32. package/dist/tools/cli-profile.d.ts +40 -0
  33. package/dist/tools/cli-profile.d.ts.map +1 -0
  34. package/dist/tools/cli-update.d.ts +64 -0
  35. package/dist/tools/cli-update.d.ts.map +1 -0
  36. package/dist/tools/cli-view.d.ts +12 -0
  37. package/dist/tools/cli-view.d.ts.map +1 -0
  38. package/dist/tools/cli.d.ts.map +1 -1
  39. package/dist/tools/connections/index.d.ts +2 -1
  40. package/dist/tools/connections/index.d.ts.map +1 -1
  41. package/dist/tools/connections/index.js +74 -14
  42. package/dist/tools/connections/mcp-envelope.d.ts +44 -0
  43. package/dist/tools/connections/mcp-envelope.d.ts.map +1 -0
  44. package/dist/tools/connections/mcp.d.ts +2 -1
  45. package/dist/tools/connections/mcp.d.ts.map +1 -1
  46. package/dist/tools/connections/mount.d.ts.map +1 -1
  47. package/dist/tools/connections/openapi.d.ts +2 -1
  48. package/dist/tools/connections/openapi.d.ts.map +1 -1
  49. package/dist/tools/connections/runtime.d.ts +17 -0
  50. package/dist/tools/connections/runtime.d.ts.map +1 -1
  51. package/dist/tools/connections/types.d.ts +18 -1
  52. package/dist/tools/connections/types.d.ts.map +1 -1
  53. package/dist/tools/json-schema-dialect.d.ts +17 -0
  54. package/dist/tools/json-schema-dialect.d.ts.map +1 -0
  55. package/dist/tools/presentation.d.ts +8 -1
  56. package/dist/tools/presentation.d.ts.map +1 -1
  57. package/dist/tools.js +13 -13
  58. package/dist/tracking.js +1 -1
  59. package/llms-full.txt +273 -3
  60. package/package.json +1 -1
  61. package/dist/{index-db51n3xr.js → index-ra6txecz.js} +3 -3
@@ -3,15 +3,15 @@ import {
3
3
  } from "./index-sbdmyz75.js";
4
4
  import {
5
5
  collectToolSurface
6
- } from "./index-wb15909q.js";
6
+ } from "./index-zsdgd1tz.js";
7
7
  import {
8
8
  createToolRunner,
9
9
  formatToolError
10
- } from "./index-2hrfpw2c.js";
10
+ } from "./index-1bnkzq95.js";
11
11
  import {
12
12
  toolErrorFromResult,
13
13
  toolResultFromError
14
- } from "./index-44ht2790.js";
14
+ } from "./index-8pjqv3zh.js";
15
15
  import {
16
16
  formatZodError,
17
17
  validateDeclaredOutput
@@ -19,18 +19,18 @@ import {
19
19
  import {
20
20
  coerceJsonArgs
21
21
  } from "./index-7zbps32p.js";
22
- import {
23
- isUnsafeKey,
24
- safeJsonParse
25
- } from "./index-kzfs85xp.js";
26
22
  import {
27
23
  assertUniqueToolName,
28
24
  buildToolPresentationSchema,
29
25
  objectShapeKeys
30
- } from "./index-r159gjwy.js";
26
+ } from "./index-fenaekmk.js";
31
27
  import {
32
28
  jsonSchemaFields
33
29
  } from "./index-cby4ar3v.js";
30
+ import {
31
+ isUnsafeKey,
32
+ safeJsonParse
33
+ } from "./index-kzfs85xp.js";
34
34
  import {
35
35
  isRecord
36
36
  } from "./index-77fekveh.js";
@@ -38,8 +38,9 @@ import {
38
38
  // src/tools/cli-args.ts
39
39
  import { z } from "zod";
40
40
  var NUMERIC_VALUE = /^-(\d+\.?\d*|\.\d+)$/;
41
- var BOOL_OPTIONS = new Set(["json", "wait", "quiet", "dry-run", "help"]);
42
- var VALUE_OPTIONS = new Set(["wait-timeout", "output-dir"]);
41
+ var BOOL_OPTIONS = new Set(["json", "wait", "quiet", "dry-run", "help", "ascending"]);
42
+ var VIEW_OPTIONS = new Set(["count-by", "sum", "by", "top", "table", "sort"]);
43
+ var VALUE_OPTIONS = new Set(["wait-timeout", "output-dir", ...VIEW_OPTIONS]);
43
44
  var RESERVED_CLI_OPTIONS = new Set([...BOOL_OPTIONS, ...VALUE_OPTIONS]);
44
45
  function classifyLongOptionToken(token) {
45
46
  if (!token.startsWith("--") || token === "--")
@@ -53,10 +54,30 @@ function classifyLongOptionToken(token) {
53
54
  globalKind: BOOL_OPTIONS.has(name) ? "boolean" : VALUE_OPTIONS.has(name) ? "value" : undefined
54
55
  };
55
56
  }
57
+ var HELP_TOKENS = new Set(["--help", "-h", "help"]);
58
+ function helpFilterFrom(token, rest) {
59
+ if (token?.startsWith("--help=")) {
60
+ const value = token.slice("--help=".length).trim();
61
+ if (value.length === 0 || isReservedBoolWord(value))
62
+ return;
63
+ return value;
64
+ }
65
+ if (token === undefined || !HELP_TOKENS.has(token))
66
+ return;
67
+ const next = rest[0];
68
+ return next !== undefined && !next.startsWith("-") ? next : undefined;
69
+ }
56
70
  function routeCliArgv(argv, defaultCommand) {
57
71
  if (defaultCommand === undefined) {
58
72
  const [command, ...commandArgv] = argv;
59
- return { command, commandArgv, topLevelHelp: false, version: false };
73
+ const helpFilter = helpFilterFrom(command, commandArgv);
74
+ return {
75
+ command,
76
+ commandArgv,
77
+ topLevelHelp: false,
78
+ version: false,
79
+ ...helpFilter !== undefined && { helpFilter }
80
+ };
60
81
  }
61
82
  const globals = [];
62
83
  let index = 0;
@@ -72,8 +93,15 @@ function routeCliArgv(argv, defaultCommand) {
72
93
  error: 'A command is required before "--"'
73
94
  };
74
95
  }
75
- if (token === "--help" || token === "-h") {
76
- return { commandArgv: [], topLevelHelp: true, version: false };
96
+ const inlineHelpFilter = token.startsWith("--help=") && !isReservedBoolWord(token.slice("--help=".length));
97
+ if (token === "--help" || token === "-h" || inlineHelpFilter) {
98
+ const helpFilter = helpFilterFrom(token, argv.slice(index + 1));
99
+ return {
100
+ commandArgv: [],
101
+ topLevelHelp: true,
102
+ version: false,
103
+ ...helpFilter !== undefined && { helpFilter }
104
+ };
77
105
  }
78
106
  if (token === "--version" || token === "version") {
79
107
  return { commandArgv: [], topLevelHelp: false, version: true };
@@ -113,7 +141,13 @@ function routeCliArgv(argv, defaultCommand) {
113
141
  if (!option.inline) {
114
142
  const value = argv[index + 1];
115
143
  if (value === "--help" || value === "-h") {
116
- return { commandArgv: [], topLevelHelp: true, version: false };
144
+ const helpFilter = helpFilterFrom(value, argv.slice(index + 2));
145
+ return {
146
+ commandArgv: [],
147
+ topLevelHelp: true,
148
+ version: false,
149
+ ...helpFilter !== undefined && { helpFilter }
150
+ };
117
151
  }
118
152
  if (value === "--version" || value === "version") {
119
153
  return { commandArgv: [], topLevelHelp: false, version: true };
@@ -216,6 +250,10 @@ function describeSchemaFields(schema) {
216
250
  }
217
251
  var TRUE_WORDS = new Set(["true", "1", "yes", "on"]);
218
252
  var FALSE_WORDS = new Set(["false", "0", "no", "off"]);
253
+ function isReservedBoolWord(value) {
254
+ const word = value.toLowerCase();
255
+ return TRUE_WORDS.has(word) || FALSE_WORDS.has(word);
256
+ }
219
257
  function parseReservedBool(name, value) {
220
258
  const v = value.toLowerCase();
221
259
  if (TRUE_WORDS.has(v))
@@ -315,6 +353,8 @@ function parseCliArgs(argv, schema, config = {}) {
315
353
  }
316
354
  const flags = new Map;
317
355
  const boolFlags = new Map;
356
+ const viewFlags = new Map;
357
+ let ascending = false;
318
358
  const positionals = [];
319
359
  const pushFlag = (name, value) => {
320
360
  const existing = flags.get(name);
@@ -382,6 +422,8 @@ function parseCliArgs(argv, schema, config = {}) {
382
422
  options.wait = enabled;
383
423
  else if (name === "quiet")
384
424
  options.quiet = enabled;
425
+ else if (name === "ascending")
426
+ ascending = enabled;
385
427
  else
386
428
  options.help = enabled;
387
429
  continue;
@@ -400,6 +442,10 @@ function parseCliArgs(argv, schema, config = {}) {
400
442
  throw new CliArgumentError("--wait-timeout must be a positive number");
401
443
  }
402
444
  options.waitTimeout = timeout;
445
+ } else if (VIEW_OPTIONS.has(name)) {
446
+ if (viewFlags.has(name))
447
+ throw new CliArgumentError(`--${name} was given twice`);
448
+ viewFlags.set(name, value);
403
449
  } else {
404
450
  options.outputDir = value;
405
451
  }
@@ -433,6 +479,9 @@ function parseCliArgs(argv, schema, config = {}) {
433
479
  }
434
480
  pushFlag(name, value);
435
481
  }
482
+ const view = resolveCliView(viewFlags, ascending);
483
+ if (view)
484
+ options.view = view;
436
485
  const toolArgs = {};
437
486
  const fillable = config.positionals === undefined ? [...fields.entries()].filter(([, info]) => info.kind !== "boolean").map(([name]) => name) : [...config.positionals];
438
487
  const variadicTail = config.positionals !== undefined && fields.get(fillable[fillable.length - 1] ?? "")?.kind === "array" ? fillable[fillable.length - 1] : undefined;
@@ -536,6 +585,85 @@ function extractCliGlobalOptions(argv, schema) {
536
585
  }
537
586
  return { argv: rest, globals: parsed.data };
538
587
  }
588
+ function resolveCliView(flags, ascending) {
589
+ if (flags.size === 0) {
590
+ if (ascending) {
591
+ throw new CliArgumentError("--ascending orders a record view; pass --sort with it");
592
+ }
593
+ return;
594
+ }
595
+ const countBy = flags.get("count-by");
596
+ const sum = flags.get("sum");
597
+ const table = flags.get("table");
598
+ const by = flags.get("by");
599
+ const rawTop = flags.get("top");
600
+ const named = [
601
+ ["--count-by", countBy],
602
+ ["--sum", sum]
603
+ ].filter(([, value]) => value !== undefined);
604
+ if (named.length > 1) {
605
+ throw new CliArgumentError(`${named.map(([flag]) => flag).join(" and ")} ask for different shapes — pass one`);
606
+ }
607
+ let top;
608
+ if (rawTop !== undefined) {
609
+ top = Number(rawTop);
610
+ if (!Number.isInteger(top) || top <= 0) {
611
+ throw new CliArgumentError("--top must be a positive whole number");
612
+ }
613
+ }
614
+ const sort = flags.get("sort");
615
+ if (table !== undefined || sort !== undefined) {
616
+ if (countBy !== undefined || sum !== undefined) {
617
+ throw new CliArgumentError(`${table !== undefined ? "--table" : "--sort"} lists records; --count-by and --sum aggregate them — pass one`);
618
+ }
619
+ if (by !== undefined) {
620
+ throw new CliArgumentError("--by groups a view; a record view orders with --sort");
621
+ }
622
+ if (top !== undefined && sort === undefined) {
623
+ throw new CliArgumentError("--top needs --sort here: unordered records have no n largest");
624
+ }
625
+ let fields;
626
+ if (table !== undefined) {
627
+ fields = table.split(",").map((field) => field.trim()).filter(Boolean);
628
+ if (fields.length === 0)
629
+ throw new CliArgumentError("--table needs at least one field");
630
+ }
631
+ return {
632
+ kind: "records",
633
+ ...sort !== undefined && { sort },
634
+ ...ascending && { ascending },
635
+ ...top !== undefined && { top },
636
+ ...fields && { table: fields }
637
+ };
638
+ }
639
+ if (ascending) {
640
+ throw new CliArgumentError("--ascending orders a record view; pass --sort with it");
641
+ }
642
+ if (sum !== undefined) {
643
+ if (top !== undefined && by === undefined) {
644
+ throw new CliArgumentError("--top needs --by: a single sum has nothing to rank");
645
+ }
646
+ return {
647
+ kind: "sum",
648
+ field: sum,
649
+ ...by !== undefined && { by },
650
+ ...top !== undefined && { top }
651
+ };
652
+ }
653
+ if (countBy !== undefined) {
654
+ if (by !== undefined) {
655
+ throw new CliArgumentError("--count-by already names the grouping field; drop --by");
656
+ }
657
+ return { kind: "count", field: countBy, ...top !== undefined && { top } };
658
+ }
659
+ if (by !== undefined) {
660
+ if (top === undefined) {
661
+ throw new CliArgumentError("--by groups a view; pass --count-by, --sum or --top with it");
662
+ }
663
+ return { kind: "count", field: by, top };
664
+ }
665
+ throw new CliArgumentError("--top needs --sort, --by, --count-by or --sum to rank");
666
+ }
539
667
 
540
668
  // src/tools/cli-command.ts
541
669
  function defineCliCommand(definition) {
@@ -633,6 +761,153 @@ function emitResult(result, writers, opts) {
633
761
  return codes[result.code] ?? 1;
634
762
  }
635
763
 
764
+ // src/tools/cli-view.ts
765
+ var ABSENT = "(absent)";
766
+ function selectRecords(data) {
767
+ if (Array.isArray(data))
768
+ return data;
769
+ if (isRecord(data)) {
770
+ const arrays = Object.entries(data).filter(([, value]) => Array.isArray(value));
771
+ const only = arrays[0];
772
+ if (arrays.length === 1 && only && Array.isArray(only[1]))
773
+ return only[1];
774
+ if (arrays.length > 1) {
775
+ throw new CliArgumentError(`an aggregate needs one collection, but the result carries several: ${arrays.map(([key]) => key).join(", ")} — name the shape you want with jq instead`);
776
+ }
777
+ }
778
+ throw new CliArgumentError("an aggregate needs a collection; this result is not one");
779
+ }
780
+ function readField(record, path) {
781
+ let current = record;
782
+ for (const segment of path) {
783
+ if (!isRecord(current))
784
+ return;
785
+ current = current[segment];
786
+ }
787
+ return current;
788
+ }
789
+ function fieldPath(field) {
790
+ const path = field.split(".");
791
+ if (path.some((segment) => segment.length === 0 || isUnsafeKey(segment))) {
792
+ throw new CliArgumentError(`"${field}" is not a readable field path`);
793
+ }
794
+ return path;
795
+ }
796
+ function availableFields(records) {
797
+ const keys = new Set;
798
+ for (const record of records) {
799
+ if (isRecord(record))
800
+ for (const key of Object.keys(record))
801
+ keys.add(key);
802
+ }
803
+ return [...keys].sort();
804
+ }
805
+ function assertFieldPresent(records, field) {
806
+ const path = fieldPath(field);
807
+ const present = records.some((record) => readField(record, path) !== undefined);
808
+ if (!present) {
809
+ const available = availableFields(records);
810
+ throw new CliArgumentError(`no record carries the field "${field}"${available.length > 0 ? ` — available: ${available.join(", ")}` : ""}`);
811
+ }
812
+ return path;
813
+ }
814
+ function groupKey(value) {
815
+ if (value === undefined)
816
+ return ABSENT;
817
+ if (value === null)
818
+ return "null";
819
+ if (typeof value === "object")
820
+ return JSON.stringify(value);
821
+ return String(value);
822
+ }
823
+ function ordered(totals, top) {
824
+ const entries = [...totals].sort(([leftKey, left], [rightKey, right]) => right === left ? leftKey.localeCompare(rightKey) : right - left);
825
+ const sliced = top === undefined ? entries : entries.slice(0, top);
826
+ return Object.fromEntries(sliced);
827
+ }
828
+ function numericValue(value, field) {
829
+ if (value === undefined || value === null)
830
+ return;
831
+ if (typeof value === "number" && Number.isFinite(value))
832
+ return value;
833
+ if (typeof value === "bigint")
834
+ return Number(value);
835
+ throw new CliArgumentError(`--sum ${field}: "${groupKey(value)}" is not a number`);
836
+ }
837
+ function renderTable(records, fields) {
838
+ const paths = fields.map((field) => assertFieldPresent(records, field));
839
+ const cell = (value) => {
840
+ if (value === undefined)
841
+ return "";
842
+ if (value === null)
843
+ return "null";
844
+ if (typeof value === "object")
845
+ return JSON.stringify(value);
846
+ return String(value);
847
+ };
848
+ const rows = records.map((record) => paths.map((path) => cell(readField(record, path))));
849
+ const widths = fields.map((field, column) => Math.max(field.length, ...rows.map((row) => row[column]?.length ?? 0)));
850
+ const line = (cells) => cells.map((value, column) => value.padEnd(widths[column] ?? value.length)).join(" ").trimEnd();
851
+ return `${[line(fields), line(widths.map((width) => "-".repeat(width))), ...rows.map(line)].join(`
852
+ `)}
853
+ `;
854
+ }
855
+ function compareFieldValues(left, right) {
856
+ if (left === undefined || left === null)
857
+ return right === undefined || right === null ? 0 : 1;
858
+ if (right === undefined || right === null)
859
+ return -1;
860
+ if (typeof left === "number" && typeof right === "number")
861
+ return left - right;
862
+ if (typeof left === "bigint" || typeof right === "bigint") {
863
+ return Number(left) - Number(right);
864
+ }
865
+ return groupKey(left).localeCompare(groupKey(right));
866
+ }
867
+ function renderRecords(records, view) {
868
+ let selected = [...records];
869
+ if (view.sort !== undefined) {
870
+ const path = assertFieldPresent(records, view.sort);
871
+ const direction = view.ascending ? 1 : -1;
872
+ selected.sort((left, right) => {
873
+ const order = compareFieldValues(readField(left, path), readField(right, path));
874
+ const absent = readField(left, path) === undefined || readField(right, path) === undefined;
875
+ return absent ? order : order * direction;
876
+ });
877
+ }
878
+ if (view.top !== undefined)
879
+ selected = selected.slice(0, view.top);
880
+ return view.table ? { kind: "text", text: renderTable(selected, view.table) } : { kind: "json", data: selected };
881
+ }
882
+ function renderCliView(data, view) {
883
+ const records = selectRecords(data);
884
+ if (view.kind === "records")
885
+ return renderRecords(records, view);
886
+ if (view.kind === "count") {
887
+ const path2 = assertFieldPresent(records, view.field);
888
+ const totals2 = new Map;
889
+ for (const record of records) {
890
+ const key = groupKey(readField(record, path2));
891
+ totals2.set(key, (totals2.get(key) ?? 0) + 1);
892
+ }
893
+ return { kind: "json", data: ordered(totals2, view.top) };
894
+ }
895
+ const path = assertFieldPresent(records, view.field);
896
+ if (view.by === undefined) {
897
+ let total = 0;
898
+ for (const record of records)
899
+ total += numericValue(readField(record, path), view.field) ?? 0;
900
+ return { kind: "json", data: total };
901
+ }
902
+ const byPath = assertFieldPresent(records, view.by);
903
+ const totals = new Map;
904
+ for (const record of records) {
905
+ const key = groupKey(readField(record, byPath));
906
+ totals.set(key, (totals.get(key) ?? 0) + (numericValue(readField(record, path), view.field) ?? 0));
907
+ }
908
+ return { kind: "json", data: ordered(totals, view.top) };
909
+ }
910
+
636
911
  // src/tools/wait-core.ts
637
912
  var DEFAULT_BACKOFF = [2, 3, 5, 5, 8, 10];
638
913
  var DEFAULT_TIMEOUT = 600;
@@ -1181,7 +1456,14 @@ var GLOBAL_OPTIONS = [
1181
1456
  ["--output-dir <dir>", "Download result media into a directory"],
1182
1457
  ["--quiet", "Suppress non-essential stderr output"],
1183
1458
  ["--dry-run", "Print the resolved call without executing it"],
1184
- ["--help, -h", "Show help for a command"]
1459
+ ["--help, -h", "Show help for a command"],
1460
+ ["--help <text>", "List only the commands matching a substring"],
1461
+ ["--count-by <field>", "Count records per distinct value of a field"],
1462
+ ["--sum <field>", "Total a numeric field, optionally grouped by --by"],
1463
+ ["--sort <field>", "Order the records by a field, largest first"],
1464
+ ["--ascending", "Flip --sort to smallest first"],
1465
+ ["--top <n>", "Keep the n leading entries of the view asked for"],
1466
+ ["--table <a,b>", "Render the named fields as an aligned table"]
1185
1467
  ];
1186
1468
  async function readPipedStdin() {
1187
1469
  if (process.stdin.isTTY)
@@ -1261,14 +1543,19 @@ function applicationOptionLines(fields) {
1261
1543
  ...fields.map((field) => ` ${padRight(labels.get(field.name) ?? `--${field.name}`, width)} ${field.description ?? ""}`.trimEnd())
1262
1544
  ];
1263
1545
  }
1546
+ function filterCommands(commands, filter) {
1547
+ const needle = filter.toLowerCase();
1548
+ return new Map([...commands].filter(([command, descriptor]) => command.toLowerCase().includes(needle) || descriptor.description.toLowerCase().includes(needle)));
1549
+ }
1264
1550
  function renderTopHelp(input) {
1265
- const { name, version, commands, defaultCommand } = input;
1551
+ const { name, version, defaultCommand } = input;
1552
+ const commands = input.filter === undefined ? input.commands : filterCommands(input.commands, input.filter);
1266
1553
  const lines = [
1267
1554
  `${name} ${version}`,
1268
1555
  "",
1269
1556
  `Usage: ${name} ${defaultCommand ? "[command]" : "<command>"} [args] [--flags]`,
1270
1557
  "",
1271
- "Commands:"
1558
+ input.filter === undefined ? "Commands:" : `Commands matching "${input.filter}" (${commands.size} of ${input.commands.size}):`
1272
1559
  ];
1273
1560
  const width = Math.max(0, ...[...commands.keys()].map((key) => key.length));
1274
1561
  for (const [command, descriptor] of commands) {
@@ -1277,6 +1564,12 @@ function renderTopHelp(input) {
1277
1564
  if (input.unavailable !== undefined) {
1278
1565
  lines.push("", `Managed commands are unavailable: ${input.unavailable}`);
1279
1566
  }
1567
+ if (input.filter !== undefined) {
1568
+ lines.push("", `Run "${name} <command> --help" for command-specific flags.`);
1569
+ return `${lines.join(`
1570
+ `)}
1571
+ `;
1572
+ }
1280
1573
  lines.push("", "Global options:");
1281
1574
  const optWidth = Math.max(...GLOBAL_OPTIONS.map(([flag]) => flag.length));
1282
1575
  for (const [flag, desc] of GLOBAL_OPTIONS)
@@ -1603,15 +1896,25 @@ async function createCli(config) {
1603
1896
  assertCliPoliciesResolved(help, config);
1604
1897
  return { resolved: true, auth, help, tools };
1605
1898
  };
1606
- const topLevelHelp = route.topLevelHelp || command === undefined || command === "help" || command === "--help" || command === "-h";
1899
+ const topLevelHelp = route.topLevelHelp || command === undefined || command === "help" || command === "--help" || command === "-h" || command.startsWith("--help=") && !isReservedBoolWord(command.slice("--help=".length));
1607
1900
  const managed = await buildManagedSurface(!topLevelHelp && !helpRequested);
1608
1901
  if (topLevelHelp) {
1902
+ const helpFilter = route.helpFilter ?? (command !== undefined ? commandArgv[0] : undefined);
1903
+ const filter = helpFilter !== undefined && !helpFilter.startsWith("-") ? helpFilter : undefined;
1904
+ if (filter !== undefined && filterCommands(managed.help, filter).size === 0) {
1905
+ stderr(`no command matches "${filter}" (${managed.help.size} available)
1906
+ ` + (managed.resolved ? "" : `Managed commands are unavailable: ${managed.reason}
1907
+ `));
1908
+ const codes = { ...DEFAULT_EXIT_CODES, ...config.exitCodes };
1909
+ return exit(codes.NOT_FOUND ?? 4);
1910
+ }
1609
1911
  stdout(renderTopHelp({
1610
1912
  name: config.name,
1611
1913
  version: config.version,
1612
1914
  commands: managed.help,
1613
1915
  defaultCommand: config.defaultCommand,
1614
1916
  applicationOptions,
1917
+ ...filter !== undefined && { filter },
1615
1918
  ...managed.resolved ? {} : { unavailable: managed.reason }
1616
1919
  }));
1617
1920
  return exit(0);
@@ -1708,6 +2011,23 @@ async function createCli(config) {
1708
2011
  if (options.outputDir && result.ok && config.download) {
1709
2012
  downloadsOk = await downloadResults(config.download(result.data), options.outputDir, stderr, options.quiet, config.allowPrivateDownloadHosts ?? false, config.maxDownloadBytes ?? DEFAULT_DOWNLOAD_MAX_BYTES, config.downloadTimeoutMs);
1710
2013
  }
2014
+ if (options.view && result.ok) {
2015
+ let viewed;
2016
+ try {
2017
+ viewed = renderCliView(result.data, options.view);
2018
+ } catch (error) {
2019
+ if (!(error instanceof CliArgumentError))
2020
+ throw error;
2021
+ stderr(`${error.message}
2022
+ `);
2023
+ return exit(2);
2024
+ }
2025
+ if (viewed.kind === "text") {
2026
+ stdout(viewed.text);
2027
+ return exit(downloadsOk ? 0 : 1);
2028
+ }
2029
+ result = { ...result, data: viewed.data };
2030
+ }
1711
2031
  const exitCode = emitResult(result, { stdout, stderr }, {
1712
2032
  json: options.json,
1713
2033
  toolName: command,
@@ -1717,4 +2037,4 @@ async function createCli(config) {
1717
2037
  return exit(downloadsOk ? exitCode : 1);
1718
2038
  }
1719
2039
 
1720
- export { WaitTimeoutError, runWaitOperation, fetchGuarded, fetchPinnedDocument, readCapped, parseCliArgs, defineCliCommand, DEFAULT_EXIT_CODES, emitResult, pollUntilDone, createCli };
2040
+ export { WaitTimeoutError, runWaitOperation, fetchGuarded, fetchPinnedDocument, readCapped, routeCliArgv, CliArgumentError, parseCliArgs, extractCliGlobalOptions, defineCliCommand, DEFAULT_EXIT_CODES, emitResult, renderCliView, pollUntilDone, createCli };
@@ -36,7 +36,7 @@ import {
36
36
  import {
37
37
  ToolExecutionControlError,
38
38
  isToolExecutionControlError
39
- } from "./index-44ht2790.js";
39
+ } from "./index-8pjqv3zh.js";
40
40
  import {
41
41
  isRecord,
42
42
  transportResult
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  collectTools,
3
3
  createToolRunner
4
- } from "./index-2hrfpw2c.js";
4
+ } from "./index-1bnkzq95.js";
5
5
  import {
6
6
  toolErrorFromResult
7
- } from "./index-44ht2790.js";
7
+ } from "./index-8pjqv3zh.js";
8
+ import {
9
+ assertUniqueToolName
10
+ } from "./index-fenaekmk.js";
8
11
  import {
9
12
  AppError
10
13
  } from "./index-scs3f1eg.js";
11
- import {
12
- assertUniqueToolName
13
- } from "./index-r159gjwy.js";
14
14
 
15
15
  // src/tools/invoker.ts
16
16
  function createToolInvoker(services, config) {
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  contractToolMountable
3
- } from "./index-2hrfpw2c.js";
3
+ } from "./index-1bnkzq95.js";
4
4
  import {
5
5
  runtimeToolMountable
6
- } from "./index-kc6h6hg0.js";
6
+ } from "./index-8z9we758.js";
7
7
  import {
8
8
  projectToolSurface
9
- } from "./index-r159gjwy.js";
9
+ } from "./index-fenaekmk.js";
10
10
 
11
11
  // src/tools/surface.ts
12
12
  function collectToolSurface({
package/dist/index.js CHANGED
@@ -65,6 +65,13 @@ import {
65
65
  ManagedFilePathSchema,
66
66
  ManagedFileRefSchema
67
67
  } from "./index-6k1937bx.js";
68
+ import {
69
+ childSpan,
70
+ createTraceContext,
71
+ formatTraceparent,
72
+ parseTraceparent,
73
+ randomHex
74
+ } from "./index-zcgf3gqf.js";
68
75
  import {
69
76
  AppError,
70
77
  STITCH_ERROR_STATUS,
@@ -77,13 +84,6 @@ import {
77
84
  rateLimited,
78
85
  unauthorized
79
86
  } from "./index-scs3f1eg.js";
80
- import {
81
- childSpan,
82
- createTraceContext,
83
- formatTraceparent,
84
- parseTraceparent,
85
- randomHex
86
- } from "./index-zcgf3gqf.js";
87
87
  import"./index-kzfs85xp.js";
88
88
  import"./index-77fekveh.js";
89
89
  // src/retained.ts
package/dist/node.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  createHandler,
6
6
  createSocketIOServer,
7
7
  createUnixClientTransport
8
- } from "./index-db51n3xr.js";
8
+ } from "./index-ra6txecz.js";
9
9
  import"./index-y91ry9h2.js";
10
10
  import {
11
11
  ShutdownOptionsSchema,
@@ -30,6 +30,7 @@ import"./index-f9mb610r.js";
30
30
  import"./index-2hryh65w.js";
31
31
  import"./index-kazec06k.js";
32
32
  import"./index-6k1937bx.js";
33
+ import"./index-zcgf3gqf.js";
33
34
  import {
34
35
  AppError,
35
36
  appError,
@@ -40,7 +41,6 @@ import {
40
41
  rateLimited,
41
42
  unauthorized
42
43
  } from "./index-scs3f1eg.js";
43
- import"./index-zcgf3gqf.js";
44
44
  import"./index-kzfs85xp.js";
45
45
  import"./index-77fekveh.js";
46
46
  // src/server/node.ts
@@ -30,7 +30,6 @@ import {
30
30
  } from "../index-2hryh65w.js";
31
31
  import"../index-kazec06k.js";
32
32
  import"../index-6k1937bx.js";
33
- import"../index-scs3f1eg.js";
34
33
  import {
35
34
  childSpan,
36
35
  createTraceContext,
@@ -39,6 +38,7 @@ import {
39
38
  resolvePropagationContext,
40
39
  resolveTraceContext
41
40
  } from "../index-zcgf3gqf.js";
41
+ import"../index-scs3f1eg.js";
42
42
  import"../index-kzfs85xp.js";
43
43
  import {
44
44
  isRecord
package/dist/remote.js CHANGED
@@ -11,10 +11,10 @@ import {
11
11
  resolveRouteParamsSchema
12
12
  } from "./index-kazec06k.js";
13
13
  import"./index-6k1937bx.js";
14
+ import"./index-zcgf3gqf.js";
14
15
  import {
15
16
  AppError
16
17
  } from "./index-scs3f1eg.js";
17
- import"./index-zcgf3gqf.js";
18
18
  import"./index-kzfs85xp.js";
19
19
  import {
20
20
  isRecord
@@ -13,7 +13,7 @@ import {
13
13
  sseRoute,
14
14
  streamingRoute,
15
15
  webSocketLane
16
- } from "../index-db51n3xr.js";
16
+ } from "../index-ra6txecz.js";
17
17
  import"../index-y91ry9h2.js";
18
18
  import {
19
19
  withDeadline
@@ -87,6 +87,11 @@ import {
87
87
  parseTrailingWildcard
88
88
  } from "../index-kazec06k.js";
89
89
  import"../index-6k1937bx.js";
90
+ import"../index-zcgf3gqf.js";
91
+ import {
92
+ jsonSchemaFields,
93
+ toJsonSchema
94
+ } from "../index-cby4ar3v.js";
90
95
  import {
91
96
  AppError,
92
97
  STITCH_ERROR_STATUS,
@@ -99,12 +104,7 @@ import {
99
104
  rateLimited,
100
105
  unauthorized
101
106
  } from "../index-scs3f1eg.js";
102
- import"../index-zcgf3gqf.js";
103
107
  import"../index-kzfs85xp.js";
104
- import {
105
- jsonSchemaFields,
106
- toJsonSchema
107
- } from "../index-cby4ar3v.js";
108
108
  import {
109
109
  isRecord
110
110
  } from "../index-77fekveh.js";