terminal-pilot 0.0.33 → 0.0.34

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/dist/cli.js +595 -144
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/close-session.js +10 -0
  4. package/dist/commands/close-session.js.map +3 -3
  5. package/dist/commands/create-session.js +10 -0
  6. package/dist/commands/create-session.js.map +3 -3
  7. package/dist/commands/fill.js +10 -0
  8. package/dist/commands/fill.js.map +3 -3
  9. package/dist/commands/get-session.js +10 -0
  10. package/dist/commands/get-session.js.map +3 -3
  11. package/dist/commands/index.js +13 -3
  12. package/dist/commands/index.js.map +3 -3
  13. package/dist/commands/install.js +13 -3
  14. package/dist/commands/install.js.map +3 -3
  15. package/dist/commands/installer.js +13 -3
  16. package/dist/commands/installer.js.map +3 -3
  17. package/dist/commands/list-sessions.js +10 -0
  18. package/dist/commands/list-sessions.js.map +3 -3
  19. package/dist/commands/press-key.js +10 -0
  20. package/dist/commands/press-key.js.map +3 -3
  21. package/dist/commands/read-history.js +10 -0
  22. package/dist/commands/read-history.js.map +3 -3
  23. package/dist/commands/read-screen.js +10 -0
  24. package/dist/commands/read-screen.js.map +3 -3
  25. package/dist/commands/resize.js +10 -0
  26. package/dist/commands/resize.js.map +3 -3
  27. package/dist/commands/runtime.js +10 -0
  28. package/dist/commands/runtime.js.map +3 -3
  29. package/dist/commands/screenshot.js +10 -0
  30. package/dist/commands/screenshot.js.map +3 -3
  31. package/dist/commands/send-signal.js +10 -0
  32. package/dist/commands/send-signal.js.map +3 -3
  33. package/dist/commands/type.js +10 -0
  34. package/dist/commands/type.js.map +3 -3
  35. package/dist/commands/uninstall.js +13 -3
  36. package/dist/commands/uninstall.js.map +3 -3
  37. package/dist/commands/wait-for-exit.js +10 -0
  38. package/dist/commands/wait-for-exit.js.map +3 -3
  39. package/dist/commands/wait-for.js +10 -0
  40. package/dist/commands/wait-for.js.map +3 -3
  41. package/dist/testing/cli-repl.js +595 -144
  42. package/dist/testing/cli-repl.js.map +4 -4
  43. package/dist/testing/qa-cli.js +595 -144
  44. package/dist/testing/qa-cli.js.map +4 -4
  45. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.js +1 -1
  46. package/node_modules/toolcraft-design/dist/components/help-formatter.js +1 -1
  47. package/node_modules/toolcraft-design/dist/components/inspector-card.d.ts +21 -0
  48. package/node_modules/toolcraft-design/dist/components/inspector-card.js +42 -0
  49. package/node_modules/toolcraft-design/dist/components/resource-browser.d.ts +21 -0
  50. package/node_modules/toolcraft-design/dist/components/resource-browser.js +98 -0
  51. package/node_modules/toolcraft-design/dist/explorer/index.d.ts +2 -0
  52. package/node_modules/toolcraft-design/dist/explorer/index.js +1 -0
  53. package/node_modules/toolcraft-design/dist/explorer/two-pane.d.ts +102 -0
  54. package/node_modules/toolcraft-design/dist/explorer/two-pane.js +510 -0
  55. package/node_modules/toolcraft-design/dist/index.d.ts +6 -2
  56. package/node_modules/toolcraft-design/dist/index.js +3 -1
  57. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.d.ts +3 -3
  58. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.js +3 -3
  59. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.js +3 -0
  60. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.js +8 -4
  61. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -920,7 +920,7 @@ function formatColumns(opts) {
920
920
  return [`${firstIndent}${row.left}`];
921
921
  }
922
922
  const rightLines = wrapWords(row.right, rightWidth);
923
- if (visibleWidth(row.left) > leftWidth) {
923
+ if (visibleWidth(row.left) >= leftWidth) {
924
924
  return [
925
925
  `${firstIndent}${row.left}`,
926
926
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1057,7 +1057,7 @@ function formatColumns2(opts) {
1057
1057
  return [`${firstIndent}${row.left}`];
1058
1058
  }
1059
1059
  const rightLines = wrapWords2(row.right, rightWidth);
1060
- if (row.left.length > leftWidth) {
1060
+ if (row.left.length >= leftWidth) {
1061
1061
  return [
1062
1062
  `${firstIndent}${row.left}`,
1063
1063
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1877,9 +1877,9 @@ var GLYPHS = {
1877
1877
  barEnd: glyph("\u2514", "-"),
1878
1878
  radioActive: glyph("\u25CF", ">"),
1879
1879
  radioInactive: glyph("\u25CB", " "),
1880
- checkboxActive: glyph("\u25FB", "[ ]"),
1881
- checkboxSelected: glyph("\u25FC", "[+]"),
1882
- checkboxInactive: glyph("\u25FB", "[ ]"),
1880
+ checkboxActive: "[ ]",
1881
+ checkboxSelected: "[x]",
1882
+ checkboxInactive: "[ ]",
1883
1883
  passwordMask: glyph("\u2022", "*"),
1884
1884
  ellipsis: "..."
1885
1885
  };
@@ -1930,6 +1930,9 @@ function mapKey(name, char) {
1930
1930
  if (char === " ") {
1931
1931
  return "space";
1932
1932
  }
1933
+ if (char !== void 0 && aliases[char] !== void 0) {
1934
+ return aliases[char];
1935
+ }
1933
1936
  if (!name) {
1934
1937
  return void 0;
1935
1938
  }
@@ -3309,6 +3312,50 @@ var S = {
3309
3312
  Json
3310
3313
  };
3311
3314
 
3315
+ // ../toolcraft/src/runtime-logging.ts
3316
+ var LOG_LEVEL_RANK = {
3317
+ silent: 0,
3318
+ error: 1,
3319
+ warn: 2,
3320
+ info: 3,
3321
+ debug: 4,
3322
+ trace: 5
3323
+ };
3324
+ var LOG_LEVELS = Object.freeze([
3325
+ "silent",
3326
+ "error",
3327
+ "warn",
3328
+ "info",
3329
+ "debug",
3330
+ "trace"
3331
+ ]);
3332
+ function isLogLevel(value) {
3333
+ return LOG_LEVELS.includes(value);
3334
+ }
3335
+ function shouldEmitDiagnostic(eventLevel, configuredLevel) {
3336
+ if (eventLevel === "silent" || configuredLevel === "silent") {
3337
+ return false;
3338
+ }
3339
+ return LOG_LEVEL_RANK[eventLevel] <= LOG_LEVEL_RANK[configuredLevel];
3340
+ }
3341
+ function createRuntimeLogger(options = {}) {
3342
+ const level = options.level ?? "warn";
3343
+ const sink = options.logger;
3344
+ return {
3345
+ level,
3346
+ emit(event) {
3347
+ if (!shouldEmitDiagnostic(event.level, level)) {
3348
+ return;
3349
+ }
3350
+ if (typeof sink === "function") {
3351
+ sink(event);
3352
+ return;
3353
+ }
3354
+ sink?.emit(event);
3355
+ }
3356
+ };
3357
+ }
3358
+
3312
3359
  // ../toolcraft/src/package-metadata.ts
3313
3360
  import { existsSync, readFileSync, statSync } from "node:fs";
3314
3361
  import path from "node:path";
@@ -7805,14 +7852,16 @@ function getVisibleCliChildren(root) {
7805
7852
  return root.kind === "group" ? root.children.filter(isNodeVisibleInCli) : [];
7806
7853
  }
7807
7854
  function createHandlerContext(command, params17) {
7855
+ const diagnostics = createRuntimeLogger();
7808
7856
  return {
7809
7857
  params: params17,
7810
7858
  secrets: resolveCommandSecrets(command),
7811
7859
  fetch: globalThis.fetch,
7812
7860
  fs: createFs(),
7813
7861
  env: createEnv(),
7814
- progress() {
7815
- return void 0;
7862
+ diagnostics,
7863
+ progress(message2) {
7864
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
7816
7865
  }
7817
7866
  };
7818
7867
  }
@@ -7885,11 +7934,7 @@ var showParams = S.Object({
7885
7934
  approvalId: S.String()
7886
7935
  });
7887
7936
  var runParams = S.Object({
7888
- approvalId: S.String(),
7889
- dryRun: S.Optional(S.Boolean({
7890
- description: "Preview the approval without prompting or executing it",
7891
- scope: ["cli"]
7892
- }))
7937
+ approvalId: S.String()
7893
7938
  });
7894
7939
  var approvalsGroup = markApprovalsBuiltIn(
7895
7940
  defineGroup({
@@ -7946,10 +7991,6 @@ var approvalsGroup = markApprovalsBuiltIn(
7946
7991
  scope: runScope,
7947
7992
  params: runParams,
7948
7993
  handler: async ({ params: params17, runtimeOptions, root }) => {
7949
- if (params17.dryRun === true) {
7950
- const { tasks } = await ensureApprovalList(runtimeOptions, { create: false });
7951
- return tasks.get(params17.approvalId);
7952
- }
7953
7994
  return runApproval(params17.approvalId, runtimeOptions, root);
7954
7995
  },
7955
7996
  render: {
@@ -10348,7 +10389,7 @@ var McpClient = class {
10348
10389
  await onPromptsChanged();
10349
10390
  });
10350
10391
  messageLayer.onNotification("notifications/message", async (params17) => {
10351
- if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
10392
+ if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel2(params17.level)) {
10352
10393
  return;
10353
10394
  }
10354
10395
  if (!hasOwn(params17, "data")) {
@@ -11703,7 +11744,7 @@ function hasOwn(value, property) {
11703
11744
  function isRequestId(value) {
11704
11745
  return typeof value === "string" || typeof value === "number";
11705
11746
  }
11706
- function isLogLevel(value) {
11747
+ function isLogLevel2(value) {
11707
11748
  return value === "debug" || value === "info" || value === "notice" || value === "warning" || value === "error" || value === "critical" || value === "alert" || value === "emergency";
11708
11749
  }
11709
11750
  function toRequestId(value) {
@@ -13383,6 +13424,125 @@ function getExpectedNumberDescription(schema) {
13383
13424
  return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
13384
13425
  }
13385
13426
 
13427
+ // ../toolcraft/src/api-error-summary.ts
13428
+ var REQUEST_ID_FIELDS = ["request_id", "requestId", "id"];
13429
+ var CODE_FIELDS = ["code", "error_code", "errorCode", "error"];
13430
+ var MESSAGE_FIELDS = ["message", "detail", "title", "error_description"];
13431
+ function summarizeHttpError(error3) {
13432
+ const body = redactHttpBody(error3.response.body);
13433
+ const retryAfter = getHeader(error3.response.headers, "retry-after");
13434
+ const message2 = extractMessage(body);
13435
+ const summary = {
13436
+ status: error3.response.status,
13437
+ statusText: error3.response.statusText,
13438
+ requestMethod: error3.request.method,
13439
+ requestUrl: error3.request.url,
13440
+ ...message2 === void 0 ? {} : { message: message2 },
13441
+ ...optionalString("requestId", getHeader(error3.response.headers, "x-request-id") ?? extractFirstString(body, REQUEST_ID_FIELDS)),
13442
+ ...optionalString("code", extractCode(body)),
13443
+ ...optionalString("retryAfter", retryAfter),
13444
+ ...optionalArray("fieldErrors", extractFieldErrors(body)),
13445
+ ...optionalString("hint", createHttpErrorHint(error3.response.status, retryAfter))
13446
+ };
13447
+ return summary;
13448
+ }
13449
+ function createHttpErrorHint(status, retryAfter) {
13450
+ if (status === 401 || status === 403) {
13451
+ return "Check the configured API credentials and permissions.";
13452
+ }
13453
+ if ((status === 429 || status === 503) && retryAfter !== void 0) {
13454
+ return `Retry after ${retryAfter}.`;
13455
+ }
13456
+ return void 0;
13457
+ }
13458
+ function extractMessage(body) {
13459
+ if (!isPlainObject4(body)) {
13460
+ return void 0;
13461
+ }
13462
+ const graphqlMessage = extractGraphQlMessage(body);
13463
+ if (graphqlMessage !== void 0) {
13464
+ return graphqlMessage;
13465
+ }
13466
+ return extractFirstString(body, MESSAGE_FIELDS);
13467
+ }
13468
+ function extractCode(body) {
13469
+ if (!isPlainObject4(body)) {
13470
+ return void 0;
13471
+ }
13472
+ const graphqlCode = extractGraphQlCode(body);
13473
+ if (graphqlCode !== void 0) {
13474
+ return graphqlCode;
13475
+ }
13476
+ return extractFirstString(body, CODE_FIELDS);
13477
+ }
13478
+ function extractGraphQlMessage(body) {
13479
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13480
+ return isPlainObject4(first) && typeof first.message === "string" ? first.message : void 0;
13481
+ }
13482
+ function extractGraphQlCode(body) {
13483
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13484
+ if (!isPlainObject4(first) || !isPlainObject4(first.extensions)) {
13485
+ return void 0;
13486
+ }
13487
+ return typeof first.extensions.code === "string" ? first.extensions.code : void 0;
13488
+ }
13489
+ function extractFieldErrors(body) {
13490
+ if (!isPlainObject4(body)) {
13491
+ return void 0;
13492
+ }
13493
+ const candidates = [body.field_errors, body.fieldErrors, body.errors, body.non_field_errors];
13494
+ const flattened = candidates.flatMap((candidate) => flattenFieldErrors(candidate, []));
13495
+ return flattened.length === 0 ? void 0 : flattened;
13496
+ }
13497
+ function flattenFieldErrors(value, path25) {
13498
+ if (typeof value === "string") {
13499
+ return [{ path: formatPath2(path25), message: value }];
13500
+ }
13501
+ if (Array.isArray(value)) {
13502
+ if (value.every((entry) => typeof entry === "string")) {
13503
+ return value.map((message2) => ({ path: formatPath2(path25), message: message2 }));
13504
+ }
13505
+ return value.flatMap((entry, index) => flattenFieldErrors(entry, [...path25, String(index)]));
13506
+ }
13507
+ if (!isPlainObject4(value)) {
13508
+ return [];
13509
+ }
13510
+ return Object.entries(value).flatMap(([key2, nested]) => flattenFieldErrors(nested, [...path25, key2]));
13511
+ }
13512
+ function formatPath2(path25) {
13513
+ return path25.length === 0 ? "error" : path25.join(".");
13514
+ }
13515
+ function extractFirstString(body, fields) {
13516
+ if (!isPlainObject4(body)) {
13517
+ return void 0;
13518
+ }
13519
+ for (const field of fields) {
13520
+ const value = body[field];
13521
+ if (typeof value === "string" && value.length > 0) {
13522
+ return value;
13523
+ }
13524
+ }
13525
+ return void 0;
13526
+ }
13527
+ function getHeader(headers, name) {
13528
+ const lowerName = name.toLowerCase();
13529
+ for (const [key2, value] of Object.entries(headers)) {
13530
+ if (key2.toLowerCase() === lowerName && value.length > 0) {
13531
+ return value;
13532
+ }
13533
+ }
13534
+ return void 0;
13535
+ }
13536
+ function optionalString(name, value) {
13537
+ return value === void 0 ? {} : { [name]: value };
13538
+ }
13539
+ function optionalArray(name, value) {
13540
+ return value === void 0 ? {} : { [name]: value };
13541
+ }
13542
+ function isPlainObject4(value) {
13543
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13544
+ }
13545
+
13386
13546
  // ../toolcraft/src/renderer.ts
13387
13547
  import YAML from "yaml";
13388
13548
  function isObject(value) {
@@ -13430,6 +13590,9 @@ function unwrapMcpEnvelope(result) {
13430
13590
  function isArrayOfObjects(value) {
13431
13591
  return Array.isArray(value) && value.every((entry) => isObject(entry));
13432
13592
  }
13593
+ function isNonEmptyArrayOfObjects(value) {
13594
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => isObject(entry));
13595
+ }
13433
13596
  function stringifyValue2(value) {
13434
13597
  if (value === void 0) {
13435
13598
  return "";
@@ -13484,10 +13647,26 @@ function detailRows(result, depth = 0) {
13484
13647
  rows.push(...detailRows(value, depth + 1));
13485
13648
  continue;
13486
13649
  }
13650
+ if (isNonEmptyArrayOfObjects(value)) {
13651
+ rows.push({ label, value: "" });
13652
+ rows.push(...arrayObjectDetailRows(value, depth + 1));
13653
+ continue;
13654
+ }
13487
13655
  rows.push({ label, value: displayScalar(value) });
13488
13656
  }
13489
13657
  return rows;
13490
13658
  }
13659
+ function arrayObjectDetailRows(value, depth) {
13660
+ return value.flatMap((entry, index) => {
13661
+ if (value.length === 1) {
13662
+ return detailRows(entry, depth);
13663
+ }
13664
+ return [
13665
+ { label: `${" ".repeat(depth)}${index + 1}`, value: "" },
13666
+ ...detailRows(entry, depth + 1)
13667
+ ];
13668
+ });
13669
+ }
13491
13670
  function displayScalar(value) {
13492
13671
  if (typeof value === "boolean") {
13493
13672
  return value ? "Yes" : "No";
@@ -13518,17 +13697,31 @@ function directScalarRows(result) {
13518
13697
  function directObjectSections(result) {
13519
13698
  return Object.entries(result).filter(([, value]) => isObject(value)).map(([key2, value]) => ({ title: humanizeKey(key2), rows: detailRows(value) })).filter((section) => section.rows.length > 0);
13520
13699
  }
13700
+ function directArrayObjectSections(result) {
13701
+ return Object.entries(result).flatMap(([key2, value]) => {
13702
+ if (!isNonEmptyArrayOfObjects(value)) {
13703
+ return [];
13704
+ }
13705
+ const title = humanizeKey(key2);
13706
+ return value.map((entry, index) => ({
13707
+ title: value.length === 1 ? title : `${title} ${index + 1}`,
13708
+ rows: detailRows(entry)
13709
+ })).filter((section) => section.rows.length > 0);
13710
+ });
13711
+ }
13521
13712
  function renderObjectCard(result, primitives, title) {
13522
13713
  const scalarRows = directScalarRows(result);
13523
13714
  const nestedSections = directObjectSections(result);
13524
- const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13715
+ const arrayObjectSections = directArrayObjectSections(result);
13716
+ const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13525
13717
  return renderDetailCard({
13526
13718
  theme: primitives.getTheme(),
13527
13719
  title,
13528
13720
  sections: [
13529
13721
  { rows: scalarRows },
13530
13722
  ...nestedSections,
13531
- { title: "Lists", rows: listRows }
13723
+ { title: "Lists", rows: listRows },
13724
+ ...arrayObjectSections
13532
13725
  ]
13533
13726
  });
13534
13727
  }
@@ -13817,11 +14010,12 @@ var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
13817
14010
  "fetch",
13818
14011
  "fs",
13819
14012
  "env",
14013
+ "diagnostics",
13820
14014
  "progress",
13821
14015
  "runtimeOptions",
13822
14016
  "root"
13823
14017
  ]);
13824
- var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
14018
+ var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
13825
14019
  var NULL_OPTION_VALUE = /* @__PURE__ */ Symbol("toolcraft.cli.null");
13826
14020
  function inferProgramName(argv) {
13827
14021
  const entrypoint = argv[1];
@@ -14458,6 +14652,7 @@ function createOption(field, globalLongOptionFlags) {
14458
14652
  function resolveCLIControls(controls) {
14459
14653
  return {
14460
14654
  debug: controls?.debug === true,
14655
+ logLevel: controls?.logLevel === true,
14461
14656
  output: controls?.output === true,
14462
14657
  verbose: controls?.verbose === true,
14463
14658
  yes: controls?.yes === true
@@ -14477,6 +14672,9 @@ function getGlobalLongOptionFlags(presetsEnabled, versionEnabled, controls) {
14477
14672
  if (controls.debug) {
14478
14673
  flags.push("--debug");
14479
14674
  }
14675
+ if (controls.logLevel) {
14676
+ flags.push("--log-level");
14677
+ }
14480
14678
  if (controls.verbose) {
14481
14679
  flags.push("--verbose");
14482
14680
  }
@@ -14520,6 +14718,9 @@ function createCommanderOption(flags, description, field) {
14520
14718
  function hasHelpFlag(argv) {
14521
14719
  return argv.some((token) => HELP_FLAGS.has(token));
14522
14720
  }
14721
+ function normalizeVerboseAlias(argv) {
14722
+ return argv.map((token) => token === "-v" ? "--verbose" : token);
14723
+ }
14523
14724
  function resolveHelpOutput(argv) {
14524
14725
  for (let index = 0; index < argv.length; index += 1) {
14525
14726
  const token = argv[index] ?? "";
@@ -14567,7 +14768,7 @@ function findVisibleChild(group, token, scope) {
14567
14768
  (child) => child.name === token || child.aliases.includes(token)
14568
14769
  );
14569
14770
  }
14570
- function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14771
+ function resolveHelpTarget(root, argv, scope, rootUsageName, rootDisplayName) {
14571
14772
  const breadcrumb = [rootDisplayName ?? root.name];
14572
14773
  let current = root;
14573
14774
  for (const token of argv.slice(2)) {
@@ -14579,7 +14780,9 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14579
14780
  }
14580
14781
  const child = findVisibleChild(current, token, scope);
14581
14782
  if (child === void 0) {
14582
- break;
14783
+ throw new UserError(
14784
+ formatUnknownHelpCommandMessage(current, token, scope, rootUsageName, breadcrumb)
14785
+ );
14583
14786
  }
14584
14787
  breadcrumb.push(child.name);
14585
14788
  current = child;
@@ -14589,6 +14792,16 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14589
14792
  node: current
14590
14793
  };
14591
14794
  }
14795
+ function formatUnknownHelpCommandMessage(group, input, scope, rootUsageName, breadcrumb) {
14796
+ const suggestions = suggest(
14797
+ input,
14798
+ getHelpChildren(group, scope).map((child) => child.name)
14799
+ );
14800
+ const commandPath = breadcrumb.slice(1).join(" ");
14801
+ const helpTarget = commandPath.length === 0 ? rootUsageName : `${rootUsageName} ${commandPath}`;
14802
+ return `${formatSuggestionMessage(`Unknown command "${input}".`, suggestions)}
14803
+ Run ${helpTarget} --help for usage.`;
14804
+ }
14592
14805
  function formatHelpFieldFlags(field, globalLongOptionFlags) {
14593
14806
  if (field.positionalIndex !== void 0) {
14594
14807
  return formatPositionalToken(field);
@@ -14925,11 +15138,17 @@ function formatGlobalOptionsLine(ctx) {
14925
15138
  if (ctx.controls.output) {
14926
15139
  flags.push("--output <format>");
14927
15140
  }
15141
+ if (ctx.controls.verbose) {
15142
+ flags.push("-v, --verbose");
15143
+ }
14928
15144
  if (ctx.showVersion) {
14929
15145
  flags.push("--version");
14930
15146
  }
14931
15147
  return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
14932
15148
  }
15149
+ function formatLeafGlobalOptionsLine(ctx) {
15150
+ return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
15151
+ }
14933
15152
  function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
14934
15153
  const seen = /* @__PURE__ */ new Map();
14935
15154
  const visit = (node) => {
@@ -15047,6 +15266,10 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
15047
15266
  sections.push(`${text.sectionHeader("Options")}
15048
15267
  ${formatHelpOptionList(optionRows)}`);
15049
15268
  }
15269
+ const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
15270
+ if (builtInLine.length > 0) {
15271
+ sections.push(builtInLine);
15272
+ }
15050
15273
  const secretRows = formatSecretRows(command.secrets);
15051
15274
  if (secretRows.length > 0) {
15052
15275
  sections.push(
@@ -15071,6 +15294,91 @@ ${formatExampleRows(command.examples, breadcrumb, rootUsageName).join("\n")}`
15071
15294
  sections
15072
15295
  });
15073
15296
  }
15297
+ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
15298
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
15299
+ globalOptions.presetsEnabled,
15300
+ globalOptions.showVersion,
15301
+ globalOptions.controls
15302
+ );
15303
+ const node = target.node;
15304
+ if (node.kind === "group") {
15305
+ const commandRows = formatCommandRows(node, "cli", casing, globalLongOptionFlags);
15306
+ const isRoot = node === root;
15307
+ return `${JSON.stringify(
15308
+ {
15309
+ schemaVersion: 1,
15310
+ kind: "group",
15311
+ name: target.breadcrumb.at(-1) ?? rootUsageName,
15312
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15313
+ usage: buildUsageLine(
15314
+ target.breadcrumb,
15315
+ rootUsageName,
15316
+ formatGroupUsageSuffix(node, "cli", casing, globalLongOptionFlags)
15317
+ ),
15318
+ ...node.description === void 0 ? {} : { description: node.description },
15319
+ commands: commandRows.map((row) => ({ name: row.name, description: row.description })),
15320
+ options: isRoot ? collectSchemaGlobalFieldRows(node, "cli", casing, globalLongOptionFlags).map((row) => ({
15321
+ name: row.flags.split(/[ ,]+/)[0]?.replace(/^--/, "") ?? row.flags,
15322
+ flags: row.flags.split(", "),
15323
+ type: "unknown",
15324
+ description: row.description,
15325
+ required: false
15326
+ })) : []
15327
+ },
15328
+ null,
15329
+ 2
15330
+ )}
15331
+ `;
15332
+ }
15333
+ const collected = collectFields(node.params, casing, globalLongOptionFlags);
15334
+ const fields = assignPositionals(collected.fields, node.positional);
15335
+ const positionalFields = fields.filter((field) => field.positionalIndex !== void 0);
15336
+ const usageSuffix = positionalFields.length > 0 ? `[OPTIONS] ${positionalFields.map(formatPositionalToken).join(" ")}` : "[OPTIONS]";
15337
+ return `${JSON.stringify(
15338
+ {
15339
+ schemaVersion: 1,
15340
+ kind: "command",
15341
+ name: node.name,
15342
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15343
+ usage: buildUsageLine(target.breadcrumb, rootUsageName, usageSuffix),
15344
+ ...node.description === void 0 ? {} : { description: node.description },
15345
+ options: fields.filter((field) => field.global !== true).map((field) => formatJsonHelpOption(field, globalLongOptionFlags)),
15346
+ secrets: Object.entries(node.secrets).map(([name, secret]) => ({
15347
+ name,
15348
+ env: secret.env,
15349
+ required: secret.optional !== true,
15350
+ ...secret.description === void 0 ? {} : { description: secret.description }
15351
+ })),
15352
+ examples: node.examples
15353
+ },
15354
+ null,
15355
+ 2
15356
+ )}
15357
+ `;
15358
+ }
15359
+ function formatJsonHelpOption(field, globalLongOptionFlags) {
15360
+ return {
15361
+ name: field.displayPath,
15362
+ flags: formatHelpFieldFlags(field, globalLongOptionFlags).split(", "),
15363
+ type: formatJsonHelpSchemaType(field.schema),
15364
+ ...field.description === void 0 ? {} : { description: field.description },
15365
+ required: field.requiredWhenActive,
15366
+ ...field.hasDefault ? { default: field.defaultValue } : {},
15367
+ ...field.positionalIndex === void 0 ? {} : { positional: true }
15368
+ };
15369
+ }
15370
+ function formatJsonHelpSchemaType(schema) {
15371
+ if (schema.kind === "enum") {
15372
+ return "enum";
15373
+ }
15374
+ if (schema.kind === "array") {
15375
+ return "array";
15376
+ }
15377
+ if (schema.kind === "json") {
15378
+ return "json";
15379
+ }
15380
+ return schema.kind;
15381
+ }
15074
15382
  function renderHelpDocument(input) {
15075
15383
  const title = input.breadcrumb.filter((segment) => segment.length > 0).join(" ") || input.rootUsageName;
15076
15384
  const description = input.description ?? "";
@@ -15094,11 +15402,27 @@ function renderHelpDocument(input) {
15094
15402
  `;
15095
15403
  }
15096
15404
  async function renderGeneratedHelp(root, argv, options) {
15097
- const target = resolveHelpTarget(root, argv, "cli", options.rootDisplayName);
15098
15405
  const output = resolveHelpOutput(argv);
15099
15406
  const casing = options.casing ?? "kebab";
15100
15407
  const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
15408
+ const target = resolveHelpTarget(root, argv, "cli", rootUsageName, options.rootDisplayName);
15101
15409
  const controls = resolveCLIControls(options.controls);
15410
+ if (output === "json") {
15411
+ process.stdout.write(
15412
+ renderJsonHelp(
15413
+ target,
15414
+ root,
15415
+ casing,
15416
+ {
15417
+ controls,
15418
+ showVersion: options.version !== void 0,
15419
+ presetsEnabled: options.presets === true
15420
+ },
15421
+ rootUsageName
15422
+ )
15423
+ );
15424
+ return;
15425
+ }
15102
15426
  await withOutputFormat2(output, async () => {
15103
15427
  const rendered = target.node.kind === "group" ? renderGroupHelp(
15104
15428
  target.node,
@@ -15218,9 +15542,11 @@ function addCommanderChild(parent, child, isDefault, siblingNames) {
15218
15542
  parent,
15219
15543
  "_toolcraftHiddenDefaultNames",
15220
15544
  getToolcraftHiddenDefaultNames(parent).concat([
15221
- ...new Set([Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15222
- (name) => typeof name === "string" && name.length > 0
15223
- ))
15545
+ ...new Set(
15546
+ [Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15547
+ (name) => typeof name === "string" && name.length > 0
15548
+ )
15549
+ )
15224
15550
  ])
15225
15551
  );
15226
15552
  parent.addCommand(child, { hidden: true, isDefault: true });
@@ -15277,6 +15603,13 @@ function addGlobalOptions(command, presetsEnabled, controls) {
15277
15603
  new Option("--debug [mode]", "Print stack traces for unexpected errors.").preset("trim").argParser(parseDebugStackMode)
15278
15604
  );
15279
15605
  }
15606
+ if (controls.logLevel) {
15607
+ options.push(
15608
+ new Option("--log-level <level>", "Set runtime diagnostic log level.").argParser(
15609
+ parseLogLevel
15610
+ )
15611
+ );
15612
+ }
15280
15613
  if (controls.verbose) {
15281
15614
  options.push(new Option("--verbose", "Print detailed runtime diagnostics."));
15282
15615
  }
@@ -15296,6 +15629,29 @@ function parseDebugStackMode(value) {
15296
15629
  formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
15297
15630
  );
15298
15631
  }
15632
+ function parseLogLevel(value) {
15633
+ if (isLogLevel(value)) {
15634
+ return value;
15635
+ }
15636
+ throw new InvalidArgumentError(
15637
+ formatInvalidEnumMessage("--log-level", value, [...LOG_LEVELS], {
15638
+ candidates: ["warn", "debug", "trace"],
15639
+ threshold: 3
15640
+ })
15641
+ );
15642
+ }
15643
+ function writeCLIDiagnosticEvent(event) {
15644
+ const transcript = event.data?.transcript;
15645
+ if (typeof transcript === "string") {
15646
+ process.stderr.write(transcript);
15647
+ return;
15648
+ }
15649
+ if (event.category === "progress" || event.level === "trace") {
15650
+ return;
15651
+ }
15652
+ process.stderr.write(`${event.message}
15653
+ `);
15654
+ }
15299
15655
  function setNestedValue(target, path25, value) {
15300
15656
  let cursor2 = target;
15301
15657
  for (let index = 0; index < path25.length - 1; index += 1) {
@@ -15486,7 +15842,7 @@ function createEnv2(values = process.env) {
15486
15842
  }
15487
15843
  };
15488
15844
  }
15489
- function isPlainObject4(value) {
15845
+ function isPlainObject5(value) {
15490
15846
  return typeof value === "object" && value !== null && !Array.isArray(value);
15491
15847
  }
15492
15848
  function hasFieldValue(value) {
@@ -15618,7 +15974,7 @@ async function loadPresetValues(fields, presetPath) {
15618
15974
  { cause: error3 }
15619
15975
  );
15620
15976
  }
15621
- if (!isPlainObject4(parsedPreset)) {
15977
+ if (!isPlainObject5(parsedPreset)) {
15622
15978
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
15623
15979
  }
15624
15980
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
@@ -15637,7 +15993,7 @@ async function loadPresetValues(fields, presetPath) {
15637
15993
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
15638
15994
  );
15639
15995
  }
15640
- if (!isPlainObject4(value)) {
15996
+ if (!isPlainObject5(value)) {
15641
15997
  throw new UserError(
15642
15998
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
15643
15999
  );
@@ -15680,8 +16036,8 @@ function matchesFixtureValue(expected, actual) {
15680
16036
  }
15681
16037
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
15682
16038
  }
15683
- if (isPlainObject4(expected)) {
15684
- if (!isPlainObject4(actual)) {
16039
+ if (isPlainObject5(expected)) {
16040
+ if (!isPlainObject5(actual)) {
15685
16041
  return false;
15686
16042
  }
15687
16043
  return Object.entries(expected).every(
@@ -15744,9 +16100,9 @@ function createFixtureFetch(entries) {
15744
16100
  };
15745
16101
  }
15746
16102
  function createFixtureFs(definition) {
15747
- const fsDefinition = isPlainObject4(definition) ? definition : {};
15748
- const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
15749
- const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
16103
+ const fsDefinition = isPlainObject5(definition) ? definition : {};
16104
+ const readFileEntries = isPlainObject5(fsDefinition.readFile) ? fsDefinition.readFile : {};
16105
+ const existsEntries = isPlainObject5(fsDefinition.exists) ? fsDefinition.exists : {};
15750
16106
  return {
15751
16107
  readFile: async (filePath) => {
15752
16108
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -15769,10 +16125,10 @@ function createFixtureFs(definition) {
15769
16125
  function resolveFixtureMethodResult(methodName, definition, args) {
15770
16126
  if (Array.isArray(definition)) {
15771
16127
  for (const entry of definition) {
15772
- if (!isPlainObject4(entry)) {
16128
+ if (!isPlainObject5(entry)) {
15773
16129
  continue;
15774
16130
  }
15775
- const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
16131
+ const explicitMatcher = isPlainObject5(entry.request) ? entry.request : void 0;
15776
16132
  const matcher = explicitMatcher ?? Object.fromEntries(
15777
16133
  Object.entries(entry).filter(
15778
16134
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -15784,7 +16140,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15784
16140
  matched = matchesFixtureValue(matcher.args, args);
15785
16141
  } else if (Object.keys(matcher).length === 0) {
15786
16142
  matched = true;
15787
- } else if (isPlainObject4(firstArg)) {
16143
+ } else if (isPlainObject5(firstArg)) {
15788
16144
  matched = matchesFixtureValue(matcher, firstArg);
15789
16145
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
15790
16146
  const [[, expectedValue]] = Object.entries(matcher);
@@ -15805,7 +16161,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15805
16161
  return Promise.resolve(null);
15806
16162
  }
15807
16163
  }
15808
- if (isPlainObject4(definition)) {
16164
+ if (isPlainObject5(definition)) {
15809
16165
  const firstArg = args[0];
15810
16166
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
15811
16167
  return Promise.resolve(definition[firstArg]);
@@ -15817,7 +16173,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15817
16173
  return Promise.resolve(null);
15818
16174
  }
15819
16175
  function createFixtureService(definition) {
15820
- const methods = isPlainObject4(definition) ? definition : {};
16176
+ const methods = isPlainObject5(definition) ? definition : {};
15821
16177
  return new Proxy(
15822
16178
  {},
15823
16179
  {
@@ -15915,7 +16271,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions, runt
15915
16271
  };
15916
16272
  }
15917
16273
  const scenario = await loadFixtureScenario(command, selector);
15918
- const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
16274
+ const scenarioServices = isPlainObject5(scenario.services) ? scenario.services : {};
15919
16275
  const customServiceNames = /* @__PURE__ */ new Set([
15920
16276
  ...Object.keys(services),
15921
16277
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -15975,6 +16331,19 @@ function renderCliErrorPattern(pattern) {
15975
16331
  process.exitCode = 1;
15976
16332
  return;
15977
16333
  }
16334
+ if (pattern.kind === "definition") {
16335
+ logger2.error(
16336
+ `Command definition error: ${pattern.error.message}
16337
+ This is a bug in the generated command definition, not in your command arguments.
16338
+ Run with --debug for a stack trace.`
16339
+ );
16340
+ if (pattern.debugStackMode !== void 0 && pattern.error.stack) {
16341
+ process.stderr.write(`${formatDebugStack(pattern.error.stack, pattern.debugStackMode)}
16342
+ `);
16343
+ }
16344
+ process.exitCode = 1;
16345
+ return;
16346
+ }
15978
16347
  if (pattern.kind === "toolcraft-bug") {
15979
16348
  logger2.error(
15980
16349
  `toolcraft hit an internal invariant: ${pattern.error.message}
@@ -16241,7 +16610,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16241
16610
  if (itemSchema.kind !== "object") {
16242
16611
  return value;
16243
16612
  }
16244
- if (!isPlainObject4(value)) {
16613
+ if (!isPlainObject5(value)) {
16245
16614
  errors2.push({
16246
16615
  path: displayPath,
16247
16616
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -16276,7 +16645,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16276
16645
  );
16277
16646
  }
16278
16647
  case "object": {
16279
- if (!isPlainObject4(value)) {
16648
+ if (!isPlainObject5(value)) {
16280
16649
  errors2.push({
16281
16650
  path: displayPath,
16282
16651
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16307,7 +16676,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16307
16676
  return result;
16308
16677
  }
16309
16678
  case "record": {
16310
- if (!isPlainObject4(value)) {
16679
+ if (!isPlainObject5(value)) {
16311
16680
  errors2.push({
16312
16681
  path: displayPath,
16313
16682
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16637,7 +17006,7 @@ function getResolvedFlags(command) {
16637
17006
  const flags = command.optsWithGlobals();
16638
17007
  return flags;
16639
17008
  }
16640
- async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, onErrorReportContext) {
17009
+ async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, diagnosticsOptions, onErrorReportContext) {
16641
17010
  const logger2 = createLogger();
16642
17011
  const primitives = {
16643
17012
  logger: logger2,
@@ -16648,6 +17017,10 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16648
17017
  const optionValues = state.actionCommand.optsWithGlobals();
16649
17018
  const resolvedFlags = optionValues;
16650
17019
  const output = resolveOutput(resolvedFlags);
17020
+ const diagnostics = createRuntimeLogger({
17021
+ level: resolvedFlags.logLevel ?? (diagnosticsOptions.verboseControlEnabled && resolvedFlags.verbose ? "trace" : diagnosticsOptions.logLevel),
17022
+ logger: diagnosticsOptions.logger ?? writeCLIDiagnosticEvent
17023
+ });
16651
17024
  const shouldPrompt = !resolvedFlags.yes && Boolean(process.stdin.isTTY);
16652
17025
  const runtime = await resolveFixtureRuntime(
16653
17026
  state.command,
@@ -16661,7 +17034,9 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16661
17034
  fetch: runtime.fetch,
16662
17035
  fs: runtime.fs,
16663
17036
  env: runtime.env,
17037
+ diagnostics,
16664
17038
  progress(message2) {
17039
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
16665
17040
  logger2.info(message2);
16666
17041
  }
16667
17042
  };
@@ -16738,18 +17113,18 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16738
17113
  }
16739
17114
  }
16740
17115
  function isStringRecord(value) {
16741
- return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
17116
+ return isPlainObject5(value) && Object.values(value).every((entry) => typeof entry === "string");
16742
17117
  }
16743
17118
  function isHttpErrorLike(error3) {
16744
- if (!isPlainObject4(error3)) {
17119
+ if (!isPlainObject5(error3)) {
16745
17120
  return false;
16746
17121
  }
16747
- if (error3.name !== "HttpError" || typeof error3.message !== "string") {
17122
+ if (typeof error3.name !== "string" || typeof error3.message !== "string") {
16748
17123
  return false;
16749
17124
  }
16750
17125
  const request = error3.request;
16751
17126
  const response = error3.response;
16752
- return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && hasOwnProperty3(response, "body");
17127
+ return isPlainObject5(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject5(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && hasOwnProperty3(response, "body");
16753
17128
  }
16754
17129
  function hasTypedOptionalField(value, field, type2) {
16755
17130
  return !hasOwnProperty3(value, field) || typeof value[field] === type2;
@@ -16758,7 +17133,7 @@ function isNonEmptyString(value) {
16758
17133
  return typeof value === "string" && value.trim().length > 0;
16759
17134
  }
16760
17135
  function isProblemDetailsLike(body) {
16761
- if (!isPlainObject4(body)) {
17136
+ if (!isPlainObject5(body)) {
16762
17137
  return false;
16763
17138
  }
16764
17139
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -16779,11 +17154,11 @@ function isProblemDetailsLike(body) {
16779
17154
  return hasOwnNonEmptyString(body, "title") || hasOwnNonEmptyString(body, "detail");
16780
17155
  }
16781
17156
  function isGraphQLErrorEnvelopeLike(body) {
16782
- if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
17157
+ if (!isPlainObject5(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
16783
17158
  return false;
16784
17159
  }
16785
17160
  return body.errors.every((error3) => {
16786
- if (!isPlainObject4(error3) || typeof error3.message !== "string") {
17161
+ if (!isPlainObject5(error3) || typeof error3.message !== "string") {
16787
17162
  return false;
16788
17163
  }
16789
17164
  if (hasOwnProperty3(error3, "path")) {
@@ -16793,7 +17168,7 @@ function isGraphQLErrorEnvelopeLike(body) {
16793
17168
  }
16794
17169
  }
16795
17170
  if (hasOwnProperty3(error3, "extensions")) {
16796
- if (!isPlainObject4(error3.extensions)) {
17171
+ if (!isPlainObject5(error3.extensions)) {
16797
17172
  return false;
16798
17173
  }
16799
17174
  if (hasOwnProperty3(error3.extensions, "code") && typeof error3.extensions.code !== "string") {
@@ -16876,6 +17251,7 @@ function formatHttpErrorSnippet(body) {
16876
17251
  }
16877
17252
  function renderHttpError(error3, options) {
16878
17253
  const detailed = options.verbose || options.debugStackMode !== void 0;
17254
+ const summary = summarizeHttpError(error3);
16879
17255
  const lines = [
16880
17256
  styleHttpErrorLine(`Request: ${error3.request.method} ${error3.request.url}`, text.muted)
16881
17257
  ];
@@ -16902,11 +17278,27 @@ function renderHttpError(error3, options) {
16902
17278
  indentHttpErrorBlock(formatHttpErrorBody(error3.response.body))
16903
17279
  );
16904
17280
  } else {
16905
- lines.push(
16906
- "",
16907
- `Response body: ${formatHttpErrorSnippet(error3.response.body)}`,
16908
- "Re-run with --verbose to see headers and full body."
16909
- );
17281
+ const summaryLines = [
17282
+ summary.code === void 0 ? void 0 : `Code: ${summary.code}`,
17283
+ summary.message === void 0 ? void 0 : `Message: ${summary.message}`,
17284
+ summary.requestId === void 0 ? void 0 : `Request id: ${summary.requestId}`,
17285
+ summary.retryAfter === void 0 ? void 0 : `Retry after: ${summary.retryAfter}`,
17286
+ summary.hint === void 0 ? void 0 : `Hint: ${summary.hint}`
17287
+ ].filter((line) => line !== void 0);
17288
+ if (summary.fieldErrors !== void 0 && summary.fieldErrors.length > 0) {
17289
+ summaryLines.push(
17290
+ "",
17291
+ "Field errors:",
17292
+ ...summary.fieldErrors.map((fieldError) => ` ${fieldError.path}: ${fieldError.message}`)
17293
+ );
17294
+ }
17295
+ lines.push("");
17296
+ if (summaryLines.length > 0) {
17297
+ lines.push(...summaryLines);
17298
+ } else {
17299
+ lines.push(`Response body: ${formatHttpErrorSnippet(error3.response.body)}`);
17300
+ }
17301
+ lines.push("Re-run with --verbose to see headers and full body.");
16910
17302
  }
16911
17303
  process.stderr.write(`${lines.join("\n")}
16912
17304
  `);
@@ -16921,7 +17313,11 @@ async function handleRunError(error3, options) {
16921
17313
  await withOutputFormat2(options.output, async () => {
16922
17314
  if (error3 instanceof UserError) {
16923
17315
  renderCliErrorPattern(
16924
- options.userErrorPattern === "usage" ? {
17316
+ options.userErrorPattern === "definition" ? {
17317
+ kind: "definition",
17318
+ error: error3,
17319
+ debugStackMode: options.debugStackMode
17320
+ } : options.userErrorPattern === "usage" ? {
16925
17321
  kind: "usage",
16926
17322
  message: error3.message,
16927
17323
  rootUsageName: options.rootUsageName,
@@ -17159,13 +17555,23 @@ function findUnknownCommanderCommand(program, argv) {
17159
17555
  commandPath: pathSegments.join(" ")
17160
17556
  };
17161
17557
  }
17162
- if (current.commands.length === 0 || getDefaultCommanderCommandName(current) !== void 0) {
17558
+ if (current.commands.length === 0) {
17163
17559
  return void 0;
17164
17560
  }
17165
17561
  const child = current.commands.find(
17166
17562
  (command) => command.name() === token || command.aliases().includes(token)
17167
17563
  );
17168
17564
  if (child === void 0) {
17565
+ if (getDefaultCommanderCommandName(current) !== void 0) {
17566
+ if (shouldRejectDefaultCommandToken(current, token, pathSegments)) {
17567
+ return {
17568
+ input: token,
17569
+ currentCommand: current,
17570
+ commandPath: pathSegments.join(" ")
17571
+ };
17572
+ }
17573
+ return void 0;
17574
+ }
17169
17575
  return {
17170
17576
  input: token,
17171
17577
  currentCommand: current,
@@ -17177,6 +17583,36 @@ function findUnknownCommanderCommand(program, argv) {
17177
17583
  }
17178
17584
  return void 0;
17179
17585
  }
17586
+ function shouldRejectDefaultCommandToken(command, token, pathSegments) {
17587
+ return pathSegments.length === 0 && isBareCommandLikeToken(token) && hasNonDefaultPublicChildCommand(command);
17588
+ }
17589
+ function hasNonDefaultPublicChildCommand(command) {
17590
+ const defaultName = getDefaultCommanderCommandName(command);
17591
+ return command.commands.some(
17592
+ (child) => child.name() !== defaultName && !isToolcraftHiddenCommander(child) && !getToolcraftReservedChildNames(command).includes(child.name())
17593
+ );
17594
+ }
17595
+ function isBareCommandLikeToken(token) {
17596
+ if (token.length === 0) {
17597
+ return false;
17598
+ }
17599
+ for (const character of token) {
17600
+ if (!isCommandNameCharacter(character)) {
17601
+ return false;
17602
+ }
17603
+ }
17604
+ return true;
17605
+ }
17606
+ function isCommandNameCharacter(character) {
17607
+ const code = character.codePointAt(0);
17608
+ if (code === void 0) {
17609
+ return false;
17610
+ }
17611
+ const isLowercaseLetter = code >= 97 && code <= 122;
17612
+ const isUppercaseLetter = code >= 65 && code <= 90;
17613
+ const isDigit = code >= 48 && code <= 57;
17614
+ return isLowercaseLetter || isUppercaseLetter || isDigit || character === "-" || character === "_";
17615
+ }
17180
17616
  function getDefaultCommanderCommandName(command) {
17181
17617
  const candidate = command;
17182
17618
  return typeof candidate._defaultCommandName === "string" ? candidate._defaultCommandName : void 0;
@@ -17195,101 +17631,116 @@ function configureCommanderSuggestionOutput(command) {
17195
17631
  }
17196
17632
  async function runCLI(roots, options = {}) {
17197
17633
  enableSourceMaps();
17198
- const argv = [...options.argv ?? process.argv];
17199
- const normalizedRoot = normalizeRoots(roots, argv);
17200
- const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17201
- await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17202
- const casing = options.casing ?? "kebab";
17203
- const services = options.services ?? {};
17204
- const runtimeOptions = options.humanInLoop ?? {};
17205
- const runtimeFetch = options.fetch ?? globalThis.fetch;
17206
- const version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
17207
- const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
17208
17634
  const controls = resolveCLIControls(options.controls);
17209
- const servicesWithBuiltIns = {
17210
- ...services,
17211
- runtimeOptions,
17212
- root
17213
- };
17214
- const requirementOptions = {
17215
- apiVersion: options.apiVersion
17216
- };
17217
- validateServices(services);
17218
- if (hasHelpFlag(argv)) {
17219
- await renderGeneratedHelp(root, argv, { ...options, version });
17220
- return;
17221
- }
17222
- const program = new CommanderCommand();
17223
- program.name(root.name);
17224
- program.exitOverride();
17225
- program.showHelpAfterError();
17226
- program.addHelpCommand(false);
17227
- const presetsEnabled = options.presets === true;
17228
- const globalLongOptionFlags = getGlobalLongOptionFlags(
17229
- presetsEnabled,
17230
- version !== void 0,
17231
- controls
17232
- );
17233
- addGlobalOptions(program, presetsEnabled, controls);
17234
- if (version !== void 0) {
17235
- program.version(version, "--version");
17236
- }
17237
- Reflect.set(
17238
- program,
17239
- "_toolcraftReservedChildNames",
17240
- root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17241
- );
17635
+ const argv = controls.verbose ? normalizeVerboseAlias([...options.argv ?? process.argv]) : [...options.argv ?? process.argv];
17636
+ const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
17242
17637
  let lastActionCommand;
17243
17638
  let resolvedCommandPath = "";
17639
+ let program;
17640
+ let version;
17641
+ let userErrorPattern = "definition";
17244
17642
  let errorReportContext;
17245
- const execute = async (state) => {
17246
- lastActionCommand = state.actionCommand;
17247
- resolvedCommandPath = formatCliCommandPath(state.commandPath);
17248
- await executeCommand(
17249
- state,
17250
- servicesWithBuiltIns,
17251
- requirementOptions,
17252
- runtimeFetch,
17643
+ try {
17644
+ const normalizedRoot = normalizeRoots(roots, argv);
17645
+ const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17646
+ await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17647
+ const casing = options.casing ?? "kebab";
17648
+ const services = options.services ?? {};
17649
+ const runtimeOptions = options.humanInLoop ?? {};
17650
+ const runtimeFetch = options.fetch ?? globalThis.fetch;
17651
+ version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
17652
+ const servicesWithBuiltIns = {
17653
+ ...services,
17253
17654
  runtimeOptions,
17254
- (context) => {
17255
- errorReportContext = context;
17256
- }
17257
- );
17258
- };
17259
- const rootChildNames = new Set(
17260
- root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17261
- );
17262
- for (const child of root.children) {
17263
- const command = createNodeCommand(
17264
- child,
17265
- casing,
17266
- globalLongOptionFlags,
17267
- execute,
17655
+ root
17656
+ };
17657
+ const requirementOptions = {
17658
+ apiVersion: options.apiVersion
17659
+ };
17660
+ validateServices(services);
17661
+ if (hasHelpFlag(argv)) {
17662
+ userErrorPattern = "usage";
17663
+ await renderGeneratedHelp(root, argv, { ...options, version });
17664
+ return;
17665
+ }
17666
+ if (argv.length <= 2 && root.default?.scope.includes("cli") !== true) {
17667
+ userErrorPattern = "usage";
17668
+ await renderGeneratedHelp(root, argv, { ...options, version });
17669
+ return;
17670
+ }
17671
+ program = new CommanderCommand();
17672
+ program.name(root.name);
17673
+ program.exitOverride();
17674
+ program.showHelpAfterError();
17675
+ program.addHelpCommand(false);
17676
+ const presetsEnabled = options.presets === true;
17677
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
17268
17678
  presetsEnabled,
17679
+ version !== void 0,
17269
17680
  controls
17270
17681
  );
17271
- if (command === null) {
17272
- continue;
17682
+ addGlobalOptions(program, presetsEnabled, controls);
17683
+ if (version !== void 0) {
17684
+ program.version(version, "--version");
17273
17685
  }
17274
- const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17275
- addCommanderChild(program, command, isDefaultChild, rootChildNames);
17276
- }
17277
- configureCommanderSuggestionOutput(program);
17278
- const unknownCommand = findUnknownCommanderCommand(program, argv);
17279
- if (unknownCommand !== void 0) {
17280
- createLogger().error(
17281
- appendUsagePointer(
17282
- formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17686
+ Reflect.set(
17687
+ program,
17688
+ "_toolcraftReservedChildNames",
17689
+ root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17690
+ );
17691
+ const execute = async (state) => {
17692
+ lastActionCommand = state.actionCommand;
17693
+ resolvedCommandPath = formatCliCommandPath(state.commandPath);
17694
+ await executeCommand(
17695
+ state,
17696
+ servicesWithBuiltIns,
17697
+ requirementOptions,
17698
+ runtimeFetch,
17699
+ runtimeOptions,
17283
17700
  {
17284
- rootUsageName,
17285
- commandPath: unknownCommand.commandPath
17701
+ logLevel: options.logLevel,
17702
+ logger: options.logger,
17703
+ verboseControlEnabled: controls.verbose
17704
+ },
17705
+ (context) => {
17706
+ errorReportContext = context;
17286
17707
  }
17287
- )
17708
+ );
17709
+ };
17710
+ const rootChildNames = new Set(
17711
+ root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17288
17712
  );
17289
- process.exitCode = 1;
17290
- return;
17291
- }
17292
- try {
17713
+ for (const child of root.children) {
17714
+ const command = createNodeCommand(
17715
+ child,
17716
+ casing,
17717
+ globalLongOptionFlags,
17718
+ execute,
17719
+ presetsEnabled,
17720
+ controls
17721
+ );
17722
+ if (command === null) {
17723
+ continue;
17724
+ }
17725
+ const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17726
+ addCommanderChild(program, command, isDefaultChild, rootChildNames);
17727
+ }
17728
+ configureCommanderSuggestionOutput(program);
17729
+ const unknownCommand = findUnknownCommanderCommand(program, argv);
17730
+ if (unknownCommand !== void 0) {
17731
+ createLogger().error(
17732
+ appendUsagePointer(
17733
+ formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17734
+ {
17735
+ rootUsageName,
17736
+ commandPath: unknownCommand.commandPath
17737
+ }
17738
+ )
17739
+ );
17740
+ process.exitCode = 1;
17741
+ return;
17742
+ }
17743
+ userErrorPattern = "usage";
17293
17744
  await program.parseAsync(argv);
17294
17745
  } catch (error3) {
17295
17746
  if (error3 instanceof ApprovalDeclinedError) {
@@ -17321,7 +17772,7 @@ async function runCLI(roots, options = {}) {
17321
17772
  argv,
17322
17773
  rootUsageName,
17323
17774
  commandPath: resolvedCommandPath,
17324
- userErrorPattern: errorReportContext?.params === void 0 ? "usage" : "runtime-user"
17775
+ userErrorPattern: errorReportContext?.params === void 0 ? userErrorPattern : "runtime-user"
17325
17776
  });
17326
17777
  }
17327
17778
  }