terminal-pilot 0.0.32 → 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 +610 -163
  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 +22 -17
  12. package/dist/commands/index.js.map +4 -4
  13. package/dist/commands/install.js +22 -17
  14. package/dist/commands/install.js.map +4 -4
  15. package/dist/commands/installer.js +22 -17
  16. package/dist/commands/installer.js.map +4 -4
  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 -4
  36. package/dist/commands/uninstall.js.map +4 -4
  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 +610 -163
  42. package/dist/testing/cli-repl.js.map +4 -4
  43. package/dist/testing/qa-cli.js +610 -163
  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 +4 -3
@@ -992,7 +992,7 @@ function formatColumns(opts) {
992
992
  return [`${firstIndent}${row.left}`];
993
993
  }
994
994
  const rightLines = wrapWords(row.right, rightWidth);
995
- if (visibleWidth(row.left) > leftWidth) {
995
+ if (visibleWidth(row.left) >= leftWidth) {
996
996
  return [
997
997
  `${firstIndent}${row.left}`,
998
998
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1129,7 +1129,7 @@ function formatColumns2(opts) {
1129
1129
  return [`${firstIndent}${row.left}`];
1130
1130
  }
1131
1131
  const rightLines = wrapWords2(row.right, rightWidth);
1132
- if (row.left.length > leftWidth) {
1132
+ if (row.left.length >= leftWidth) {
1133
1133
  return [
1134
1134
  `${firstIndent}${row.left}`,
1135
1135
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1949,9 +1949,9 @@ var GLYPHS = {
1949
1949
  barEnd: glyph("\u2514", "-"),
1950
1950
  radioActive: glyph("\u25CF", ">"),
1951
1951
  radioInactive: glyph("\u25CB", " "),
1952
- checkboxActive: glyph("\u25FB", "[ ]"),
1953
- checkboxSelected: glyph("\u25FC", "[+]"),
1954
- checkboxInactive: glyph("\u25FB", "[ ]"),
1952
+ checkboxActive: "[ ]",
1953
+ checkboxSelected: "[x]",
1954
+ checkboxInactive: "[ ]",
1955
1955
  passwordMask: glyph("\u2022", "*"),
1956
1956
  ellipsis: "..."
1957
1957
  };
@@ -2002,6 +2002,9 @@ function mapKey(name, char) {
2002
2002
  if (char === " ") {
2003
2003
  return "space";
2004
2004
  }
2005
+ if (char !== void 0 && aliases[char] !== void 0) {
2006
+ return aliases[char];
2007
+ }
2005
2008
  if (!name) {
2006
2009
  return void 0;
2007
2010
  }
@@ -3381,6 +3384,50 @@ var S = {
3381
3384
  Json
3382
3385
  };
3383
3386
 
3387
+ // ../toolcraft/src/runtime-logging.ts
3388
+ var LOG_LEVEL_RANK = {
3389
+ silent: 0,
3390
+ error: 1,
3391
+ warn: 2,
3392
+ info: 3,
3393
+ debug: 4,
3394
+ trace: 5
3395
+ };
3396
+ var LOG_LEVELS = Object.freeze([
3397
+ "silent",
3398
+ "error",
3399
+ "warn",
3400
+ "info",
3401
+ "debug",
3402
+ "trace"
3403
+ ]);
3404
+ function isLogLevel(value) {
3405
+ return LOG_LEVELS.includes(value);
3406
+ }
3407
+ function shouldEmitDiagnostic(eventLevel, configuredLevel) {
3408
+ if (eventLevel === "silent" || configuredLevel === "silent") {
3409
+ return false;
3410
+ }
3411
+ return LOG_LEVEL_RANK[eventLevel] <= LOG_LEVEL_RANK[configuredLevel];
3412
+ }
3413
+ function createRuntimeLogger(options = {}) {
3414
+ const level = options.level ?? "warn";
3415
+ const sink = options.logger;
3416
+ return {
3417
+ level,
3418
+ emit(event) {
3419
+ if (!shouldEmitDiagnostic(event.level, level)) {
3420
+ return;
3421
+ }
3422
+ if (typeof sink === "function") {
3423
+ sink(event);
3424
+ return;
3425
+ }
3426
+ sink?.emit(event);
3427
+ }
3428
+ };
3429
+ }
3430
+
3384
3431
  // ../toolcraft/src/package-metadata.ts
3385
3432
  import { existsSync, readFileSync, statSync } from "node:fs";
3386
3433
  import path from "node:path";
@@ -7877,14 +7924,16 @@ function getVisibleCliChildren(root) {
7877
7924
  return root.kind === "group" ? root.children.filter(isNodeVisibleInCli) : [];
7878
7925
  }
7879
7926
  function createHandlerContext(command, params17) {
7927
+ const diagnostics = createRuntimeLogger();
7880
7928
  return {
7881
7929
  params: params17,
7882
7930
  secrets: resolveCommandSecrets(command),
7883
7931
  fetch: globalThis.fetch,
7884
7932
  fs: createFs(),
7885
7933
  env: createEnv(),
7886
- progress() {
7887
- return void 0;
7934
+ diagnostics,
7935
+ progress(message2) {
7936
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
7888
7937
  }
7889
7938
  };
7890
7939
  }
@@ -7957,11 +8006,7 @@ var showParams = S.Object({
7957
8006
  approvalId: S.String()
7958
8007
  });
7959
8008
  var runParams = S.Object({
7960
- approvalId: S.String(),
7961
- dryRun: S.Optional(S.Boolean({
7962
- description: "Preview the approval without prompting or executing it",
7963
- scope: ["cli"]
7964
- }))
8009
+ approvalId: S.String()
7965
8010
  });
7966
8011
  var approvalsGroup = markApprovalsBuiltIn(
7967
8012
  defineGroup({
@@ -8018,10 +8063,6 @@ var approvalsGroup = markApprovalsBuiltIn(
8018
8063
  scope: runScope,
8019
8064
  params: runParams,
8020
8065
  handler: async ({ params: params17, runtimeOptions, root }) => {
8021
- if (params17.dryRun === true) {
8022
- const { tasks } = await ensureApprovalList(runtimeOptions, { create: false });
8023
- return tasks.get(params17.approvalId);
8024
- }
8025
8066
  return runApproval(params17.approvalId, runtimeOptions, root);
8026
8067
  },
8027
8068
  render: {
@@ -10420,7 +10461,7 @@ var McpClient = class {
10420
10461
  await onPromptsChanged();
10421
10462
  });
10422
10463
  messageLayer.onNotification("notifications/message", async (params17) => {
10423
- if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
10464
+ if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel2(params17.level)) {
10424
10465
  return;
10425
10466
  }
10426
10467
  if (!hasOwn(params17, "data")) {
@@ -11775,7 +11816,7 @@ function hasOwn(value, property) {
11775
11816
  function isRequestId(value) {
11776
11817
  return typeof value === "string" || typeof value === "number";
11777
11818
  }
11778
- function isLogLevel(value) {
11819
+ function isLogLevel2(value) {
11779
11820
  return value === "debug" || value === "info" || value === "notice" || value === "warning" || value === "error" || value === "critical" || value === "alert" || value === "emergency";
11780
11821
  }
11781
11822
  function toRequestId(value) {
@@ -13455,6 +13496,125 @@ function getExpectedNumberDescription(schema) {
13455
13496
  return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
13456
13497
  }
13457
13498
 
13499
+ // ../toolcraft/src/api-error-summary.ts
13500
+ var REQUEST_ID_FIELDS = ["request_id", "requestId", "id"];
13501
+ var CODE_FIELDS = ["code", "error_code", "errorCode", "error"];
13502
+ var MESSAGE_FIELDS = ["message", "detail", "title", "error_description"];
13503
+ function summarizeHttpError(error3) {
13504
+ const body = redactHttpBody(error3.response.body);
13505
+ const retryAfter = getHeader(error3.response.headers, "retry-after");
13506
+ const message2 = extractMessage(body);
13507
+ const summary = {
13508
+ status: error3.response.status,
13509
+ statusText: error3.response.statusText,
13510
+ requestMethod: error3.request.method,
13511
+ requestUrl: error3.request.url,
13512
+ ...message2 === void 0 ? {} : { message: message2 },
13513
+ ...optionalString("requestId", getHeader(error3.response.headers, "x-request-id") ?? extractFirstString(body, REQUEST_ID_FIELDS)),
13514
+ ...optionalString("code", extractCode(body)),
13515
+ ...optionalString("retryAfter", retryAfter),
13516
+ ...optionalArray("fieldErrors", extractFieldErrors(body)),
13517
+ ...optionalString("hint", createHttpErrorHint(error3.response.status, retryAfter))
13518
+ };
13519
+ return summary;
13520
+ }
13521
+ function createHttpErrorHint(status, retryAfter) {
13522
+ if (status === 401 || status === 403) {
13523
+ return "Check the configured API credentials and permissions.";
13524
+ }
13525
+ if ((status === 429 || status === 503) && retryAfter !== void 0) {
13526
+ return `Retry after ${retryAfter}.`;
13527
+ }
13528
+ return void 0;
13529
+ }
13530
+ function extractMessage(body) {
13531
+ if (!isPlainObject4(body)) {
13532
+ return void 0;
13533
+ }
13534
+ const graphqlMessage = extractGraphQlMessage(body);
13535
+ if (graphqlMessage !== void 0) {
13536
+ return graphqlMessage;
13537
+ }
13538
+ return extractFirstString(body, MESSAGE_FIELDS);
13539
+ }
13540
+ function extractCode(body) {
13541
+ if (!isPlainObject4(body)) {
13542
+ return void 0;
13543
+ }
13544
+ const graphqlCode = extractGraphQlCode(body);
13545
+ if (graphqlCode !== void 0) {
13546
+ return graphqlCode;
13547
+ }
13548
+ return extractFirstString(body, CODE_FIELDS);
13549
+ }
13550
+ function extractGraphQlMessage(body) {
13551
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13552
+ return isPlainObject4(first) && typeof first.message === "string" ? first.message : void 0;
13553
+ }
13554
+ function extractGraphQlCode(body) {
13555
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13556
+ if (!isPlainObject4(first) || !isPlainObject4(first.extensions)) {
13557
+ return void 0;
13558
+ }
13559
+ return typeof first.extensions.code === "string" ? first.extensions.code : void 0;
13560
+ }
13561
+ function extractFieldErrors(body) {
13562
+ if (!isPlainObject4(body)) {
13563
+ return void 0;
13564
+ }
13565
+ const candidates = [body.field_errors, body.fieldErrors, body.errors, body.non_field_errors];
13566
+ const flattened = candidates.flatMap((candidate) => flattenFieldErrors(candidate, []));
13567
+ return flattened.length === 0 ? void 0 : flattened;
13568
+ }
13569
+ function flattenFieldErrors(value, path25) {
13570
+ if (typeof value === "string") {
13571
+ return [{ path: formatPath2(path25), message: value }];
13572
+ }
13573
+ if (Array.isArray(value)) {
13574
+ if (value.every((entry) => typeof entry === "string")) {
13575
+ return value.map((message2) => ({ path: formatPath2(path25), message: message2 }));
13576
+ }
13577
+ return value.flatMap((entry, index) => flattenFieldErrors(entry, [...path25, String(index)]));
13578
+ }
13579
+ if (!isPlainObject4(value)) {
13580
+ return [];
13581
+ }
13582
+ return Object.entries(value).flatMap(([key2, nested]) => flattenFieldErrors(nested, [...path25, key2]));
13583
+ }
13584
+ function formatPath2(path25) {
13585
+ return path25.length === 0 ? "error" : path25.join(".");
13586
+ }
13587
+ function extractFirstString(body, fields) {
13588
+ if (!isPlainObject4(body)) {
13589
+ return void 0;
13590
+ }
13591
+ for (const field of fields) {
13592
+ const value = body[field];
13593
+ if (typeof value === "string" && value.length > 0) {
13594
+ return value;
13595
+ }
13596
+ }
13597
+ return void 0;
13598
+ }
13599
+ function getHeader(headers, name) {
13600
+ const lowerName = name.toLowerCase();
13601
+ for (const [key2, value] of Object.entries(headers)) {
13602
+ if (key2.toLowerCase() === lowerName && value.length > 0) {
13603
+ return value;
13604
+ }
13605
+ }
13606
+ return void 0;
13607
+ }
13608
+ function optionalString(name, value) {
13609
+ return value === void 0 ? {} : { [name]: value };
13610
+ }
13611
+ function optionalArray(name, value) {
13612
+ return value === void 0 ? {} : { [name]: value };
13613
+ }
13614
+ function isPlainObject4(value) {
13615
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13616
+ }
13617
+
13458
13618
  // ../toolcraft/src/renderer.ts
13459
13619
  import YAML from "yaml";
13460
13620
  function isObject(value) {
@@ -13502,6 +13662,9 @@ function unwrapMcpEnvelope(result) {
13502
13662
  function isArrayOfObjects(value) {
13503
13663
  return Array.isArray(value) && value.every((entry) => isObject(entry));
13504
13664
  }
13665
+ function isNonEmptyArrayOfObjects(value) {
13666
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => isObject(entry));
13667
+ }
13505
13668
  function stringifyValue2(value) {
13506
13669
  if (value === void 0) {
13507
13670
  return "";
@@ -13556,10 +13719,26 @@ function detailRows(result, depth = 0) {
13556
13719
  rows.push(...detailRows(value, depth + 1));
13557
13720
  continue;
13558
13721
  }
13722
+ if (isNonEmptyArrayOfObjects(value)) {
13723
+ rows.push({ label, value: "" });
13724
+ rows.push(...arrayObjectDetailRows(value, depth + 1));
13725
+ continue;
13726
+ }
13559
13727
  rows.push({ label, value: displayScalar(value) });
13560
13728
  }
13561
13729
  return rows;
13562
13730
  }
13731
+ function arrayObjectDetailRows(value, depth) {
13732
+ return value.flatMap((entry, index) => {
13733
+ if (value.length === 1) {
13734
+ return detailRows(entry, depth);
13735
+ }
13736
+ return [
13737
+ { label: `${" ".repeat(depth)}${index + 1}`, value: "" },
13738
+ ...detailRows(entry, depth + 1)
13739
+ ];
13740
+ });
13741
+ }
13563
13742
  function displayScalar(value) {
13564
13743
  if (typeof value === "boolean") {
13565
13744
  return value ? "Yes" : "No";
@@ -13590,17 +13769,31 @@ function directScalarRows(result) {
13590
13769
  function directObjectSections(result) {
13591
13770
  return Object.entries(result).filter(([, value]) => isObject(value)).map(([key2, value]) => ({ title: humanizeKey(key2), rows: detailRows(value) })).filter((section) => section.rows.length > 0);
13592
13771
  }
13772
+ function directArrayObjectSections(result) {
13773
+ return Object.entries(result).flatMap(([key2, value]) => {
13774
+ if (!isNonEmptyArrayOfObjects(value)) {
13775
+ return [];
13776
+ }
13777
+ const title = humanizeKey(key2);
13778
+ return value.map((entry, index) => ({
13779
+ title: value.length === 1 ? title : `${title} ${index + 1}`,
13780
+ rows: detailRows(entry)
13781
+ })).filter((section) => section.rows.length > 0);
13782
+ });
13783
+ }
13593
13784
  function renderObjectCard(result, primitives, title) {
13594
13785
  const scalarRows = directScalarRows(result);
13595
13786
  const nestedSections = directObjectSections(result);
13596
- const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13787
+ const arrayObjectSections = directArrayObjectSections(result);
13788
+ const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13597
13789
  return renderDetailCard({
13598
13790
  theme: primitives.getTheme(),
13599
13791
  title,
13600
13792
  sections: [
13601
13793
  { rows: scalarRows },
13602
13794
  ...nestedSections,
13603
- { title: "Lists", rows: listRows }
13795
+ { title: "Lists", rows: listRows },
13796
+ ...arrayObjectSections
13604
13797
  ]
13605
13798
  });
13606
13799
  }
@@ -13889,11 +14082,12 @@ var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
13889
14082
  "fetch",
13890
14083
  "fs",
13891
14084
  "env",
14085
+ "diagnostics",
13892
14086
  "progress",
13893
14087
  "runtimeOptions",
13894
14088
  "root"
13895
14089
  ]);
13896
- var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
14090
+ var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
13897
14091
  var NULL_OPTION_VALUE = /* @__PURE__ */ Symbol("toolcraft.cli.null");
13898
14092
  function inferProgramName(argv) {
13899
14093
  const entrypoint = argv[1];
@@ -14530,6 +14724,7 @@ function createOption(field, globalLongOptionFlags) {
14530
14724
  function resolveCLIControls(controls) {
14531
14725
  return {
14532
14726
  debug: controls?.debug === true,
14727
+ logLevel: controls?.logLevel === true,
14533
14728
  output: controls?.output === true,
14534
14729
  verbose: controls?.verbose === true,
14535
14730
  yes: controls?.yes === true
@@ -14549,6 +14744,9 @@ function getGlobalLongOptionFlags(presetsEnabled, versionEnabled, controls) {
14549
14744
  if (controls.debug) {
14550
14745
  flags.push("--debug");
14551
14746
  }
14747
+ if (controls.logLevel) {
14748
+ flags.push("--log-level");
14749
+ }
14552
14750
  if (controls.verbose) {
14553
14751
  flags.push("--verbose");
14554
14752
  }
@@ -14592,6 +14790,9 @@ function createCommanderOption(flags, description, field) {
14592
14790
  function hasHelpFlag(argv) {
14593
14791
  return argv.some((token) => HELP_FLAGS.has(token));
14594
14792
  }
14793
+ function normalizeVerboseAlias(argv) {
14794
+ return argv.map((token) => token === "-v" ? "--verbose" : token);
14795
+ }
14595
14796
  function resolveHelpOutput(argv) {
14596
14797
  for (let index = 0; index < argv.length; index += 1) {
14597
14798
  const token = argv[index] ?? "";
@@ -14639,7 +14840,7 @@ function findVisibleChild(group, token, scope) {
14639
14840
  (child) => child.name === token || child.aliases.includes(token)
14640
14841
  );
14641
14842
  }
14642
- function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14843
+ function resolveHelpTarget(root, argv, scope, rootUsageName, rootDisplayName) {
14643
14844
  const breadcrumb = [rootDisplayName ?? root.name];
14644
14845
  let current = root;
14645
14846
  for (const token of argv.slice(2)) {
@@ -14651,7 +14852,9 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14651
14852
  }
14652
14853
  const child = findVisibleChild(current, token, scope);
14653
14854
  if (child === void 0) {
14654
- break;
14855
+ throw new UserError(
14856
+ formatUnknownHelpCommandMessage(current, token, scope, rootUsageName, breadcrumb)
14857
+ );
14655
14858
  }
14656
14859
  breadcrumb.push(child.name);
14657
14860
  current = child;
@@ -14661,6 +14864,16 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14661
14864
  node: current
14662
14865
  };
14663
14866
  }
14867
+ function formatUnknownHelpCommandMessage(group, input, scope, rootUsageName, breadcrumb) {
14868
+ const suggestions = suggest(
14869
+ input,
14870
+ getHelpChildren(group, scope).map((child) => child.name)
14871
+ );
14872
+ const commandPath = breadcrumb.slice(1).join(" ");
14873
+ const helpTarget = commandPath.length === 0 ? rootUsageName : `${rootUsageName} ${commandPath}`;
14874
+ return `${formatSuggestionMessage(`Unknown command "${input}".`, suggestions)}
14875
+ Run ${helpTarget} --help for usage.`;
14876
+ }
14664
14877
  function formatHelpFieldFlags(field, globalLongOptionFlags) {
14665
14878
  if (field.positionalIndex !== void 0) {
14666
14879
  return formatPositionalToken(field);
@@ -14997,11 +15210,17 @@ function formatGlobalOptionsLine(ctx) {
14997
15210
  if (ctx.controls.output) {
14998
15211
  flags.push("--output <format>");
14999
15212
  }
15213
+ if (ctx.controls.verbose) {
15214
+ flags.push("-v, --verbose");
15215
+ }
15000
15216
  if (ctx.showVersion) {
15001
15217
  flags.push("--version");
15002
15218
  }
15003
15219
  return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
15004
15220
  }
15221
+ function formatLeafGlobalOptionsLine(ctx) {
15222
+ return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
15223
+ }
15005
15224
  function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
15006
15225
  const seen = /* @__PURE__ */ new Map();
15007
15226
  const visit = (node) => {
@@ -15119,6 +15338,10 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
15119
15338
  sections.push(`${text.sectionHeader("Options")}
15120
15339
  ${formatHelpOptionList(optionRows)}`);
15121
15340
  }
15341
+ const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
15342
+ if (builtInLine.length > 0) {
15343
+ sections.push(builtInLine);
15344
+ }
15122
15345
  const secretRows = formatSecretRows(command.secrets);
15123
15346
  if (secretRows.length > 0) {
15124
15347
  sections.push(
@@ -15143,6 +15366,91 @@ ${formatExampleRows(command.examples, breadcrumb, rootUsageName).join("\n")}`
15143
15366
  sections
15144
15367
  });
15145
15368
  }
15369
+ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
15370
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
15371
+ globalOptions.presetsEnabled,
15372
+ globalOptions.showVersion,
15373
+ globalOptions.controls
15374
+ );
15375
+ const node = target.node;
15376
+ if (node.kind === "group") {
15377
+ const commandRows = formatCommandRows(node, "cli", casing, globalLongOptionFlags);
15378
+ const isRoot = node === root;
15379
+ return `${JSON.stringify(
15380
+ {
15381
+ schemaVersion: 1,
15382
+ kind: "group",
15383
+ name: target.breadcrumb.at(-1) ?? rootUsageName,
15384
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15385
+ usage: buildUsageLine(
15386
+ target.breadcrumb,
15387
+ rootUsageName,
15388
+ formatGroupUsageSuffix(node, "cli", casing, globalLongOptionFlags)
15389
+ ),
15390
+ ...node.description === void 0 ? {} : { description: node.description },
15391
+ commands: commandRows.map((row) => ({ name: row.name, description: row.description })),
15392
+ options: isRoot ? collectSchemaGlobalFieldRows(node, "cli", casing, globalLongOptionFlags).map((row) => ({
15393
+ name: row.flags.split(/[ ,]+/)[0]?.replace(/^--/, "") ?? row.flags,
15394
+ flags: row.flags.split(", "),
15395
+ type: "unknown",
15396
+ description: row.description,
15397
+ required: false
15398
+ })) : []
15399
+ },
15400
+ null,
15401
+ 2
15402
+ )}
15403
+ `;
15404
+ }
15405
+ const collected = collectFields(node.params, casing, globalLongOptionFlags);
15406
+ const fields = assignPositionals(collected.fields, node.positional);
15407
+ const positionalFields = fields.filter((field) => field.positionalIndex !== void 0);
15408
+ const usageSuffix = positionalFields.length > 0 ? `[OPTIONS] ${positionalFields.map(formatPositionalToken).join(" ")}` : "[OPTIONS]";
15409
+ return `${JSON.stringify(
15410
+ {
15411
+ schemaVersion: 1,
15412
+ kind: "command",
15413
+ name: node.name,
15414
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15415
+ usage: buildUsageLine(target.breadcrumb, rootUsageName, usageSuffix),
15416
+ ...node.description === void 0 ? {} : { description: node.description },
15417
+ options: fields.filter((field) => field.global !== true).map((field) => formatJsonHelpOption(field, globalLongOptionFlags)),
15418
+ secrets: Object.entries(node.secrets).map(([name, secret]) => ({
15419
+ name,
15420
+ env: secret.env,
15421
+ required: secret.optional !== true,
15422
+ ...secret.description === void 0 ? {} : { description: secret.description }
15423
+ })),
15424
+ examples: node.examples
15425
+ },
15426
+ null,
15427
+ 2
15428
+ )}
15429
+ `;
15430
+ }
15431
+ function formatJsonHelpOption(field, globalLongOptionFlags) {
15432
+ return {
15433
+ name: field.displayPath,
15434
+ flags: formatHelpFieldFlags(field, globalLongOptionFlags).split(", "),
15435
+ type: formatJsonHelpSchemaType(field.schema),
15436
+ ...field.description === void 0 ? {} : { description: field.description },
15437
+ required: field.requiredWhenActive,
15438
+ ...field.hasDefault ? { default: field.defaultValue } : {},
15439
+ ...field.positionalIndex === void 0 ? {} : { positional: true }
15440
+ };
15441
+ }
15442
+ function formatJsonHelpSchemaType(schema) {
15443
+ if (schema.kind === "enum") {
15444
+ return "enum";
15445
+ }
15446
+ if (schema.kind === "array") {
15447
+ return "array";
15448
+ }
15449
+ if (schema.kind === "json") {
15450
+ return "json";
15451
+ }
15452
+ return schema.kind;
15453
+ }
15146
15454
  function renderHelpDocument(input) {
15147
15455
  const title = input.breadcrumb.filter((segment) => segment.length > 0).join(" ") || input.rootUsageName;
15148
15456
  const description = input.description ?? "";
@@ -15166,11 +15474,27 @@ function renderHelpDocument(input) {
15166
15474
  `;
15167
15475
  }
15168
15476
  async function renderGeneratedHelp(root, argv, options) {
15169
- const target = resolveHelpTarget(root, argv, "cli", options.rootDisplayName);
15170
15477
  const output = resolveHelpOutput(argv);
15171
15478
  const casing = options.casing ?? "kebab";
15172
15479
  const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
15480
+ const target = resolveHelpTarget(root, argv, "cli", rootUsageName, options.rootDisplayName);
15173
15481
  const controls = resolveCLIControls(options.controls);
15482
+ if (output === "json") {
15483
+ process.stdout.write(
15484
+ renderJsonHelp(
15485
+ target,
15486
+ root,
15487
+ casing,
15488
+ {
15489
+ controls,
15490
+ showVersion: options.version !== void 0,
15491
+ presetsEnabled: options.presets === true
15492
+ },
15493
+ rootUsageName
15494
+ )
15495
+ );
15496
+ return;
15497
+ }
15174
15498
  await withOutputFormat2(output, async () => {
15175
15499
  const rendered = target.node.kind === "group" ? renderGroupHelp(
15176
15500
  target.node,
@@ -15290,9 +15614,11 @@ function addCommanderChild(parent, child, isDefault, siblingNames) {
15290
15614
  parent,
15291
15615
  "_toolcraftHiddenDefaultNames",
15292
15616
  getToolcraftHiddenDefaultNames(parent).concat([
15293
- ...new Set([Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15294
- (name) => typeof name === "string" && name.length > 0
15295
- ))
15617
+ ...new Set(
15618
+ [Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15619
+ (name) => typeof name === "string" && name.length > 0
15620
+ )
15621
+ )
15296
15622
  ])
15297
15623
  );
15298
15624
  parent.addCommand(child, { hidden: true, isDefault: true });
@@ -15349,6 +15675,13 @@ function addGlobalOptions(command, presetsEnabled, controls) {
15349
15675
  new Option("--debug [mode]", "Print stack traces for unexpected errors.").preset("trim").argParser(parseDebugStackMode)
15350
15676
  );
15351
15677
  }
15678
+ if (controls.logLevel) {
15679
+ options.push(
15680
+ new Option("--log-level <level>", "Set runtime diagnostic log level.").argParser(
15681
+ parseLogLevel
15682
+ )
15683
+ );
15684
+ }
15352
15685
  if (controls.verbose) {
15353
15686
  options.push(new Option("--verbose", "Print detailed runtime diagnostics."));
15354
15687
  }
@@ -15368,6 +15701,29 @@ function parseDebugStackMode(value) {
15368
15701
  formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
15369
15702
  );
15370
15703
  }
15704
+ function parseLogLevel(value) {
15705
+ if (isLogLevel(value)) {
15706
+ return value;
15707
+ }
15708
+ throw new InvalidArgumentError(
15709
+ formatInvalidEnumMessage("--log-level", value, [...LOG_LEVELS], {
15710
+ candidates: ["warn", "debug", "trace"],
15711
+ threshold: 3
15712
+ })
15713
+ );
15714
+ }
15715
+ function writeCLIDiagnosticEvent(event) {
15716
+ const transcript = event.data?.transcript;
15717
+ if (typeof transcript === "string") {
15718
+ process.stderr.write(transcript);
15719
+ return;
15720
+ }
15721
+ if (event.category === "progress" || event.level === "trace") {
15722
+ return;
15723
+ }
15724
+ process.stderr.write(`${event.message}
15725
+ `);
15726
+ }
15371
15727
  function setNestedValue(target, path25, value) {
15372
15728
  let cursor2 = target;
15373
15729
  for (let index = 0; index < path25.length - 1; index += 1) {
@@ -15558,7 +15914,7 @@ function createEnv2(values = process.env) {
15558
15914
  }
15559
15915
  };
15560
15916
  }
15561
- function isPlainObject4(value) {
15917
+ function isPlainObject5(value) {
15562
15918
  return typeof value === "object" && value !== null && !Array.isArray(value);
15563
15919
  }
15564
15920
  function hasFieldValue(value) {
@@ -15690,7 +16046,7 @@ async function loadPresetValues(fields, presetPath) {
15690
16046
  { cause: error3 }
15691
16047
  );
15692
16048
  }
15693
- if (!isPlainObject4(parsedPreset)) {
16049
+ if (!isPlainObject5(parsedPreset)) {
15694
16050
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
15695
16051
  }
15696
16052
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
@@ -15709,7 +16065,7 @@ async function loadPresetValues(fields, presetPath) {
15709
16065
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
15710
16066
  );
15711
16067
  }
15712
- if (!isPlainObject4(value)) {
16068
+ if (!isPlainObject5(value)) {
15713
16069
  throw new UserError(
15714
16070
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
15715
16071
  );
@@ -15752,8 +16108,8 @@ function matchesFixtureValue(expected, actual) {
15752
16108
  }
15753
16109
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
15754
16110
  }
15755
- if (isPlainObject4(expected)) {
15756
- if (!isPlainObject4(actual)) {
16111
+ if (isPlainObject5(expected)) {
16112
+ if (!isPlainObject5(actual)) {
15757
16113
  return false;
15758
16114
  }
15759
16115
  return Object.entries(expected).every(
@@ -15816,9 +16172,9 @@ function createFixtureFetch(entries) {
15816
16172
  };
15817
16173
  }
15818
16174
  function createFixtureFs(definition) {
15819
- const fsDefinition = isPlainObject4(definition) ? definition : {};
15820
- const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
15821
- const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
16175
+ const fsDefinition = isPlainObject5(definition) ? definition : {};
16176
+ const readFileEntries = isPlainObject5(fsDefinition.readFile) ? fsDefinition.readFile : {};
16177
+ const existsEntries = isPlainObject5(fsDefinition.exists) ? fsDefinition.exists : {};
15822
16178
  return {
15823
16179
  readFile: async (filePath) => {
15824
16180
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -15841,10 +16197,10 @@ function createFixtureFs(definition) {
15841
16197
  function resolveFixtureMethodResult(methodName, definition, args) {
15842
16198
  if (Array.isArray(definition)) {
15843
16199
  for (const entry of definition) {
15844
- if (!isPlainObject4(entry)) {
16200
+ if (!isPlainObject5(entry)) {
15845
16201
  continue;
15846
16202
  }
15847
- const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
16203
+ const explicitMatcher = isPlainObject5(entry.request) ? entry.request : void 0;
15848
16204
  const matcher = explicitMatcher ?? Object.fromEntries(
15849
16205
  Object.entries(entry).filter(
15850
16206
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -15856,7 +16212,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15856
16212
  matched = matchesFixtureValue(matcher.args, args);
15857
16213
  } else if (Object.keys(matcher).length === 0) {
15858
16214
  matched = true;
15859
- } else if (isPlainObject4(firstArg)) {
16215
+ } else if (isPlainObject5(firstArg)) {
15860
16216
  matched = matchesFixtureValue(matcher, firstArg);
15861
16217
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
15862
16218
  const [[, expectedValue]] = Object.entries(matcher);
@@ -15877,7 +16233,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15877
16233
  return Promise.resolve(null);
15878
16234
  }
15879
16235
  }
15880
- if (isPlainObject4(definition)) {
16236
+ if (isPlainObject5(definition)) {
15881
16237
  const firstArg = args[0];
15882
16238
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
15883
16239
  return Promise.resolve(definition[firstArg]);
@@ -15889,7 +16245,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15889
16245
  return Promise.resolve(null);
15890
16246
  }
15891
16247
  function createFixtureService(definition) {
15892
- const methods = isPlainObject4(definition) ? definition : {};
16248
+ const methods = isPlainObject5(definition) ? definition : {};
15893
16249
  return new Proxy(
15894
16250
  {},
15895
16251
  {
@@ -15987,7 +16343,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions, runt
15987
16343
  };
15988
16344
  }
15989
16345
  const scenario = await loadFixtureScenario(command, selector);
15990
- const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
16346
+ const scenarioServices = isPlainObject5(scenario.services) ? scenario.services : {};
15991
16347
  const customServiceNames = /* @__PURE__ */ new Set([
15992
16348
  ...Object.keys(services),
15993
16349
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -16047,6 +16403,19 @@ function renderCliErrorPattern(pattern) {
16047
16403
  process.exitCode = 1;
16048
16404
  return;
16049
16405
  }
16406
+ if (pattern.kind === "definition") {
16407
+ logger2.error(
16408
+ `Command definition error: ${pattern.error.message}
16409
+ This is a bug in the generated command definition, not in your command arguments.
16410
+ Run with --debug for a stack trace.`
16411
+ );
16412
+ if (pattern.debugStackMode !== void 0 && pattern.error.stack) {
16413
+ process.stderr.write(`${formatDebugStack(pattern.error.stack, pattern.debugStackMode)}
16414
+ `);
16415
+ }
16416
+ process.exitCode = 1;
16417
+ return;
16418
+ }
16050
16419
  if (pattern.kind === "toolcraft-bug") {
16051
16420
  logger2.error(
16052
16421
  `toolcraft hit an internal invariant: ${pattern.error.message}
@@ -16313,7 +16682,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16313
16682
  if (itemSchema.kind !== "object") {
16314
16683
  return value;
16315
16684
  }
16316
- if (!isPlainObject4(value)) {
16685
+ if (!isPlainObject5(value)) {
16317
16686
  errors2.push({
16318
16687
  path: displayPath,
16319
16688
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -16348,7 +16717,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16348
16717
  );
16349
16718
  }
16350
16719
  case "object": {
16351
- if (!isPlainObject4(value)) {
16720
+ if (!isPlainObject5(value)) {
16352
16721
  errors2.push({
16353
16722
  path: displayPath,
16354
16723
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16379,7 +16748,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16379
16748
  return result;
16380
16749
  }
16381
16750
  case "record": {
16382
- if (!isPlainObject4(value)) {
16751
+ if (!isPlainObject5(value)) {
16383
16752
  errors2.push({
16384
16753
  path: displayPath,
16385
16754
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16709,7 +17078,7 @@ function getResolvedFlags(command) {
16709
17078
  const flags = command.optsWithGlobals();
16710
17079
  return flags;
16711
17080
  }
16712
- async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, onErrorReportContext) {
17081
+ async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, diagnosticsOptions, onErrorReportContext) {
16713
17082
  const logger2 = createLogger();
16714
17083
  const primitives = {
16715
17084
  logger: logger2,
@@ -16720,6 +17089,10 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16720
17089
  const optionValues = state.actionCommand.optsWithGlobals();
16721
17090
  const resolvedFlags = optionValues;
16722
17091
  const output = resolveOutput(resolvedFlags);
17092
+ const diagnostics = createRuntimeLogger({
17093
+ level: resolvedFlags.logLevel ?? (diagnosticsOptions.verboseControlEnabled && resolvedFlags.verbose ? "trace" : diagnosticsOptions.logLevel),
17094
+ logger: diagnosticsOptions.logger ?? writeCLIDiagnosticEvent
17095
+ });
16723
17096
  const shouldPrompt = !resolvedFlags.yes && Boolean(process.stdin.isTTY);
16724
17097
  const runtime = await resolveFixtureRuntime(
16725
17098
  state.command,
@@ -16733,7 +17106,9 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16733
17106
  fetch: runtime.fetch,
16734
17107
  fs: runtime.fs,
16735
17108
  env: runtime.env,
17109
+ diagnostics,
16736
17110
  progress(message2) {
17111
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
16737
17112
  logger2.info(message2);
16738
17113
  }
16739
17114
  };
@@ -16810,18 +17185,18 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16810
17185
  }
16811
17186
  }
16812
17187
  function isStringRecord(value) {
16813
- return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
17188
+ return isPlainObject5(value) && Object.values(value).every((entry) => typeof entry === "string");
16814
17189
  }
16815
17190
  function isHttpErrorLike(error3) {
16816
- if (!isPlainObject4(error3)) {
17191
+ if (!isPlainObject5(error3)) {
16817
17192
  return false;
16818
17193
  }
16819
- if (error3.name !== "HttpError" || typeof error3.message !== "string") {
17194
+ if (typeof error3.name !== "string" || typeof error3.message !== "string") {
16820
17195
  return false;
16821
17196
  }
16822
17197
  const request = error3.request;
16823
17198
  const response = error3.response;
16824
- 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");
17199
+ 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");
16825
17200
  }
16826
17201
  function hasTypedOptionalField(value, field, type2) {
16827
17202
  return !hasOwnProperty3(value, field) || typeof value[field] === type2;
@@ -16830,7 +17205,7 @@ function isNonEmptyString(value) {
16830
17205
  return typeof value === "string" && value.trim().length > 0;
16831
17206
  }
16832
17207
  function isProblemDetailsLike(body) {
16833
- if (!isPlainObject4(body)) {
17208
+ if (!isPlainObject5(body)) {
16834
17209
  return false;
16835
17210
  }
16836
17211
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -16851,11 +17226,11 @@ function isProblemDetailsLike(body) {
16851
17226
  return hasOwnNonEmptyString(body, "title") || hasOwnNonEmptyString(body, "detail");
16852
17227
  }
16853
17228
  function isGraphQLErrorEnvelopeLike(body) {
16854
- if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
17229
+ if (!isPlainObject5(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
16855
17230
  return false;
16856
17231
  }
16857
17232
  return body.errors.every((error3) => {
16858
- if (!isPlainObject4(error3) || typeof error3.message !== "string") {
17233
+ if (!isPlainObject5(error3) || typeof error3.message !== "string") {
16859
17234
  return false;
16860
17235
  }
16861
17236
  if (hasOwnProperty3(error3, "path")) {
@@ -16865,7 +17240,7 @@ function isGraphQLErrorEnvelopeLike(body) {
16865
17240
  }
16866
17241
  }
16867
17242
  if (hasOwnProperty3(error3, "extensions")) {
16868
- if (!isPlainObject4(error3.extensions)) {
17243
+ if (!isPlainObject5(error3.extensions)) {
16869
17244
  return false;
16870
17245
  }
16871
17246
  if (hasOwnProperty3(error3.extensions, "code") && typeof error3.extensions.code !== "string") {
@@ -16948,6 +17323,7 @@ function formatHttpErrorSnippet(body) {
16948
17323
  }
16949
17324
  function renderHttpError(error3, options) {
16950
17325
  const detailed = options.verbose || options.debugStackMode !== void 0;
17326
+ const summary = summarizeHttpError(error3);
16951
17327
  const lines = [
16952
17328
  styleHttpErrorLine(`Request: ${error3.request.method} ${error3.request.url}`, text.muted)
16953
17329
  ];
@@ -16974,11 +17350,27 @@ function renderHttpError(error3, options) {
16974
17350
  indentHttpErrorBlock(formatHttpErrorBody(error3.response.body))
16975
17351
  );
16976
17352
  } else {
16977
- lines.push(
16978
- "",
16979
- `Response body: ${formatHttpErrorSnippet(error3.response.body)}`,
16980
- "Re-run with --verbose to see headers and full body."
16981
- );
17353
+ const summaryLines = [
17354
+ summary.code === void 0 ? void 0 : `Code: ${summary.code}`,
17355
+ summary.message === void 0 ? void 0 : `Message: ${summary.message}`,
17356
+ summary.requestId === void 0 ? void 0 : `Request id: ${summary.requestId}`,
17357
+ summary.retryAfter === void 0 ? void 0 : `Retry after: ${summary.retryAfter}`,
17358
+ summary.hint === void 0 ? void 0 : `Hint: ${summary.hint}`
17359
+ ].filter((line) => line !== void 0);
17360
+ if (summary.fieldErrors !== void 0 && summary.fieldErrors.length > 0) {
17361
+ summaryLines.push(
17362
+ "",
17363
+ "Field errors:",
17364
+ ...summary.fieldErrors.map((fieldError) => ` ${fieldError.path}: ${fieldError.message}`)
17365
+ );
17366
+ }
17367
+ lines.push("");
17368
+ if (summaryLines.length > 0) {
17369
+ lines.push(...summaryLines);
17370
+ } else {
17371
+ lines.push(`Response body: ${formatHttpErrorSnippet(error3.response.body)}`);
17372
+ }
17373
+ lines.push("Re-run with --verbose to see headers and full body.");
16982
17374
  }
16983
17375
  process.stderr.write(`${lines.join("\n")}
16984
17376
  `);
@@ -16993,7 +17385,11 @@ async function handleRunError(error3, options) {
16993
17385
  await withOutputFormat2(options.output, async () => {
16994
17386
  if (error3 instanceof UserError) {
16995
17387
  renderCliErrorPattern(
16996
- options.userErrorPattern === "usage" ? {
17388
+ options.userErrorPattern === "definition" ? {
17389
+ kind: "definition",
17390
+ error: error3,
17391
+ debugStackMode: options.debugStackMode
17392
+ } : options.userErrorPattern === "usage" ? {
16997
17393
  kind: "usage",
16998
17394
  message: error3.message,
16999
17395
  rootUsageName: options.rootUsageName,
@@ -17231,13 +17627,23 @@ function findUnknownCommanderCommand(program, argv) {
17231
17627
  commandPath: pathSegments.join(" ")
17232
17628
  };
17233
17629
  }
17234
- if (current.commands.length === 0 || getDefaultCommanderCommandName(current) !== void 0) {
17630
+ if (current.commands.length === 0) {
17235
17631
  return void 0;
17236
17632
  }
17237
17633
  const child = current.commands.find(
17238
17634
  (command) => command.name() === token || command.aliases().includes(token)
17239
17635
  );
17240
17636
  if (child === void 0) {
17637
+ if (getDefaultCommanderCommandName(current) !== void 0) {
17638
+ if (shouldRejectDefaultCommandToken(current, token, pathSegments)) {
17639
+ return {
17640
+ input: token,
17641
+ currentCommand: current,
17642
+ commandPath: pathSegments.join(" ")
17643
+ };
17644
+ }
17645
+ return void 0;
17646
+ }
17241
17647
  return {
17242
17648
  input: token,
17243
17649
  currentCommand: current,
@@ -17249,6 +17655,36 @@ function findUnknownCommanderCommand(program, argv) {
17249
17655
  }
17250
17656
  return void 0;
17251
17657
  }
17658
+ function shouldRejectDefaultCommandToken(command, token, pathSegments) {
17659
+ return pathSegments.length === 0 && isBareCommandLikeToken(token) && hasNonDefaultPublicChildCommand(command);
17660
+ }
17661
+ function hasNonDefaultPublicChildCommand(command) {
17662
+ const defaultName = getDefaultCommanderCommandName(command);
17663
+ return command.commands.some(
17664
+ (child) => child.name() !== defaultName && !isToolcraftHiddenCommander(child) && !getToolcraftReservedChildNames(command).includes(child.name())
17665
+ );
17666
+ }
17667
+ function isBareCommandLikeToken(token) {
17668
+ if (token.length === 0) {
17669
+ return false;
17670
+ }
17671
+ for (const character of token) {
17672
+ if (!isCommandNameCharacter(character)) {
17673
+ return false;
17674
+ }
17675
+ }
17676
+ return true;
17677
+ }
17678
+ function isCommandNameCharacter(character) {
17679
+ const code = character.codePointAt(0);
17680
+ if (code === void 0) {
17681
+ return false;
17682
+ }
17683
+ const isLowercaseLetter = code >= 97 && code <= 122;
17684
+ const isUppercaseLetter = code >= 65 && code <= 90;
17685
+ const isDigit = code >= 48 && code <= 57;
17686
+ return isLowercaseLetter || isUppercaseLetter || isDigit || character === "-" || character === "_";
17687
+ }
17252
17688
  function getDefaultCommanderCommandName(command) {
17253
17689
  const candidate = command;
17254
17690
  return typeof candidate._defaultCommandName === "string" ? candidate._defaultCommandName : void 0;
@@ -17267,101 +17703,117 @@ function configureCommanderSuggestionOutput(command) {
17267
17703
  }
17268
17704
  async function runCLI(roots, options = {}) {
17269
17705
  enableSourceMaps();
17270
- const normalizedRoot = normalizeRoots(roots, process.argv);
17271
- const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17272
- await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17273
- const casing = options.casing ?? "kebab";
17274
- const services = options.services ?? {};
17275
- const runtimeOptions = options.humanInLoop ?? {};
17276
- const runtimeFetch = options.fetch ?? globalThis.fetch;
17277
- const version = options.version ?? findEntrypointPackageMetadata(process.argv[1])?.version;
17278
- const rootUsageName = options.rootUsageName ?? inferProgramName(process.argv);
17279
17706
  const controls = resolveCLIControls(options.controls);
17280
- const servicesWithBuiltIns = {
17281
- ...services,
17282
- runtimeOptions,
17283
- root
17284
- };
17285
- const requirementOptions = {
17286
- apiVersion: options.apiVersion
17287
- };
17288
- validateServices(services);
17289
- if (hasHelpFlag(process.argv)) {
17290
- await renderGeneratedHelp(root, process.argv, { ...options, version });
17291
- return;
17292
- }
17293
- const program = new CommanderCommand();
17294
- program.name(root.name);
17295
- program.exitOverride();
17296
- program.showHelpAfterError();
17297
- program.addHelpCommand(false);
17298
- const presetsEnabled = options.presets === true;
17299
- const globalLongOptionFlags = getGlobalLongOptionFlags(
17300
- presetsEnabled,
17301
- version !== void 0,
17302
- controls
17303
- );
17304
- addGlobalOptions(program, presetsEnabled, controls);
17305
- if (version !== void 0) {
17306
- program.version(version, "--version");
17307
- }
17308
- Reflect.set(
17309
- program,
17310
- "_toolcraftReservedChildNames",
17311
- root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17312
- );
17707
+ const argv = controls.verbose ? normalizeVerboseAlias([...options.argv ?? process.argv]) : [...options.argv ?? process.argv];
17708
+ const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
17313
17709
  let lastActionCommand;
17314
17710
  let resolvedCommandPath = "";
17711
+ let program;
17712
+ let version;
17713
+ let userErrorPattern = "definition";
17315
17714
  let errorReportContext;
17316
- const execute = async (state) => {
17317
- lastActionCommand = state.actionCommand;
17318
- resolvedCommandPath = formatCliCommandPath(state.commandPath);
17319
- await executeCommand(
17320
- state,
17321
- servicesWithBuiltIns,
17322
- requirementOptions,
17323
- runtimeFetch,
17715
+ try {
17716
+ const normalizedRoot = normalizeRoots(roots, argv);
17717
+ const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17718
+ await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17719
+ const casing = options.casing ?? "kebab";
17720
+ const services = options.services ?? {};
17721
+ const runtimeOptions = options.humanInLoop ?? {};
17722
+ const runtimeFetch = options.fetch ?? globalThis.fetch;
17723
+ version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
17724
+ const servicesWithBuiltIns = {
17725
+ ...services,
17324
17726
  runtimeOptions,
17325
- (context) => {
17326
- errorReportContext = context;
17327
- }
17328
- );
17329
- };
17330
- const rootChildNames = new Set(
17331
- root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17332
- );
17333
- for (const child of root.children) {
17334
- const command = createNodeCommand(
17335
- child,
17336
- casing,
17337
- globalLongOptionFlags,
17338
- execute,
17727
+ root
17728
+ };
17729
+ const requirementOptions = {
17730
+ apiVersion: options.apiVersion
17731
+ };
17732
+ validateServices(services);
17733
+ if (hasHelpFlag(argv)) {
17734
+ userErrorPattern = "usage";
17735
+ await renderGeneratedHelp(root, argv, { ...options, version });
17736
+ return;
17737
+ }
17738
+ if (argv.length <= 2 && root.default?.scope.includes("cli") !== true) {
17739
+ userErrorPattern = "usage";
17740
+ await renderGeneratedHelp(root, argv, { ...options, version });
17741
+ return;
17742
+ }
17743
+ program = new CommanderCommand();
17744
+ program.name(root.name);
17745
+ program.exitOverride();
17746
+ program.showHelpAfterError();
17747
+ program.addHelpCommand(false);
17748
+ const presetsEnabled = options.presets === true;
17749
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
17339
17750
  presetsEnabled,
17751
+ version !== void 0,
17340
17752
  controls
17341
17753
  );
17342
- if (command === null) {
17343
- continue;
17754
+ addGlobalOptions(program, presetsEnabled, controls);
17755
+ if (version !== void 0) {
17756
+ program.version(version, "--version");
17344
17757
  }
17345
- const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17346
- addCommanderChild(program, command, isDefaultChild, rootChildNames);
17347
- }
17348
- configureCommanderSuggestionOutput(program);
17349
- const unknownCommand = findUnknownCommanderCommand(program, process.argv);
17350
- if (unknownCommand !== void 0) {
17351
- createLogger().error(
17352
- appendUsagePointer(
17353
- formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17758
+ Reflect.set(
17759
+ program,
17760
+ "_toolcraftReservedChildNames",
17761
+ root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17762
+ );
17763
+ const execute = async (state) => {
17764
+ lastActionCommand = state.actionCommand;
17765
+ resolvedCommandPath = formatCliCommandPath(state.commandPath);
17766
+ await executeCommand(
17767
+ state,
17768
+ servicesWithBuiltIns,
17769
+ requirementOptions,
17770
+ runtimeFetch,
17771
+ runtimeOptions,
17354
17772
  {
17355
- rootUsageName,
17356
- commandPath: unknownCommand.commandPath
17773
+ logLevel: options.logLevel,
17774
+ logger: options.logger,
17775
+ verboseControlEnabled: controls.verbose
17776
+ },
17777
+ (context) => {
17778
+ errorReportContext = context;
17357
17779
  }
17358
- )
17780
+ );
17781
+ };
17782
+ const rootChildNames = new Set(
17783
+ root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17359
17784
  );
17360
- process.exitCode = 1;
17361
- return;
17362
- }
17363
- try {
17364
- await program.parseAsync(process.argv);
17785
+ for (const child of root.children) {
17786
+ const command = createNodeCommand(
17787
+ child,
17788
+ casing,
17789
+ globalLongOptionFlags,
17790
+ execute,
17791
+ presetsEnabled,
17792
+ controls
17793
+ );
17794
+ if (command === null) {
17795
+ continue;
17796
+ }
17797
+ const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17798
+ addCommanderChild(program, command, isDefaultChild, rootChildNames);
17799
+ }
17800
+ configureCommanderSuggestionOutput(program);
17801
+ const unknownCommand = findUnknownCommanderCommand(program, argv);
17802
+ if (unknownCommand !== void 0) {
17803
+ createLogger().error(
17804
+ appendUsagePointer(
17805
+ formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17806
+ {
17807
+ rootUsageName,
17808
+ commandPath: unknownCommand.commandPath
17809
+ }
17810
+ )
17811
+ );
17812
+ process.exitCode = 1;
17813
+ return;
17814
+ }
17815
+ userErrorPattern = "usage";
17816
+ await program.parseAsync(argv);
17365
17817
  } catch (error3) {
17366
17818
  if (error3 instanceof ApprovalDeclinedError) {
17367
17819
  renderApprovalDeclined(error3);
@@ -17369,7 +17821,7 @@ async function runCLI(roots, options = {}) {
17369
17821
  }
17370
17822
  const resolvedFlags = lastActionCommand ? getResolvedFlags(lastActionCommand) : void 0;
17371
17823
  const report = await writeErrorReport({
17372
- argv: process.argv,
17824
+ argv,
17373
17825
  command: errorReportContext?.command,
17374
17826
  commandPath: errorReportContext?.commandPath ?? resolvedCommandPath,
17375
17827
  env: process.env,
@@ -17385,14 +17837,14 @@ async function runCLI(roots, options = {}) {
17385
17837
  `);
17386
17838
  }
17387
17839
  await handleRunError(error3, {
17388
- debugStackMode: resolvedFlags !== void 0 ? resolveDebugStackMode(resolvedFlags.debug) : getDebugStackModeFromArgv(process.argv),
17389
- output: resolvedFlags !== void 0 ? resolveOutput(resolvedFlags) : resolveOutputFromArgv(process.argv),
17390
- verbose: resolvedFlags ? Boolean(resolvedFlags.verbose) : process.argv.includes("--verbose"),
17840
+ debugStackMode: resolvedFlags !== void 0 ? resolveDebugStackMode(resolvedFlags.debug) : getDebugStackModeFromArgv(argv),
17841
+ output: resolvedFlags !== void 0 ? resolveOutput(resolvedFlags) : resolveOutputFromArgv(argv),
17842
+ verbose: resolvedFlags ? Boolean(resolvedFlags.verbose) : argv.includes("--verbose"),
17391
17843
  program,
17392
- argv: process.argv,
17844
+ argv,
17393
17845
  rootUsageName,
17394
17846
  commandPath: resolvedCommandPath,
17395
- userErrorPattern: errorReportContext?.params === void 0 ? "usage" : "runtime-user"
17847
+ userErrorPattern: errorReportContext?.params === void 0 ? userErrorPattern : "runtime-user"
17396
17848
  });
17397
17849
  }
17398
17850
  }
@@ -20689,7 +21141,6 @@ import path22 from "node:path";
20689
21141
  import os3 from "node:os";
20690
21142
  import path23 from "node:path";
20691
21143
  import * as nodeFs2 from "node:fs/promises";
20692
- import { readFile as readFile7 } from "node:fs/promises";
20693
21144
  var DEFAULT_INSTALL_AGENT = "claude-code";
20694
21145
  var DEFAULT_INSTALL_SCOPE = "local";
20695
21146
  var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
@@ -20732,19 +21183,15 @@ async function loadTerminalPilotTemplate() {
20732
21183
  if (terminalPilotTemplateCache !== void 0) {
20733
21184
  return terminalPilotTemplateCache;
20734
21185
  }
20735
- const candidates = [
20736
- new URL("./templates/terminal-pilot.md", import.meta.url),
20737
- new URL("../templates/terminal-pilot.md", import.meta.url),
20738
- new URL("../../../agent-skill-config/src/templates/terminal-pilot.md", import.meta.url)
20739
- ];
20740
- for (const candidate of candidates) {
20741
- try {
20742
- terminalPilotTemplateCache = await readFile7(candidate, "utf8");
20743
- return terminalPilotTemplateCache;
20744
- } catch (error3) {
20745
- if (!isNotFoundError2(error3)) {
20746
- throw error3;
20747
- }
21186
+ try {
21187
+ terminalPilotTemplateCache = await nodeFs2.readFile(
21188
+ new URL("../templates/terminal-pilot.md", import.meta.url),
21189
+ "utf8"
21190
+ );
21191
+ return terminalPilotTemplateCache;
21192
+ } catch (error3) {
21193
+ if (!isNotFoundError2(error3)) {
21194
+ throw error3;
20748
21195
  }
20749
21196
  }
20750
21197
  throw new UserError("terminal-pilot skill template is missing.");