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
@@ -999,7 +999,7 @@ function formatColumns(opts) {
999
999
  return [`${firstIndent}${row.left}`];
1000
1000
  }
1001
1001
  const rightLines = wrapWords(row.right, rightWidth);
1002
- if (visibleWidth(row.left) > leftWidth) {
1002
+ if (visibleWidth(row.left) >= leftWidth) {
1003
1003
  return [
1004
1004
  `${firstIndent}${row.left}`,
1005
1005
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1136,7 +1136,7 @@ function formatColumns2(opts) {
1136
1136
  return [`${firstIndent}${row.left}`];
1137
1137
  }
1138
1138
  const rightLines = wrapWords2(row.right, rightWidth);
1139
- if (row.left.length > leftWidth) {
1139
+ if (row.left.length >= leftWidth) {
1140
1140
  return [
1141
1141
  `${firstIndent}${row.left}`,
1142
1142
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1956,9 +1956,9 @@ var GLYPHS = {
1956
1956
  barEnd: glyph("\u2514", "-"),
1957
1957
  radioActive: glyph("\u25CF", ">"),
1958
1958
  radioInactive: glyph("\u25CB", " "),
1959
- checkboxActive: glyph("\u25FB", "[ ]"),
1960
- checkboxSelected: glyph("\u25FC", "[+]"),
1961
- checkboxInactive: glyph("\u25FB", "[ ]"),
1959
+ checkboxActive: "[ ]",
1960
+ checkboxSelected: "[x]",
1961
+ checkboxInactive: "[ ]",
1962
1962
  passwordMask: glyph("\u2022", "*"),
1963
1963
  ellipsis: "..."
1964
1964
  };
@@ -2009,6 +2009,9 @@ function mapKey(name, char) {
2009
2009
  if (char === " ") {
2010
2010
  return "space";
2011
2011
  }
2012
+ if (char !== void 0 && aliases[char] !== void 0) {
2013
+ return aliases[char];
2014
+ }
2012
2015
  if (!name) {
2013
2016
  return void 0;
2014
2017
  }
@@ -3388,6 +3391,50 @@ var S = {
3388
3391
  Json
3389
3392
  };
3390
3393
 
3394
+ // ../toolcraft/src/runtime-logging.ts
3395
+ var LOG_LEVEL_RANK = {
3396
+ silent: 0,
3397
+ error: 1,
3398
+ warn: 2,
3399
+ info: 3,
3400
+ debug: 4,
3401
+ trace: 5
3402
+ };
3403
+ var LOG_LEVELS = Object.freeze([
3404
+ "silent",
3405
+ "error",
3406
+ "warn",
3407
+ "info",
3408
+ "debug",
3409
+ "trace"
3410
+ ]);
3411
+ function isLogLevel(value) {
3412
+ return LOG_LEVELS.includes(value);
3413
+ }
3414
+ function shouldEmitDiagnostic(eventLevel, configuredLevel) {
3415
+ if (eventLevel === "silent" || configuredLevel === "silent") {
3416
+ return false;
3417
+ }
3418
+ return LOG_LEVEL_RANK[eventLevel] <= LOG_LEVEL_RANK[configuredLevel];
3419
+ }
3420
+ function createRuntimeLogger(options = {}) {
3421
+ const level = options.level ?? "warn";
3422
+ const sink = options.logger;
3423
+ return {
3424
+ level,
3425
+ emit(event) {
3426
+ if (!shouldEmitDiagnostic(event.level, level)) {
3427
+ return;
3428
+ }
3429
+ if (typeof sink === "function") {
3430
+ sink(event);
3431
+ return;
3432
+ }
3433
+ sink?.emit(event);
3434
+ }
3435
+ };
3436
+ }
3437
+
3391
3438
  // ../toolcraft/src/package-metadata.ts
3392
3439
  import { existsSync, readFileSync, statSync } from "node:fs";
3393
3440
  import path from "node:path";
@@ -7884,14 +7931,16 @@ function getVisibleCliChildren(root) {
7884
7931
  return root.kind === "group" ? root.children.filter(isNodeVisibleInCli) : [];
7885
7932
  }
7886
7933
  function createHandlerContext(command, params17) {
7934
+ const diagnostics = createRuntimeLogger();
7887
7935
  return {
7888
7936
  params: params17,
7889
7937
  secrets: resolveCommandSecrets(command),
7890
7938
  fetch: globalThis.fetch,
7891
7939
  fs: createFs(),
7892
7940
  env: createEnv(),
7893
- progress() {
7894
- return void 0;
7941
+ diagnostics,
7942
+ progress(message2) {
7943
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
7895
7944
  }
7896
7945
  };
7897
7946
  }
@@ -7964,11 +8013,7 @@ var showParams = S.Object({
7964
8013
  approvalId: S.String()
7965
8014
  });
7966
8015
  var runParams = S.Object({
7967
- approvalId: S.String(),
7968
- dryRun: S.Optional(S.Boolean({
7969
- description: "Preview the approval without prompting or executing it",
7970
- scope: ["cli"]
7971
- }))
8016
+ approvalId: S.String()
7972
8017
  });
7973
8018
  var approvalsGroup = markApprovalsBuiltIn(
7974
8019
  defineGroup({
@@ -8025,10 +8070,6 @@ var approvalsGroup = markApprovalsBuiltIn(
8025
8070
  scope: runScope,
8026
8071
  params: runParams,
8027
8072
  handler: async ({ params: params17, runtimeOptions, root }) => {
8028
- if (params17.dryRun === true) {
8029
- const { tasks } = await ensureApprovalList(runtimeOptions, { create: false });
8030
- return tasks.get(params17.approvalId);
8031
- }
8032
8073
  return runApproval(params17.approvalId, runtimeOptions, root);
8033
8074
  },
8034
8075
  render: {
@@ -10427,7 +10468,7 @@ var McpClient = class {
10427
10468
  await onPromptsChanged();
10428
10469
  });
10429
10470
  messageLayer.onNotification("notifications/message", async (params17) => {
10430
- if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
10471
+ if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel2(params17.level)) {
10431
10472
  return;
10432
10473
  }
10433
10474
  if (!hasOwn(params17, "data")) {
@@ -11782,7 +11823,7 @@ function hasOwn(value, property) {
11782
11823
  function isRequestId(value) {
11783
11824
  return typeof value === "string" || typeof value === "number";
11784
11825
  }
11785
- function isLogLevel(value) {
11826
+ function isLogLevel2(value) {
11786
11827
  return value === "debug" || value === "info" || value === "notice" || value === "warning" || value === "error" || value === "critical" || value === "alert" || value === "emergency";
11787
11828
  }
11788
11829
  function toRequestId(value) {
@@ -13462,6 +13503,125 @@ function getExpectedNumberDescription(schema) {
13462
13503
  return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
13463
13504
  }
13464
13505
 
13506
+ // ../toolcraft/src/api-error-summary.ts
13507
+ var REQUEST_ID_FIELDS = ["request_id", "requestId", "id"];
13508
+ var CODE_FIELDS = ["code", "error_code", "errorCode", "error"];
13509
+ var MESSAGE_FIELDS = ["message", "detail", "title", "error_description"];
13510
+ function summarizeHttpError(error3) {
13511
+ const body = redactHttpBody(error3.response.body);
13512
+ const retryAfter = getHeader(error3.response.headers, "retry-after");
13513
+ const message2 = extractMessage(body);
13514
+ const summary = {
13515
+ status: error3.response.status,
13516
+ statusText: error3.response.statusText,
13517
+ requestMethod: error3.request.method,
13518
+ requestUrl: error3.request.url,
13519
+ ...message2 === void 0 ? {} : { message: message2 },
13520
+ ...optionalString("requestId", getHeader(error3.response.headers, "x-request-id") ?? extractFirstString(body, REQUEST_ID_FIELDS)),
13521
+ ...optionalString("code", extractCode(body)),
13522
+ ...optionalString("retryAfter", retryAfter),
13523
+ ...optionalArray("fieldErrors", extractFieldErrors(body)),
13524
+ ...optionalString("hint", createHttpErrorHint(error3.response.status, retryAfter))
13525
+ };
13526
+ return summary;
13527
+ }
13528
+ function createHttpErrorHint(status, retryAfter) {
13529
+ if (status === 401 || status === 403) {
13530
+ return "Check the configured API credentials and permissions.";
13531
+ }
13532
+ if ((status === 429 || status === 503) && retryAfter !== void 0) {
13533
+ return `Retry after ${retryAfter}.`;
13534
+ }
13535
+ return void 0;
13536
+ }
13537
+ function extractMessage(body) {
13538
+ if (!isPlainObject4(body)) {
13539
+ return void 0;
13540
+ }
13541
+ const graphqlMessage = extractGraphQlMessage(body);
13542
+ if (graphqlMessage !== void 0) {
13543
+ return graphqlMessage;
13544
+ }
13545
+ return extractFirstString(body, MESSAGE_FIELDS);
13546
+ }
13547
+ function extractCode(body) {
13548
+ if (!isPlainObject4(body)) {
13549
+ return void 0;
13550
+ }
13551
+ const graphqlCode = extractGraphQlCode(body);
13552
+ if (graphqlCode !== void 0) {
13553
+ return graphqlCode;
13554
+ }
13555
+ return extractFirstString(body, CODE_FIELDS);
13556
+ }
13557
+ function extractGraphQlMessage(body) {
13558
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13559
+ return isPlainObject4(first) && typeof first.message === "string" ? first.message : void 0;
13560
+ }
13561
+ function extractGraphQlCode(body) {
13562
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13563
+ if (!isPlainObject4(first) || !isPlainObject4(first.extensions)) {
13564
+ return void 0;
13565
+ }
13566
+ return typeof first.extensions.code === "string" ? first.extensions.code : void 0;
13567
+ }
13568
+ function extractFieldErrors(body) {
13569
+ if (!isPlainObject4(body)) {
13570
+ return void 0;
13571
+ }
13572
+ const candidates = [body.field_errors, body.fieldErrors, body.errors, body.non_field_errors];
13573
+ const flattened = candidates.flatMap((candidate) => flattenFieldErrors(candidate, []));
13574
+ return flattened.length === 0 ? void 0 : flattened;
13575
+ }
13576
+ function flattenFieldErrors(value, path26) {
13577
+ if (typeof value === "string") {
13578
+ return [{ path: formatPath2(path26), message: value }];
13579
+ }
13580
+ if (Array.isArray(value)) {
13581
+ if (value.every((entry) => typeof entry === "string")) {
13582
+ return value.map((message2) => ({ path: formatPath2(path26), message: message2 }));
13583
+ }
13584
+ return value.flatMap((entry, index) => flattenFieldErrors(entry, [...path26, String(index)]));
13585
+ }
13586
+ if (!isPlainObject4(value)) {
13587
+ return [];
13588
+ }
13589
+ return Object.entries(value).flatMap(([key2, nested]) => flattenFieldErrors(nested, [...path26, key2]));
13590
+ }
13591
+ function formatPath2(path26) {
13592
+ return path26.length === 0 ? "error" : path26.join(".");
13593
+ }
13594
+ function extractFirstString(body, fields) {
13595
+ if (!isPlainObject4(body)) {
13596
+ return void 0;
13597
+ }
13598
+ for (const field of fields) {
13599
+ const value = body[field];
13600
+ if (typeof value === "string" && value.length > 0) {
13601
+ return value;
13602
+ }
13603
+ }
13604
+ return void 0;
13605
+ }
13606
+ function getHeader(headers, name) {
13607
+ const lowerName = name.toLowerCase();
13608
+ for (const [key2, value] of Object.entries(headers)) {
13609
+ if (key2.toLowerCase() === lowerName && value.length > 0) {
13610
+ return value;
13611
+ }
13612
+ }
13613
+ return void 0;
13614
+ }
13615
+ function optionalString(name, value) {
13616
+ return value === void 0 ? {} : { [name]: value };
13617
+ }
13618
+ function optionalArray(name, value) {
13619
+ return value === void 0 ? {} : { [name]: value };
13620
+ }
13621
+ function isPlainObject4(value) {
13622
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13623
+ }
13624
+
13465
13625
  // ../toolcraft/src/renderer.ts
13466
13626
  import YAML from "yaml";
13467
13627
  function isObject(value) {
@@ -13509,6 +13669,9 @@ function unwrapMcpEnvelope(result) {
13509
13669
  function isArrayOfObjects(value) {
13510
13670
  return Array.isArray(value) && value.every((entry) => isObject(entry));
13511
13671
  }
13672
+ function isNonEmptyArrayOfObjects(value) {
13673
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => isObject(entry));
13674
+ }
13512
13675
  function stringifyValue2(value) {
13513
13676
  if (value === void 0) {
13514
13677
  return "";
@@ -13563,10 +13726,26 @@ function detailRows(result, depth = 0) {
13563
13726
  rows.push(...detailRows(value, depth + 1));
13564
13727
  continue;
13565
13728
  }
13729
+ if (isNonEmptyArrayOfObjects(value)) {
13730
+ rows.push({ label, value: "" });
13731
+ rows.push(...arrayObjectDetailRows(value, depth + 1));
13732
+ continue;
13733
+ }
13566
13734
  rows.push({ label, value: displayScalar(value) });
13567
13735
  }
13568
13736
  return rows;
13569
13737
  }
13738
+ function arrayObjectDetailRows(value, depth) {
13739
+ return value.flatMap((entry, index) => {
13740
+ if (value.length === 1) {
13741
+ return detailRows(entry, depth);
13742
+ }
13743
+ return [
13744
+ { label: `${" ".repeat(depth)}${index + 1}`, value: "" },
13745
+ ...detailRows(entry, depth + 1)
13746
+ ];
13747
+ });
13748
+ }
13570
13749
  function displayScalar(value) {
13571
13750
  if (typeof value === "boolean") {
13572
13751
  return value ? "Yes" : "No";
@@ -13597,17 +13776,31 @@ function directScalarRows(result) {
13597
13776
  function directObjectSections(result) {
13598
13777
  return Object.entries(result).filter(([, value]) => isObject(value)).map(([key2, value]) => ({ title: humanizeKey(key2), rows: detailRows(value) })).filter((section) => section.rows.length > 0);
13599
13778
  }
13779
+ function directArrayObjectSections(result) {
13780
+ return Object.entries(result).flatMap(([key2, value]) => {
13781
+ if (!isNonEmptyArrayOfObjects(value)) {
13782
+ return [];
13783
+ }
13784
+ const title = humanizeKey(key2);
13785
+ return value.map((entry, index) => ({
13786
+ title: value.length === 1 ? title : `${title} ${index + 1}`,
13787
+ rows: detailRows(entry)
13788
+ })).filter((section) => section.rows.length > 0);
13789
+ });
13790
+ }
13600
13791
  function renderObjectCard(result, primitives, title) {
13601
13792
  const scalarRows = directScalarRows(result);
13602
13793
  const nestedSections = directObjectSections(result);
13603
- const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13794
+ const arrayObjectSections = directArrayObjectSections(result);
13795
+ const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13604
13796
  return renderDetailCard({
13605
13797
  theme: primitives.getTheme(),
13606
13798
  title,
13607
13799
  sections: [
13608
13800
  { rows: scalarRows },
13609
13801
  ...nestedSections,
13610
- { title: "Lists", rows: listRows }
13802
+ { title: "Lists", rows: listRows },
13803
+ ...arrayObjectSections
13611
13804
  ]
13612
13805
  });
13613
13806
  }
@@ -13896,11 +14089,12 @@ var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
13896
14089
  "fetch",
13897
14090
  "fs",
13898
14091
  "env",
14092
+ "diagnostics",
13899
14093
  "progress",
13900
14094
  "runtimeOptions",
13901
14095
  "root"
13902
14096
  ]);
13903
- var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
14097
+ var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
13904
14098
  var NULL_OPTION_VALUE = /* @__PURE__ */ Symbol("toolcraft.cli.null");
13905
14099
  function inferProgramName(argv) {
13906
14100
  const entrypoint = argv[1];
@@ -14537,6 +14731,7 @@ function createOption(field, globalLongOptionFlags) {
14537
14731
  function resolveCLIControls(controls) {
14538
14732
  return {
14539
14733
  debug: controls?.debug === true,
14734
+ logLevel: controls?.logLevel === true,
14540
14735
  output: controls?.output === true,
14541
14736
  verbose: controls?.verbose === true,
14542
14737
  yes: controls?.yes === true
@@ -14556,6 +14751,9 @@ function getGlobalLongOptionFlags(presetsEnabled, versionEnabled, controls) {
14556
14751
  if (controls.debug) {
14557
14752
  flags.push("--debug");
14558
14753
  }
14754
+ if (controls.logLevel) {
14755
+ flags.push("--log-level");
14756
+ }
14559
14757
  if (controls.verbose) {
14560
14758
  flags.push("--verbose");
14561
14759
  }
@@ -14599,6 +14797,9 @@ function createCommanderOption(flags, description, field) {
14599
14797
  function hasHelpFlag(argv) {
14600
14798
  return argv.some((token) => HELP_FLAGS.has(token));
14601
14799
  }
14800
+ function normalizeVerboseAlias(argv) {
14801
+ return argv.map((token) => token === "-v" ? "--verbose" : token);
14802
+ }
14602
14803
  function resolveHelpOutput(argv) {
14603
14804
  for (let index = 0; index < argv.length; index += 1) {
14604
14805
  const token = argv[index] ?? "";
@@ -14646,7 +14847,7 @@ function findVisibleChild(group, token, scope) {
14646
14847
  (child) => child.name === token || child.aliases.includes(token)
14647
14848
  );
14648
14849
  }
14649
- function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14850
+ function resolveHelpTarget(root, argv, scope, rootUsageName, rootDisplayName) {
14650
14851
  const breadcrumb = [rootDisplayName ?? root.name];
14651
14852
  let current = root;
14652
14853
  for (const token of argv.slice(2)) {
@@ -14658,7 +14859,9 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14658
14859
  }
14659
14860
  const child = findVisibleChild(current, token, scope);
14660
14861
  if (child === void 0) {
14661
- break;
14862
+ throw new UserError(
14863
+ formatUnknownHelpCommandMessage(current, token, scope, rootUsageName, breadcrumb)
14864
+ );
14662
14865
  }
14663
14866
  breadcrumb.push(child.name);
14664
14867
  current = child;
@@ -14668,6 +14871,16 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14668
14871
  node: current
14669
14872
  };
14670
14873
  }
14874
+ function formatUnknownHelpCommandMessage(group, input, scope, rootUsageName, breadcrumb) {
14875
+ const suggestions = suggest(
14876
+ input,
14877
+ getHelpChildren(group, scope).map((child) => child.name)
14878
+ );
14879
+ const commandPath = breadcrumb.slice(1).join(" ");
14880
+ const helpTarget = commandPath.length === 0 ? rootUsageName : `${rootUsageName} ${commandPath}`;
14881
+ return `${formatSuggestionMessage(`Unknown command "${input}".`, suggestions)}
14882
+ Run ${helpTarget} --help for usage.`;
14883
+ }
14671
14884
  function formatHelpFieldFlags(field, globalLongOptionFlags) {
14672
14885
  if (field.positionalIndex !== void 0) {
14673
14886
  return formatPositionalToken(field);
@@ -15004,11 +15217,17 @@ function formatGlobalOptionsLine(ctx) {
15004
15217
  if (ctx.controls.output) {
15005
15218
  flags.push("--output <format>");
15006
15219
  }
15220
+ if (ctx.controls.verbose) {
15221
+ flags.push("-v, --verbose");
15222
+ }
15007
15223
  if (ctx.showVersion) {
15008
15224
  flags.push("--version");
15009
15225
  }
15010
15226
  return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
15011
15227
  }
15228
+ function formatLeafGlobalOptionsLine(ctx) {
15229
+ return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
15230
+ }
15012
15231
  function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
15013
15232
  const seen = /* @__PURE__ */ new Map();
15014
15233
  const visit = (node) => {
@@ -15126,6 +15345,10 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
15126
15345
  sections.push(`${text.sectionHeader("Options")}
15127
15346
  ${formatHelpOptionList(optionRows)}`);
15128
15347
  }
15348
+ const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
15349
+ if (builtInLine.length > 0) {
15350
+ sections.push(builtInLine);
15351
+ }
15129
15352
  const secretRows = formatSecretRows(command.secrets);
15130
15353
  if (secretRows.length > 0) {
15131
15354
  sections.push(
@@ -15150,6 +15373,91 @@ ${formatExampleRows(command.examples, breadcrumb, rootUsageName).join("\n")}`
15150
15373
  sections
15151
15374
  });
15152
15375
  }
15376
+ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
15377
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
15378
+ globalOptions.presetsEnabled,
15379
+ globalOptions.showVersion,
15380
+ globalOptions.controls
15381
+ );
15382
+ const node = target.node;
15383
+ if (node.kind === "group") {
15384
+ const commandRows = formatCommandRows(node, "cli", casing, globalLongOptionFlags);
15385
+ const isRoot = node === root;
15386
+ return `${JSON.stringify(
15387
+ {
15388
+ schemaVersion: 1,
15389
+ kind: "group",
15390
+ name: target.breadcrumb.at(-1) ?? rootUsageName,
15391
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15392
+ usage: buildUsageLine(
15393
+ target.breadcrumb,
15394
+ rootUsageName,
15395
+ formatGroupUsageSuffix(node, "cli", casing, globalLongOptionFlags)
15396
+ ),
15397
+ ...node.description === void 0 ? {} : { description: node.description },
15398
+ commands: commandRows.map((row) => ({ name: row.name, description: row.description })),
15399
+ options: isRoot ? collectSchemaGlobalFieldRows(node, "cli", casing, globalLongOptionFlags).map((row) => ({
15400
+ name: row.flags.split(/[ ,]+/)[0]?.replace(/^--/, "") ?? row.flags,
15401
+ flags: row.flags.split(", "),
15402
+ type: "unknown",
15403
+ description: row.description,
15404
+ required: false
15405
+ })) : []
15406
+ },
15407
+ null,
15408
+ 2
15409
+ )}
15410
+ `;
15411
+ }
15412
+ const collected = collectFields(node.params, casing, globalLongOptionFlags);
15413
+ const fields = assignPositionals(collected.fields, node.positional);
15414
+ const positionalFields = fields.filter((field) => field.positionalIndex !== void 0);
15415
+ const usageSuffix = positionalFields.length > 0 ? `[OPTIONS] ${positionalFields.map(formatPositionalToken).join(" ")}` : "[OPTIONS]";
15416
+ return `${JSON.stringify(
15417
+ {
15418
+ schemaVersion: 1,
15419
+ kind: "command",
15420
+ name: node.name,
15421
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15422
+ usage: buildUsageLine(target.breadcrumb, rootUsageName, usageSuffix),
15423
+ ...node.description === void 0 ? {} : { description: node.description },
15424
+ options: fields.filter((field) => field.global !== true).map((field) => formatJsonHelpOption(field, globalLongOptionFlags)),
15425
+ secrets: Object.entries(node.secrets).map(([name, secret]) => ({
15426
+ name,
15427
+ env: secret.env,
15428
+ required: secret.optional !== true,
15429
+ ...secret.description === void 0 ? {} : { description: secret.description }
15430
+ })),
15431
+ examples: node.examples
15432
+ },
15433
+ null,
15434
+ 2
15435
+ )}
15436
+ `;
15437
+ }
15438
+ function formatJsonHelpOption(field, globalLongOptionFlags) {
15439
+ return {
15440
+ name: field.displayPath,
15441
+ flags: formatHelpFieldFlags(field, globalLongOptionFlags).split(", "),
15442
+ type: formatJsonHelpSchemaType(field.schema),
15443
+ ...field.description === void 0 ? {} : { description: field.description },
15444
+ required: field.requiredWhenActive,
15445
+ ...field.hasDefault ? { default: field.defaultValue } : {},
15446
+ ...field.positionalIndex === void 0 ? {} : { positional: true }
15447
+ };
15448
+ }
15449
+ function formatJsonHelpSchemaType(schema) {
15450
+ if (schema.kind === "enum") {
15451
+ return "enum";
15452
+ }
15453
+ if (schema.kind === "array") {
15454
+ return "array";
15455
+ }
15456
+ if (schema.kind === "json") {
15457
+ return "json";
15458
+ }
15459
+ return schema.kind;
15460
+ }
15153
15461
  function renderHelpDocument(input) {
15154
15462
  const title = input.breadcrumb.filter((segment) => segment.length > 0).join(" ") || input.rootUsageName;
15155
15463
  const description = input.description ?? "";
@@ -15173,11 +15481,27 @@ function renderHelpDocument(input) {
15173
15481
  `;
15174
15482
  }
15175
15483
  async function renderGeneratedHelp(root, argv, options) {
15176
- const target = resolveHelpTarget(root, argv, "cli", options.rootDisplayName);
15177
15484
  const output = resolveHelpOutput(argv);
15178
15485
  const casing = options.casing ?? "kebab";
15179
15486
  const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
15487
+ const target = resolveHelpTarget(root, argv, "cli", rootUsageName, options.rootDisplayName);
15180
15488
  const controls = resolveCLIControls(options.controls);
15489
+ if (output === "json") {
15490
+ process.stdout.write(
15491
+ renderJsonHelp(
15492
+ target,
15493
+ root,
15494
+ casing,
15495
+ {
15496
+ controls,
15497
+ showVersion: options.version !== void 0,
15498
+ presetsEnabled: options.presets === true
15499
+ },
15500
+ rootUsageName
15501
+ )
15502
+ );
15503
+ return;
15504
+ }
15181
15505
  await withOutputFormat2(output, async () => {
15182
15506
  const rendered = target.node.kind === "group" ? renderGroupHelp(
15183
15507
  target.node,
@@ -15297,9 +15621,11 @@ function addCommanderChild(parent, child, isDefault, siblingNames) {
15297
15621
  parent,
15298
15622
  "_toolcraftHiddenDefaultNames",
15299
15623
  getToolcraftHiddenDefaultNames(parent).concat([
15300
- ...new Set([Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15301
- (name) => typeof name === "string" && name.length > 0
15302
- ))
15624
+ ...new Set(
15625
+ [Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15626
+ (name) => typeof name === "string" && name.length > 0
15627
+ )
15628
+ )
15303
15629
  ])
15304
15630
  );
15305
15631
  parent.addCommand(child, { hidden: true, isDefault: true });
@@ -15356,6 +15682,13 @@ function addGlobalOptions(command, presetsEnabled, controls) {
15356
15682
  new Option("--debug [mode]", "Print stack traces for unexpected errors.").preset("trim").argParser(parseDebugStackMode)
15357
15683
  );
15358
15684
  }
15685
+ if (controls.logLevel) {
15686
+ options.push(
15687
+ new Option("--log-level <level>", "Set runtime diagnostic log level.").argParser(
15688
+ parseLogLevel
15689
+ )
15690
+ );
15691
+ }
15359
15692
  if (controls.verbose) {
15360
15693
  options.push(new Option("--verbose", "Print detailed runtime diagnostics."));
15361
15694
  }
@@ -15375,6 +15708,29 @@ function parseDebugStackMode(value) {
15375
15708
  formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
15376
15709
  );
15377
15710
  }
15711
+ function parseLogLevel(value) {
15712
+ if (isLogLevel(value)) {
15713
+ return value;
15714
+ }
15715
+ throw new InvalidArgumentError(
15716
+ formatInvalidEnumMessage("--log-level", value, [...LOG_LEVELS], {
15717
+ candidates: ["warn", "debug", "trace"],
15718
+ threshold: 3
15719
+ })
15720
+ );
15721
+ }
15722
+ function writeCLIDiagnosticEvent(event) {
15723
+ const transcript = event.data?.transcript;
15724
+ if (typeof transcript === "string") {
15725
+ process.stderr.write(transcript);
15726
+ return;
15727
+ }
15728
+ if (event.category === "progress" || event.level === "trace") {
15729
+ return;
15730
+ }
15731
+ process.stderr.write(`${event.message}
15732
+ `);
15733
+ }
15378
15734
  function setNestedValue(target, path26, value) {
15379
15735
  let cursor2 = target;
15380
15736
  for (let index = 0; index < path26.length - 1; index += 1) {
@@ -15565,7 +15921,7 @@ function createEnv2(values = process.env) {
15565
15921
  }
15566
15922
  };
15567
15923
  }
15568
- function isPlainObject4(value) {
15924
+ function isPlainObject5(value) {
15569
15925
  return typeof value === "object" && value !== null && !Array.isArray(value);
15570
15926
  }
15571
15927
  function hasFieldValue(value) {
@@ -15697,7 +16053,7 @@ async function loadPresetValues(fields, presetPath) {
15697
16053
  { cause: error3 }
15698
16054
  );
15699
16055
  }
15700
- if (!isPlainObject4(parsedPreset)) {
16056
+ if (!isPlainObject5(parsedPreset)) {
15701
16057
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
15702
16058
  }
15703
16059
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
@@ -15716,7 +16072,7 @@ async function loadPresetValues(fields, presetPath) {
15716
16072
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
15717
16073
  );
15718
16074
  }
15719
- if (!isPlainObject4(value)) {
16075
+ if (!isPlainObject5(value)) {
15720
16076
  throw new UserError(
15721
16077
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
15722
16078
  );
@@ -15759,8 +16115,8 @@ function matchesFixtureValue(expected, actual) {
15759
16115
  }
15760
16116
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
15761
16117
  }
15762
- if (isPlainObject4(expected)) {
15763
- if (!isPlainObject4(actual)) {
16118
+ if (isPlainObject5(expected)) {
16119
+ if (!isPlainObject5(actual)) {
15764
16120
  return false;
15765
16121
  }
15766
16122
  return Object.entries(expected).every(
@@ -15823,9 +16179,9 @@ function createFixtureFetch(entries) {
15823
16179
  };
15824
16180
  }
15825
16181
  function createFixtureFs(definition) {
15826
- const fsDefinition = isPlainObject4(definition) ? definition : {};
15827
- const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
15828
- const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
16182
+ const fsDefinition = isPlainObject5(definition) ? definition : {};
16183
+ const readFileEntries = isPlainObject5(fsDefinition.readFile) ? fsDefinition.readFile : {};
16184
+ const existsEntries = isPlainObject5(fsDefinition.exists) ? fsDefinition.exists : {};
15829
16185
  return {
15830
16186
  readFile: async (filePath) => {
15831
16187
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -15848,10 +16204,10 @@ function createFixtureFs(definition) {
15848
16204
  function resolveFixtureMethodResult(methodName, definition, args) {
15849
16205
  if (Array.isArray(definition)) {
15850
16206
  for (const entry of definition) {
15851
- if (!isPlainObject4(entry)) {
16207
+ if (!isPlainObject5(entry)) {
15852
16208
  continue;
15853
16209
  }
15854
- const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
16210
+ const explicitMatcher = isPlainObject5(entry.request) ? entry.request : void 0;
15855
16211
  const matcher = explicitMatcher ?? Object.fromEntries(
15856
16212
  Object.entries(entry).filter(
15857
16213
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -15863,7 +16219,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15863
16219
  matched = matchesFixtureValue(matcher.args, args);
15864
16220
  } else if (Object.keys(matcher).length === 0) {
15865
16221
  matched = true;
15866
- } else if (isPlainObject4(firstArg)) {
16222
+ } else if (isPlainObject5(firstArg)) {
15867
16223
  matched = matchesFixtureValue(matcher, firstArg);
15868
16224
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
15869
16225
  const [[, expectedValue]] = Object.entries(matcher);
@@ -15884,7 +16240,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15884
16240
  return Promise.resolve(null);
15885
16241
  }
15886
16242
  }
15887
- if (isPlainObject4(definition)) {
16243
+ if (isPlainObject5(definition)) {
15888
16244
  const firstArg = args[0];
15889
16245
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
15890
16246
  return Promise.resolve(definition[firstArg]);
@@ -15896,7 +16252,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15896
16252
  return Promise.resolve(null);
15897
16253
  }
15898
16254
  function createFixtureService(definition) {
15899
- const methods = isPlainObject4(definition) ? definition : {};
16255
+ const methods = isPlainObject5(definition) ? definition : {};
15900
16256
  return new Proxy(
15901
16257
  {},
15902
16258
  {
@@ -15994,7 +16350,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions, runt
15994
16350
  };
15995
16351
  }
15996
16352
  const scenario = await loadFixtureScenario(command, selector);
15997
- const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
16353
+ const scenarioServices = isPlainObject5(scenario.services) ? scenario.services : {};
15998
16354
  const customServiceNames = /* @__PURE__ */ new Set([
15999
16355
  ...Object.keys(services),
16000
16356
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -16054,6 +16410,19 @@ function renderCliErrorPattern(pattern) {
16054
16410
  process.exitCode = 1;
16055
16411
  return;
16056
16412
  }
16413
+ if (pattern.kind === "definition") {
16414
+ logger2.error(
16415
+ `Command definition error: ${pattern.error.message}
16416
+ This is a bug in the generated command definition, not in your command arguments.
16417
+ Run with --debug for a stack trace.`
16418
+ );
16419
+ if (pattern.debugStackMode !== void 0 && pattern.error.stack) {
16420
+ process.stderr.write(`${formatDebugStack(pattern.error.stack, pattern.debugStackMode)}
16421
+ `);
16422
+ }
16423
+ process.exitCode = 1;
16424
+ return;
16425
+ }
16057
16426
  if (pattern.kind === "toolcraft-bug") {
16058
16427
  logger2.error(
16059
16428
  `toolcraft hit an internal invariant: ${pattern.error.message}
@@ -16320,7 +16689,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16320
16689
  if (itemSchema.kind !== "object") {
16321
16690
  return value;
16322
16691
  }
16323
- if (!isPlainObject4(value)) {
16692
+ if (!isPlainObject5(value)) {
16324
16693
  errors2.push({
16325
16694
  path: displayPath,
16326
16695
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -16355,7 +16724,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16355
16724
  );
16356
16725
  }
16357
16726
  case "object": {
16358
- if (!isPlainObject4(value)) {
16727
+ if (!isPlainObject5(value)) {
16359
16728
  errors2.push({
16360
16729
  path: displayPath,
16361
16730
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16386,7 +16755,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16386
16755
  return result;
16387
16756
  }
16388
16757
  case "record": {
16389
- if (!isPlainObject4(value)) {
16758
+ if (!isPlainObject5(value)) {
16390
16759
  errors2.push({
16391
16760
  path: displayPath,
16392
16761
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16716,7 +17085,7 @@ function getResolvedFlags(command) {
16716
17085
  const flags = command.optsWithGlobals();
16717
17086
  return flags;
16718
17087
  }
16719
- async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, onErrorReportContext) {
17088
+ async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, diagnosticsOptions, onErrorReportContext) {
16720
17089
  const logger2 = createLogger();
16721
17090
  const primitives = {
16722
17091
  logger: logger2,
@@ -16727,6 +17096,10 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16727
17096
  const optionValues = state.actionCommand.optsWithGlobals();
16728
17097
  const resolvedFlags = optionValues;
16729
17098
  const output = resolveOutput(resolvedFlags);
17099
+ const diagnostics = createRuntimeLogger({
17100
+ level: resolvedFlags.logLevel ?? (diagnosticsOptions.verboseControlEnabled && resolvedFlags.verbose ? "trace" : diagnosticsOptions.logLevel),
17101
+ logger: diagnosticsOptions.logger ?? writeCLIDiagnosticEvent
17102
+ });
16730
17103
  const shouldPrompt = !resolvedFlags.yes && Boolean(process.stdin.isTTY);
16731
17104
  const runtime = await resolveFixtureRuntime(
16732
17105
  state.command,
@@ -16740,7 +17113,9 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16740
17113
  fetch: runtime.fetch,
16741
17114
  fs: runtime.fs,
16742
17115
  env: runtime.env,
17116
+ diagnostics,
16743
17117
  progress(message2) {
17118
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
16744
17119
  logger2.info(message2);
16745
17120
  }
16746
17121
  };
@@ -16817,18 +17192,18 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16817
17192
  }
16818
17193
  }
16819
17194
  function isStringRecord(value) {
16820
- return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
17195
+ return isPlainObject5(value) && Object.values(value).every((entry) => typeof entry === "string");
16821
17196
  }
16822
17197
  function isHttpErrorLike(error3) {
16823
- if (!isPlainObject4(error3)) {
17198
+ if (!isPlainObject5(error3)) {
16824
17199
  return false;
16825
17200
  }
16826
- if (error3.name !== "HttpError" || typeof error3.message !== "string") {
17201
+ if (typeof error3.name !== "string" || typeof error3.message !== "string") {
16827
17202
  return false;
16828
17203
  }
16829
17204
  const request = error3.request;
16830
17205
  const response = error3.response;
16831
- 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");
17206
+ 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");
16832
17207
  }
16833
17208
  function hasTypedOptionalField(value, field, type2) {
16834
17209
  return !hasOwnProperty3(value, field) || typeof value[field] === type2;
@@ -16837,7 +17212,7 @@ function isNonEmptyString(value) {
16837
17212
  return typeof value === "string" && value.trim().length > 0;
16838
17213
  }
16839
17214
  function isProblemDetailsLike(body) {
16840
- if (!isPlainObject4(body)) {
17215
+ if (!isPlainObject5(body)) {
16841
17216
  return false;
16842
17217
  }
16843
17218
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -16858,11 +17233,11 @@ function isProblemDetailsLike(body) {
16858
17233
  return hasOwnNonEmptyString(body, "title") || hasOwnNonEmptyString(body, "detail");
16859
17234
  }
16860
17235
  function isGraphQLErrorEnvelopeLike(body) {
16861
- if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
17236
+ if (!isPlainObject5(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
16862
17237
  return false;
16863
17238
  }
16864
17239
  return body.errors.every((error3) => {
16865
- if (!isPlainObject4(error3) || typeof error3.message !== "string") {
17240
+ if (!isPlainObject5(error3) || typeof error3.message !== "string") {
16866
17241
  return false;
16867
17242
  }
16868
17243
  if (hasOwnProperty3(error3, "path")) {
@@ -16872,7 +17247,7 @@ function isGraphQLErrorEnvelopeLike(body) {
16872
17247
  }
16873
17248
  }
16874
17249
  if (hasOwnProperty3(error3, "extensions")) {
16875
- if (!isPlainObject4(error3.extensions)) {
17250
+ if (!isPlainObject5(error3.extensions)) {
16876
17251
  return false;
16877
17252
  }
16878
17253
  if (hasOwnProperty3(error3.extensions, "code") && typeof error3.extensions.code !== "string") {
@@ -16955,6 +17330,7 @@ function formatHttpErrorSnippet(body) {
16955
17330
  }
16956
17331
  function renderHttpError(error3, options) {
16957
17332
  const detailed = options.verbose || options.debugStackMode !== void 0;
17333
+ const summary = summarizeHttpError(error3);
16958
17334
  const lines = [
16959
17335
  styleHttpErrorLine(`Request: ${error3.request.method} ${error3.request.url}`, text.muted)
16960
17336
  ];
@@ -16981,11 +17357,27 @@ function renderHttpError(error3, options) {
16981
17357
  indentHttpErrorBlock(formatHttpErrorBody(error3.response.body))
16982
17358
  );
16983
17359
  } else {
16984
- lines.push(
16985
- "",
16986
- `Response body: ${formatHttpErrorSnippet(error3.response.body)}`,
16987
- "Re-run with --verbose to see headers and full body."
16988
- );
17360
+ const summaryLines = [
17361
+ summary.code === void 0 ? void 0 : `Code: ${summary.code}`,
17362
+ summary.message === void 0 ? void 0 : `Message: ${summary.message}`,
17363
+ summary.requestId === void 0 ? void 0 : `Request id: ${summary.requestId}`,
17364
+ summary.retryAfter === void 0 ? void 0 : `Retry after: ${summary.retryAfter}`,
17365
+ summary.hint === void 0 ? void 0 : `Hint: ${summary.hint}`
17366
+ ].filter((line) => line !== void 0);
17367
+ if (summary.fieldErrors !== void 0 && summary.fieldErrors.length > 0) {
17368
+ summaryLines.push(
17369
+ "",
17370
+ "Field errors:",
17371
+ ...summary.fieldErrors.map((fieldError) => ` ${fieldError.path}: ${fieldError.message}`)
17372
+ );
17373
+ }
17374
+ lines.push("");
17375
+ if (summaryLines.length > 0) {
17376
+ lines.push(...summaryLines);
17377
+ } else {
17378
+ lines.push(`Response body: ${formatHttpErrorSnippet(error3.response.body)}`);
17379
+ }
17380
+ lines.push("Re-run with --verbose to see headers and full body.");
16989
17381
  }
16990
17382
  process.stderr.write(`${lines.join("\n")}
16991
17383
  `);
@@ -17000,7 +17392,11 @@ async function handleRunError(error3, options) {
17000
17392
  await withOutputFormat2(options.output, async () => {
17001
17393
  if (error3 instanceof UserError) {
17002
17394
  renderCliErrorPattern(
17003
- options.userErrorPattern === "usage" ? {
17395
+ options.userErrorPattern === "definition" ? {
17396
+ kind: "definition",
17397
+ error: error3,
17398
+ debugStackMode: options.debugStackMode
17399
+ } : options.userErrorPattern === "usage" ? {
17004
17400
  kind: "usage",
17005
17401
  message: error3.message,
17006
17402
  rootUsageName: options.rootUsageName,
@@ -17238,13 +17634,23 @@ function findUnknownCommanderCommand(program, argv) {
17238
17634
  commandPath: pathSegments.join(" ")
17239
17635
  };
17240
17636
  }
17241
- if (current.commands.length === 0 || getDefaultCommanderCommandName(current) !== void 0) {
17637
+ if (current.commands.length === 0) {
17242
17638
  return void 0;
17243
17639
  }
17244
17640
  const child = current.commands.find(
17245
17641
  (command) => command.name() === token || command.aliases().includes(token)
17246
17642
  );
17247
17643
  if (child === void 0) {
17644
+ if (getDefaultCommanderCommandName(current) !== void 0) {
17645
+ if (shouldRejectDefaultCommandToken(current, token, pathSegments)) {
17646
+ return {
17647
+ input: token,
17648
+ currentCommand: current,
17649
+ commandPath: pathSegments.join(" ")
17650
+ };
17651
+ }
17652
+ return void 0;
17653
+ }
17248
17654
  return {
17249
17655
  input: token,
17250
17656
  currentCommand: current,
@@ -17256,6 +17662,36 @@ function findUnknownCommanderCommand(program, argv) {
17256
17662
  }
17257
17663
  return void 0;
17258
17664
  }
17665
+ function shouldRejectDefaultCommandToken(command, token, pathSegments) {
17666
+ return pathSegments.length === 0 && isBareCommandLikeToken(token) && hasNonDefaultPublicChildCommand(command);
17667
+ }
17668
+ function hasNonDefaultPublicChildCommand(command) {
17669
+ const defaultName = getDefaultCommanderCommandName(command);
17670
+ return command.commands.some(
17671
+ (child) => child.name() !== defaultName && !isToolcraftHiddenCommander(child) && !getToolcraftReservedChildNames(command).includes(child.name())
17672
+ );
17673
+ }
17674
+ function isBareCommandLikeToken(token) {
17675
+ if (token.length === 0) {
17676
+ return false;
17677
+ }
17678
+ for (const character of token) {
17679
+ if (!isCommandNameCharacter(character)) {
17680
+ return false;
17681
+ }
17682
+ }
17683
+ return true;
17684
+ }
17685
+ function isCommandNameCharacter(character) {
17686
+ const code = character.codePointAt(0);
17687
+ if (code === void 0) {
17688
+ return false;
17689
+ }
17690
+ const isLowercaseLetter = code >= 97 && code <= 122;
17691
+ const isUppercaseLetter = code >= 65 && code <= 90;
17692
+ const isDigit = code >= 48 && code <= 57;
17693
+ return isLowercaseLetter || isUppercaseLetter || isDigit || character === "-" || character === "_";
17694
+ }
17259
17695
  function getDefaultCommanderCommandName(command) {
17260
17696
  const candidate = command;
17261
17697
  return typeof candidate._defaultCommandName === "string" ? candidate._defaultCommandName : void 0;
@@ -17274,101 +17710,117 @@ function configureCommanderSuggestionOutput(command) {
17274
17710
  }
17275
17711
  async function runCLI(roots, options = {}) {
17276
17712
  enableSourceMaps();
17277
- const normalizedRoot = normalizeRoots(roots, process.argv);
17278
- const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17279
- await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17280
- const casing = options.casing ?? "kebab";
17281
- const services = options.services ?? {};
17282
- const runtimeOptions = options.humanInLoop ?? {};
17283
- const runtimeFetch = options.fetch ?? globalThis.fetch;
17284
- const version = options.version ?? findEntrypointPackageMetadata(process.argv[1])?.version;
17285
- const rootUsageName = options.rootUsageName ?? inferProgramName(process.argv);
17286
17713
  const controls = resolveCLIControls(options.controls);
17287
- const servicesWithBuiltIns = {
17288
- ...services,
17289
- runtimeOptions,
17290
- root
17291
- };
17292
- const requirementOptions = {
17293
- apiVersion: options.apiVersion
17294
- };
17295
- validateServices(services);
17296
- if (hasHelpFlag(process.argv)) {
17297
- await renderGeneratedHelp(root, process.argv, { ...options, version });
17298
- return;
17299
- }
17300
- const program = new CommanderCommand();
17301
- program.name(root.name);
17302
- program.exitOverride();
17303
- program.showHelpAfterError();
17304
- program.addHelpCommand(false);
17305
- const presetsEnabled = options.presets === true;
17306
- const globalLongOptionFlags = getGlobalLongOptionFlags(
17307
- presetsEnabled,
17308
- version !== void 0,
17309
- controls
17310
- );
17311
- addGlobalOptions(program, presetsEnabled, controls);
17312
- if (version !== void 0) {
17313
- program.version(version, "--version");
17314
- }
17315
- Reflect.set(
17316
- program,
17317
- "_toolcraftReservedChildNames",
17318
- root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17319
- );
17714
+ const argv = controls.verbose ? normalizeVerboseAlias([...options.argv ?? process.argv]) : [...options.argv ?? process.argv];
17715
+ const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
17320
17716
  let lastActionCommand;
17321
17717
  let resolvedCommandPath = "";
17718
+ let program;
17719
+ let version;
17720
+ let userErrorPattern = "definition";
17322
17721
  let errorReportContext;
17323
- const execute = async (state) => {
17324
- lastActionCommand = state.actionCommand;
17325
- resolvedCommandPath = formatCliCommandPath(state.commandPath);
17326
- await executeCommand(
17327
- state,
17328
- servicesWithBuiltIns,
17329
- requirementOptions,
17330
- runtimeFetch,
17722
+ try {
17723
+ const normalizedRoot = normalizeRoots(roots, argv);
17724
+ const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17725
+ await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17726
+ const casing = options.casing ?? "kebab";
17727
+ const services = options.services ?? {};
17728
+ const runtimeOptions = options.humanInLoop ?? {};
17729
+ const runtimeFetch = options.fetch ?? globalThis.fetch;
17730
+ version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
17731
+ const servicesWithBuiltIns = {
17732
+ ...services,
17331
17733
  runtimeOptions,
17332
- (context) => {
17333
- errorReportContext = context;
17334
- }
17335
- );
17336
- };
17337
- const rootChildNames = new Set(
17338
- root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17339
- );
17340
- for (const child of root.children) {
17341
- const command = createNodeCommand(
17342
- child,
17343
- casing,
17344
- globalLongOptionFlags,
17345
- execute,
17734
+ root
17735
+ };
17736
+ const requirementOptions = {
17737
+ apiVersion: options.apiVersion
17738
+ };
17739
+ validateServices(services);
17740
+ if (hasHelpFlag(argv)) {
17741
+ userErrorPattern = "usage";
17742
+ await renderGeneratedHelp(root, argv, { ...options, version });
17743
+ return;
17744
+ }
17745
+ if (argv.length <= 2 && root.default?.scope.includes("cli") !== true) {
17746
+ userErrorPattern = "usage";
17747
+ await renderGeneratedHelp(root, argv, { ...options, version });
17748
+ return;
17749
+ }
17750
+ program = new CommanderCommand();
17751
+ program.name(root.name);
17752
+ program.exitOverride();
17753
+ program.showHelpAfterError();
17754
+ program.addHelpCommand(false);
17755
+ const presetsEnabled = options.presets === true;
17756
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
17346
17757
  presetsEnabled,
17758
+ version !== void 0,
17347
17759
  controls
17348
17760
  );
17349
- if (command === null) {
17350
- continue;
17761
+ addGlobalOptions(program, presetsEnabled, controls);
17762
+ if (version !== void 0) {
17763
+ program.version(version, "--version");
17351
17764
  }
17352
- const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17353
- addCommanderChild(program, command, isDefaultChild, rootChildNames);
17354
- }
17355
- configureCommanderSuggestionOutput(program);
17356
- const unknownCommand = findUnknownCommanderCommand(program, process.argv);
17357
- if (unknownCommand !== void 0) {
17358
- createLogger().error(
17359
- appendUsagePointer(
17360
- formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17765
+ Reflect.set(
17766
+ program,
17767
+ "_toolcraftReservedChildNames",
17768
+ root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17769
+ );
17770
+ const execute = async (state) => {
17771
+ lastActionCommand = state.actionCommand;
17772
+ resolvedCommandPath = formatCliCommandPath(state.commandPath);
17773
+ await executeCommand(
17774
+ state,
17775
+ servicesWithBuiltIns,
17776
+ requirementOptions,
17777
+ runtimeFetch,
17778
+ runtimeOptions,
17361
17779
  {
17362
- rootUsageName,
17363
- commandPath: unknownCommand.commandPath
17780
+ logLevel: options.logLevel,
17781
+ logger: options.logger,
17782
+ verboseControlEnabled: controls.verbose
17783
+ },
17784
+ (context) => {
17785
+ errorReportContext = context;
17364
17786
  }
17365
- )
17787
+ );
17788
+ };
17789
+ const rootChildNames = new Set(
17790
+ root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17366
17791
  );
17367
- process.exitCode = 1;
17368
- return;
17369
- }
17370
- try {
17371
- await program.parseAsync(process.argv);
17792
+ for (const child of root.children) {
17793
+ const command = createNodeCommand(
17794
+ child,
17795
+ casing,
17796
+ globalLongOptionFlags,
17797
+ execute,
17798
+ presetsEnabled,
17799
+ controls
17800
+ );
17801
+ if (command === null) {
17802
+ continue;
17803
+ }
17804
+ const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17805
+ addCommanderChild(program, command, isDefaultChild, rootChildNames);
17806
+ }
17807
+ configureCommanderSuggestionOutput(program);
17808
+ const unknownCommand = findUnknownCommanderCommand(program, argv);
17809
+ if (unknownCommand !== void 0) {
17810
+ createLogger().error(
17811
+ appendUsagePointer(
17812
+ formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17813
+ {
17814
+ rootUsageName,
17815
+ commandPath: unknownCommand.commandPath
17816
+ }
17817
+ )
17818
+ );
17819
+ process.exitCode = 1;
17820
+ return;
17821
+ }
17822
+ userErrorPattern = "usage";
17823
+ await program.parseAsync(argv);
17372
17824
  } catch (error3) {
17373
17825
  if (error3 instanceof ApprovalDeclinedError) {
17374
17826
  renderApprovalDeclined(error3);
@@ -17376,7 +17828,7 @@ async function runCLI(roots, options = {}) {
17376
17828
  }
17377
17829
  const resolvedFlags = lastActionCommand ? getResolvedFlags(lastActionCommand) : void 0;
17378
17830
  const report = await writeErrorReport({
17379
- argv: process.argv,
17831
+ argv,
17380
17832
  command: errorReportContext?.command,
17381
17833
  commandPath: errorReportContext?.commandPath ?? resolvedCommandPath,
17382
17834
  env: process.env,
@@ -17392,14 +17844,14 @@ async function runCLI(roots, options = {}) {
17392
17844
  `);
17393
17845
  }
17394
17846
  await handleRunError(error3, {
17395
- debugStackMode: resolvedFlags !== void 0 ? resolveDebugStackMode(resolvedFlags.debug) : getDebugStackModeFromArgv(process.argv),
17396
- output: resolvedFlags !== void 0 ? resolveOutput(resolvedFlags) : resolveOutputFromArgv(process.argv),
17397
- verbose: resolvedFlags ? Boolean(resolvedFlags.verbose) : process.argv.includes("--verbose"),
17847
+ debugStackMode: resolvedFlags !== void 0 ? resolveDebugStackMode(resolvedFlags.debug) : getDebugStackModeFromArgv(argv),
17848
+ output: resolvedFlags !== void 0 ? resolveOutput(resolvedFlags) : resolveOutputFromArgv(argv),
17849
+ verbose: resolvedFlags ? Boolean(resolvedFlags.verbose) : argv.includes("--verbose"),
17398
17850
  program,
17399
- argv: process.argv,
17851
+ argv,
17400
17852
  rootUsageName,
17401
17853
  commandPath: resolvedCommandPath,
17402
- userErrorPattern: errorReportContext?.params === void 0 ? "usage" : "runtime-user"
17854
+ userErrorPattern: errorReportContext?.params === void 0 ? userErrorPattern : "runtime-user"
17403
17855
  });
17404
17856
  }
17405
17857
  }
@@ -20696,7 +21148,6 @@ import path22 from "node:path";
20696
21148
  import os3 from "node:os";
20697
21149
  import path23 from "node:path";
20698
21150
  import * as nodeFs2 from "node:fs/promises";
20699
- import { readFile as readFile7 } from "node:fs/promises";
20700
21151
  var DEFAULT_INSTALL_AGENT = "claude-code";
20701
21152
  var DEFAULT_INSTALL_SCOPE = "local";
20702
21153
  var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
@@ -20739,19 +21190,15 @@ async function loadTerminalPilotTemplate() {
20739
21190
  if (terminalPilotTemplateCache !== void 0) {
20740
21191
  return terminalPilotTemplateCache;
20741
21192
  }
20742
- const candidates = [
20743
- new URL("./templates/terminal-pilot.md", import.meta.url),
20744
- new URL("../templates/terminal-pilot.md", import.meta.url),
20745
- new URL("../../../agent-skill-config/src/templates/terminal-pilot.md", import.meta.url)
20746
- ];
20747
- for (const candidate of candidates) {
20748
- try {
20749
- terminalPilotTemplateCache = await readFile7(candidate, "utf8");
20750
- return terminalPilotTemplateCache;
20751
- } catch (error3) {
20752
- if (!isNotFoundError2(error3)) {
20753
- throw error3;
20754
- }
21193
+ try {
21194
+ terminalPilotTemplateCache = await nodeFs2.readFile(
21195
+ new URL("../templates/terminal-pilot.md", import.meta.url),
21196
+ "utf8"
21197
+ );
21198
+ return terminalPilotTemplateCache;
21199
+ } catch (error3) {
21200
+ if (!isNotFoundError2(error3)) {
21201
+ throw error3;
20755
21202
  }
20756
21203
  }
20757
21204
  throw new UserError("terminal-pilot skill template is missing.");