terminal-pilot 0.0.33 → 0.0.35

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 (72) hide show
  1. package/dist/cli.d.ts +4 -1
  2. package/dist/cli.js +1164 -318
  3. package/dist/cli.js.map +4 -4
  4. package/dist/commands/close-session.js +10 -0
  5. package/dist/commands/close-session.js.map +3 -3
  6. package/dist/commands/create-session.js +10 -0
  7. package/dist/commands/create-session.js.map +3 -3
  8. package/dist/commands/daemon-runtime.d.ts +4 -0
  9. package/dist/commands/daemon-runtime.js +1944 -0
  10. package/dist/commands/daemon-runtime.js.map +7 -0
  11. package/dist/commands/fill.js +10 -0
  12. package/dist/commands/fill.js.map +3 -3
  13. package/dist/commands/get-session.js +10 -0
  14. package/dist/commands/get-session.js.map +3 -3
  15. package/dist/commands/index.js +13 -3
  16. package/dist/commands/index.js.map +3 -3
  17. package/dist/commands/install.js +13 -3
  18. package/dist/commands/install.js.map +3 -3
  19. package/dist/commands/installer.js +13 -3
  20. package/dist/commands/installer.js.map +3 -3
  21. package/dist/commands/list-sessions.js +10 -0
  22. package/dist/commands/list-sessions.js.map +3 -3
  23. package/dist/commands/press-key.js +10 -0
  24. package/dist/commands/press-key.js.map +3 -3
  25. package/dist/commands/read-history.js +10 -0
  26. package/dist/commands/read-history.js.map +3 -3
  27. package/dist/commands/read-screen.js +10 -0
  28. package/dist/commands/read-screen.js.map +3 -3
  29. package/dist/commands/resize.js +10 -0
  30. package/dist/commands/resize.js.map +3 -3
  31. package/dist/commands/runtime.js +10 -0
  32. package/dist/commands/runtime.js.map +3 -3
  33. package/dist/commands/screenshot.js +10 -0
  34. package/dist/commands/screenshot.js.map +3 -3
  35. package/dist/commands/send-signal.js +10 -0
  36. package/dist/commands/send-signal.js.map +3 -3
  37. package/dist/commands/type.js +10 -0
  38. package/dist/commands/type.js.map +3 -3
  39. package/dist/commands/uninstall.js +13 -3
  40. package/dist/commands/uninstall.js.map +3 -3
  41. package/dist/commands/wait-for-exit.js +10 -0
  42. package/dist/commands/wait-for-exit.js.map +3 -3
  43. package/dist/commands/wait-for.js +10 -0
  44. package/dist/commands/wait-for.js.map +3 -3
  45. package/dist/testing/cli-repl.js +1175 -328
  46. package/dist/testing/cli-repl.js.map +4 -4
  47. package/dist/testing/qa-cli.js +1187 -340
  48. package/dist/testing/qa-cli.js.map +4 -4
  49. package/node_modules/toolcraft-design/dist/components/help-formatter-plain.js +1 -1
  50. package/node_modules/toolcraft-design/dist/components/help-formatter.js +1 -1
  51. package/node_modules/toolcraft-design/dist/components/inspector-card.d.ts +21 -0
  52. package/node_modules/toolcraft-design/dist/components/inspector-card.js +42 -0
  53. package/node_modules/toolcraft-design/dist/components/resource-browser.d.ts +21 -0
  54. package/node_modules/toolcraft-design/dist/components/resource-browser.js +98 -0
  55. package/node_modules/toolcraft-design/dist/explorer/index.d.ts +2 -0
  56. package/node_modules/toolcraft-design/dist/explorer/index.js +1 -0
  57. package/node_modules/toolcraft-design/dist/explorer/layout.js +5 -3
  58. package/node_modules/toolcraft-design/dist/explorer/reducer.js +22 -6
  59. package/node_modules/toolcraft-design/dist/explorer/render/detail.js +19 -6
  60. package/node_modules/toolcraft-design/dist/explorer/render/list.js +28 -9
  61. package/node_modules/toolcraft-design/dist/explorer/render/pane.d.ts +5 -0
  62. package/node_modules/toolcraft-design/dist/explorer/render/pane.js +30 -0
  63. package/node_modules/toolcraft-design/dist/explorer/runtime.js +22 -4
  64. package/node_modules/toolcraft-design/dist/explorer/two-pane.d.ts +102 -0
  65. package/node_modules/toolcraft-design/dist/explorer/two-pane.js +510 -0
  66. package/node_modules/toolcraft-design/dist/index.d.ts +6 -2
  67. package/node_modules/toolcraft-design/dist/index.js +3 -1
  68. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.d.ts +3 -3
  69. package/node_modules/toolcraft-design/dist/prompts/interactive/glyphs.js +3 -3
  70. package/node_modules/toolcraft-design/dist/prompts/interactive/keys.js +3 -0
  71. package/node_modules/toolcraft-design/dist/prompts/interactive/multiselect.js +8 -4
  72. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ var __export = (target, all) => {
7
7
 
8
8
  // src/cli.ts
9
9
  import { realpath as realpath3 } from "node:fs/promises";
10
- import path24 from "node:path";
10
+ import path25 from "node:path";
11
11
  import { fileURLToPath as fileURLToPath5 } from "node:url";
12
12
 
13
13
  // ../toolcraft/src/cli.ts
@@ -920,7 +920,7 @@ function formatColumns(opts) {
920
920
  return [`${firstIndent}${row.left}`];
921
921
  }
922
922
  const rightLines = wrapWords(row.right, rightWidth);
923
- if (visibleWidth(row.left) > leftWidth) {
923
+ if (visibleWidth(row.left) >= leftWidth) {
924
924
  return [
925
925
  `${firstIndent}${row.left}`,
926
926
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1057,7 +1057,7 @@ function formatColumns2(opts) {
1057
1057
  return [`${firstIndent}${row.left}`];
1058
1058
  }
1059
1059
  const rightLines = wrapWords2(row.right, rightWidth);
1060
- if (row.left.length > leftWidth) {
1060
+ if (row.left.length >= leftWidth) {
1061
1061
  return [
1062
1062
  `${firstIndent}${row.left}`,
1063
1063
  ...rightLines.map((line) => `${continuationIndent}${line}`)
@@ -1877,9 +1877,9 @@ var GLYPHS = {
1877
1877
  barEnd: glyph("\u2514", "-"),
1878
1878
  radioActive: glyph("\u25CF", ">"),
1879
1879
  radioInactive: glyph("\u25CB", " "),
1880
- checkboxActive: glyph("\u25FB", "[ ]"),
1881
- checkboxSelected: glyph("\u25FC", "[+]"),
1882
- checkboxInactive: glyph("\u25FB", "[ ]"),
1880
+ checkboxActive: "[ ]",
1881
+ checkboxSelected: "[x]",
1882
+ checkboxInactive: "[ ]",
1883
1883
  passwordMask: glyph("\u2022", "*"),
1884
1884
  ellipsis: "..."
1885
1885
  };
@@ -1930,6 +1930,9 @@ function mapKey(name, char) {
1930
1930
  if (char === " ") {
1931
1931
  return "space";
1932
1932
  }
1933
+ if (char !== void 0 && aliases[char] !== void 0) {
1934
+ return aliases[char];
1935
+ }
1933
1936
  if (!name) {
1934
1937
  return void 0;
1935
1938
  }
@@ -2743,17 +2746,17 @@ function validate(schema, value) {
2743
2746
  }
2744
2747
  return { ok: true, value: result.present ? result.value : void 0 };
2745
2748
  }
2746
- function walkSchema(schema, value, path25, state) {
2749
+ function walkSchema(schema, value, path26, state) {
2747
2750
  if (schema.kind === "optional") {
2748
- return walkOptional(schema, value, path25, state);
2751
+ return walkOptional(schema, value, path26, state);
2749
2752
  }
2750
2753
  if (value === missingValue) {
2751
2754
  addIssue(
2752
2755
  state,
2753
- path25,
2756
+ path26,
2754
2757
  expectedFor(schema),
2755
2758
  "missing",
2756
- `Expected ${expectedFor(schema)} at ${formatPath(path25)}`
2759
+ `Expected ${expectedFor(schema)} at ${formatPath(path26)}`
2757
2760
  );
2758
2761
  return { present: false };
2759
2762
  }
@@ -2762,149 +2765,149 @@ function walkSchema(schema, value, path25, state) {
2762
2765
  }
2763
2766
  switch (schema.kind) {
2764
2767
  case "string":
2765
- return walkString(schema, value, path25, state);
2768
+ return walkString(schema, value, path26, state);
2766
2769
  case "number":
2767
- return walkNumber(schema, value, path25, state);
2770
+ return walkNumber(schema, value, path26, state);
2768
2771
  case "boolean":
2769
- return walkBoolean(value, path25, state);
2772
+ return walkBoolean(value, path26, state);
2770
2773
  case "enum":
2771
- return walkEnum(schema, value, path25, state);
2774
+ return walkEnum(schema, value, path26, state);
2772
2775
  case "array":
2773
- return walkArray(schema, value, path25, state);
2776
+ return walkArray(schema, value, path26, state);
2774
2777
  case "object":
2775
- return walkObject(schema, value, path25, state);
2778
+ return walkObject(schema, value, path26, state);
2776
2779
  case "oneOf":
2777
- return walkOneOf(schema, value, path25, state);
2780
+ return walkOneOf(schema, value, path26, state);
2778
2781
  case "union":
2779
- return walkUnion(schema, value, path25, state);
2782
+ return walkUnion(schema, value, path26, state);
2780
2783
  case "record":
2781
- return walkRecord(schema, value, path25, state);
2784
+ return walkRecord(schema, value, path26, state);
2782
2785
  case "json":
2783
- return walkJson(value, path25, state);
2786
+ return walkJson(value, path26, state);
2784
2787
  }
2785
2788
  }
2786
- function walkOptional(schema, value, path25, state) {
2789
+ function walkOptional(schema, value, path26, state) {
2787
2790
  if (value === missingValue || value === void 0) {
2788
2791
  const defaultValue = getDefault(schema.inner);
2789
2792
  if (defaultValue.present) {
2790
- return walkSchema(schema.inner, cloneDefault(defaultValue.value), path25, state);
2793
+ return walkSchema(schema.inner, cloneDefault(defaultValue.value), path26, state);
2791
2794
  }
2792
2795
  return { present: false };
2793
2796
  }
2794
- return walkSchema(schema.inner, value, path25, state);
2797
+ return walkSchema(schema.inner, value, path26, state);
2795
2798
  }
2796
- function walkString(schema, value, path25, state) {
2799
+ function walkString(schema, value, path26, state) {
2797
2800
  if (typeof value !== "string") {
2798
- addExpectedIssue(state, path25, "string", value);
2801
+ addExpectedIssue(state, path26, "string", value);
2799
2802
  return { present: true, value };
2800
2803
  }
2801
2804
  if (schema.minLength !== void 0 && value.length < schema.minLength) {
2802
2805
  const expected = `string with length at least ${schema.minLength}`;
2803
2806
  addIssue(
2804
2807
  state,
2805
- path25,
2808
+ path26,
2806
2809
  expected,
2807
2810
  `string with length ${value.length}`,
2808
- `Expected ${expected} at ${formatPath(path25)}`
2811
+ `Expected ${expected} at ${formatPath(path26)}`
2809
2812
  );
2810
2813
  }
2811
2814
  if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
2812
2815
  const expected = `string with length at most ${schema.maxLength}`;
2813
2816
  addIssue(
2814
2817
  state,
2815
- path25,
2818
+ path26,
2816
2819
  expected,
2817
2820
  `string with length ${value.length}`,
2818
- `Expected ${expected} at ${formatPath(path25)}`
2821
+ `Expected ${expected} at ${formatPath(path26)}`
2819
2822
  );
2820
2823
  }
2821
2824
  if (schema.pattern !== void 0) {
2822
2825
  const pattern = compilePattern(schema.pattern);
2823
2826
  if (pattern === void 0 || !pattern.test(value)) {
2824
2827
  const expected = `string matching pattern ${schema.pattern}`;
2825
- addIssue(state, path25, expected, value, `Expected ${expected} at ${formatPath(path25)}`);
2828
+ addIssue(state, path26, expected, value, `Expected ${expected} at ${formatPath(path26)}`);
2826
2829
  }
2827
2830
  }
2828
2831
  return { present: true, value };
2829
2832
  }
2830
- function walkNumber(schema, value, path25, state) {
2833
+ function walkNumber(schema, value, path26, state) {
2831
2834
  if (typeof value !== "number" || !Number.isFinite(value)) {
2832
- addExpectedIssue(state, path25, schema.jsonType === "integer" ? "integer" : "number", value);
2835
+ addExpectedIssue(state, path26, schema.jsonType === "integer" ? "integer" : "number", value);
2833
2836
  return { present: true, value };
2834
2837
  }
2835
2838
  if (schema.jsonType === "integer" && !Number.isInteger(value)) {
2836
- addExpectedIssue(state, path25, "integer", value);
2839
+ addExpectedIssue(state, path26, "integer", value);
2837
2840
  }
2838
2841
  if (schema.minimum !== void 0 && value < schema.minimum) {
2839
2842
  const expected = `number greater than or equal to ${schema.minimum}`;
2840
- addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
2843
+ addIssue(state, path26, expected, String(value), `Expected ${expected} at ${formatPath(path26)}`);
2841
2844
  }
2842
2845
  if (schema.maximum !== void 0 && value > schema.maximum) {
2843
2846
  const expected = `number less than or equal to ${schema.maximum}`;
2844
- addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
2847
+ addIssue(state, path26, expected, String(value), `Expected ${expected} at ${formatPath(path26)}`);
2845
2848
  }
2846
2849
  return { present: true, value };
2847
2850
  }
2848
- function walkBoolean(value, path25, state) {
2851
+ function walkBoolean(value, path26, state) {
2849
2852
  if (typeof value !== "boolean") {
2850
- addExpectedIssue(state, path25, "boolean", value);
2853
+ addExpectedIssue(state, path26, "boolean", value);
2851
2854
  }
2852
2855
  return { present: true, value };
2853
2856
  }
2854
- function walkEnum(schema, value, path25, state) {
2857
+ function walkEnum(schema, value, path26, state) {
2855
2858
  if (!schema.values.includes(value)) {
2856
2859
  const expected = `one of ${schema.values.join(", ")}`;
2857
2860
  addIssue(
2858
2861
  state,
2859
- path25,
2862
+ path26,
2860
2863
  expected,
2861
2864
  receivedValue(value),
2862
- `Expected ${expected} at ${formatPath(path25)}`
2865
+ `Expected ${expected} at ${formatPath(path26)}`
2863
2866
  );
2864
2867
  }
2865
2868
  return { present: true, value };
2866
2869
  }
2867
- function walkArray(schema, value, path25, state) {
2870
+ function walkArray(schema, value, path26, state) {
2868
2871
  if (!Array.isArray(value)) {
2869
- addExpectedIssue(state, path25, "array", value);
2872
+ addExpectedIssue(state, path26, "array", value);
2870
2873
  return { present: true, value };
2871
2874
  }
2872
2875
  if (schema.minItems !== void 0 && value.length < schema.minItems) {
2873
2876
  const expected = `array with at least ${schema.minItems} items`;
2874
2877
  addIssue(
2875
2878
  state,
2876
- path25,
2879
+ path26,
2877
2880
  expected,
2878
2881
  `array with ${value.length} items`,
2879
- `Expected ${expected} at ${formatPath(path25)}`
2882
+ `Expected ${expected} at ${formatPath(path26)}`
2880
2883
  );
2881
2884
  }
2882
2885
  if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
2883
2886
  const expected = `array with at most ${schema.maxItems} items`;
2884
2887
  addIssue(
2885
2888
  state,
2886
- path25,
2889
+ path26,
2887
2890
  expected,
2888
2891
  `array with ${value.length} items`,
2889
- `Expected ${expected} at ${formatPath(path25)}`
2892
+ `Expected ${expected} at ${formatPath(path26)}`
2890
2893
  );
2891
2894
  }
2892
2895
  const nextValue = value.map((item, index) => {
2893
- const result = walkSchema(schema.item, item, [...path25, String(index)], state);
2896
+ const result = walkSchema(schema.item, item, [...path26, String(index)], state);
2894
2897
  return result.present ? result.value : item;
2895
2898
  });
2896
2899
  return { present: true, value: nextValue };
2897
2900
  }
2898
- function walkObject(schema, value, path25, state, injectedProperties = {}) {
2901
+ function walkObject(schema, value, path26, state, injectedProperties = {}) {
2899
2902
  if (!isPlainRecord(value)) {
2900
- addExpectedIssue(state, path25, "object", value);
2903
+ addExpectedIssue(state, path26, "object", value);
2901
2904
  return { present: true, value };
2902
2905
  }
2903
2906
  const nextValue = {};
2904
2907
  const allowedKeys = /* @__PURE__ */ new Set([...Object.keys(schema.shape), ...Object.keys(injectedProperties)]);
2905
2908
  for (const [key2, propertySchema] of Object.entries(schema.shape)) {
2906
2909
  const propertyValue = Object.hasOwn(value, key2) ? value[key2] : missingValue;
2907
- const result = walkSchema(propertySchema, propertyValue, [...path25, key2], state);
2910
+ const result = walkSchema(propertySchema, propertyValue, [...path26, key2], state);
2908
2911
  if (result.present) {
2909
2912
  setOwnValue(nextValue, key2, result.value);
2910
2913
  }
@@ -2923,18 +2926,18 @@ function walkObject(schema, value, path25, state, injectedProperties = {}) {
2923
2926
  if (schema.additionalProperties === true) {
2924
2927
  setOwnValue(nextValue, key2, propertyValue);
2925
2928
  } else {
2926
- addUnexpectedPropertyIssue(state, [...path25, key2]);
2929
+ addUnexpectedPropertyIssue(state, [...path26, key2]);
2927
2930
  }
2928
2931
  }
2929
2932
  return { present: true, value: nextValue };
2930
2933
  }
2931
- function walkOneOf(schema, value, path25, state) {
2934
+ function walkOneOf(schema, value, path26, state) {
2932
2935
  if (!isPlainRecord(value)) {
2933
- addExpectedIssue(state, path25, "object", value);
2936
+ addExpectedIssue(state, path26, "object", value);
2934
2937
  return { present: true, value };
2935
2938
  }
2936
2939
  const discriminatorValue = value[schema.discriminator];
2937
- const discriminatorPath = [...path25, schema.discriminator];
2940
+ const discriminatorPath = [...path26, schema.discriminator];
2938
2941
  const branchValues = Object.keys(schema.branches);
2939
2942
  const expected = `one of ${branchValues.join(", ")}`;
2940
2943
  if (!Object.hasOwn(value, schema.discriminator)) {
@@ -2943,7 +2946,7 @@ function walkOneOf(schema, value, path25, state) {
2943
2946
  discriminatorPath,
2944
2947
  expected,
2945
2948
  "missing",
2946
- `Missing discriminator "${schema.discriminator}" at ${formatPath(path25)}. Expected one of: ${branchValues.join(", ")}.`
2949
+ `Missing discriminator "${schema.discriminator}" at ${formatPath(path26)}. Expected one of: ${branchValues.join(", ")}.`
2947
2950
  );
2948
2951
  return { present: true, value };
2949
2952
  }
@@ -2957,21 +2960,21 @@ function walkOneOf(schema, value, path25, state) {
2957
2960
  );
2958
2961
  return { present: true, value };
2959
2962
  }
2960
- return walkObject(schema.branches[discriminatorValue], value, path25, state, {
2963
+ return walkObject(schema.branches[discriminatorValue], value, path26, state, {
2961
2964
  [schema.discriminator]: discriminatorValue
2962
2965
  });
2963
2966
  }
2964
- function walkUnion(schema, value, path25, state) {
2967
+ function walkUnion(schema, value, path26, state) {
2965
2968
  if (isPlainRecord(value)) {
2966
2969
  const candidateBranches = schema.branches.filter((branch) => hasRequiredKeys(branch, value));
2967
2970
  if (candidateBranches.length === 1) {
2968
- return walkObject(candidateBranches[0], value, path25, state);
2971
+ return walkObject(candidateBranches[0], value, path26, state);
2969
2972
  }
2970
2973
  }
2971
2974
  const matches = [];
2972
2975
  for (const branch of schema.branches) {
2973
2976
  const branchState = { issues: [] };
2974
- const result = walkObject(branch, value, path25, branchState);
2977
+ const result = walkObject(branch, value, path26, branchState);
2975
2978
  if (branchState.issues.length === 0 && result.present) {
2976
2979
  matches.push({ fingerprint: getRequiredKeyFingerprint(branch), value: result.value });
2977
2980
  }
@@ -2983,19 +2986,19 @@ function walkUnion(schema, value, path25, state) {
2983
2986
  const branchDescriptions = schema.branches.map((branch) => getRequiredKeyFingerprint(branch));
2984
2987
  addIssueWithMessage(
2985
2988
  state,
2986
- path25,
2989
+ path26,
2987
2990
  "exactly one union branch",
2988
2991
  "0 matching branches",
2989
- `No union branch matched at ${formatPath(path25)}. Tried ${schema.branches.length} branches. Expected one of: ${branchDescriptions.join(" | ")}.`
2992
+ `No union branch matched at ${formatPath(path26)}. Tried ${schema.branches.length} branches. Expected one of: ${branchDescriptions.join(" | ")}.`
2990
2993
  );
2991
2994
  return { present: true, value };
2992
2995
  }
2993
2996
  addIssueWithMessage(
2994
2997
  state,
2995
- path25,
2998
+ path26,
2996
2999
  "exactly one union branch",
2997
3000
  `${matches.length} matching branches`,
2998
- `Expected exactly one union branch at ${formatPath(path25)}, but matched more than one branch: ${matches.map((match) => match.fingerprint).join(" | ")}`
3001
+ `Expected exactly one union branch at ${formatPath(path26)}, but matched more than one branch: ${matches.map((match) => match.fingerprint).join(" | ")}`
2999
3002
  );
3000
3003
  return { present: true, value };
3001
3004
  }
@@ -3007,25 +3010,25 @@ function hasRequiredKeys(schema, value) {
3007
3010
  }
3008
3011
  return true;
3009
3012
  }
3010
- function walkRecord(schema, value, path25, state) {
3013
+ function walkRecord(schema, value, path26, state) {
3011
3014
  if (!isPlainRecord(value)) {
3012
- addExpectedIssue(state, path25, "object", value);
3015
+ addExpectedIssue(state, path26, "object", value);
3013
3016
  return { present: true, value };
3014
3017
  }
3015
3018
  const nextValue = {};
3016
3019
  for (const [key2, propertyValue] of Object.entries(value)) {
3017
- const result = walkSchema(schema.value, propertyValue, [...path25, key2], state);
3020
+ const result = walkSchema(schema.value, propertyValue, [...path26, key2], state);
3018
3021
  if (result.present) {
3019
3022
  setOwnValue(nextValue, key2, result.value);
3020
3023
  }
3021
3024
  }
3022
3025
  return { present: true, value: nextValue };
3023
3026
  }
3024
- function walkJson(value, path25, state) {
3027
+ function walkJson(value, path26, state) {
3025
3028
  if (isJsonValue(value)) {
3026
3029
  return { present: true, value };
3027
3030
  }
3028
- addExpectedIssue(state, path25, "JSON value", value);
3031
+ addExpectedIssue(state, path26, "JSON value", value);
3029
3032
  return { present: true, value };
3030
3033
  }
3031
3034
  function getDefault(schema) {
@@ -3103,45 +3106,45 @@ function expectedFor(schema) {
3103
3106
  return expectedFor(schema.inner);
3104
3107
  }
3105
3108
  }
3106
- function addExpectedIssue(state, path25, expected, value) {
3109
+ function addExpectedIssue(state, path26, expected, value) {
3107
3110
  addIssue(
3108
3111
  state,
3109
- path25,
3112
+ path26,
3110
3113
  expected,
3111
3114
  receivedType(value),
3112
- `Expected ${expected} at ${formatPath(path25)}`
3115
+ `Expected ${expected} at ${formatPath(path26)}`
3113
3116
  );
3114
3117
  }
3115
- function addUnexpectedPropertyIssue(state, path25) {
3118
+ function addUnexpectedPropertyIssue(state, path26) {
3116
3119
  addIssue(
3117
3120
  state,
3118
- path25,
3121
+ path26,
3119
3122
  "no additional properties",
3120
3123
  "unknown property",
3121
- `Unexpected property ${formatPath(path25)}`
3124
+ `Unexpected property ${formatPath(path26)}`
3122
3125
  );
3123
3126
  }
3124
- function addIssue(state, path25, expected, received, _message) {
3127
+ function addIssue(state, path26, expected, received, _message) {
3125
3128
  state.issues.push({
3126
- path: path25,
3129
+ path: path26,
3127
3130
  expected,
3128
3131
  received,
3129
- message: formatIssueMessage(expected, path25, received)
3132
+ message: formatIssueMessage(expected, path26, received)
3130
3133
  });
3131
3134
  }
3132
- function addIssueWithMessage(state, path25, expected, received, message2) {
3135
+ function addIssueWithMessage(state, path26, expected, received, message2) {
3133
3136
  state.issues.push({
3134
- path: path25,
3137
+ path: path26,
3135
3138
  expected,
3136
3139
  received,
3137
3140
  message: message2
3138
3141
  });
3139
3142
  }
3140
- function formatIssueMessage(expected, path25, received) {
3141
- return `Expected ${expected} at ${formatPath(path25)}, got ${received}`;
3143
+ function formatIssueMessage(expected, path26, received) {
3144
+ return `Expected ${expected} at ${formatPath(path26)}, got ${received}`;
3142
3145
  }
3143
- function formatPath(path25) {
3144
- return path25.length === 0 ? "value" : path25.join(".");
3146
+ function formatPath(path26) {
3147
+ return path26.length === 0 ? "value" : path26.join(".");
3145
3148
  }
3146
3149
  function compilePattern(pattern) {
3147
3150
  try {
@@ -3309,6 +3312,50 @@ var S = {
3309
3312
  Json
3310
3313
  };
3311
3314
 
3315
+ // ../toolcraft/src/runtime-logging.ts
3316
+ var LOG_LEVEL_RANK = {
3317
+ silent: 0,
3318
+ error: 1,
3319
+ warn: 2,
3320
+ info: 3,
3321
+ debug: 4,
3322
+ trace: 5
3323
+ };
3324
+ var LOG_LEVELS = Object.freeze([
3325
+ "silent",
3326
+ "error",
3327
+ "warn",
3328
+ "info",
3329
+ "debug",
3330
+ "trace"
3331
+ ]);
3332
+ function isLogLevel(value) {
3333
+ return LOG_LEVELS.includes(value);
3334
+ }
3335
+ function shouldEmitDiagnostic(eventLevel, configuredLevel) {
3336
+ if (eventLevel === "silent" || configuredLevel === "silent") {
3337
+ return false;
3338
+ }
3339
+ return LOG_LEVEL_RANK[eventLevel] <= LOG_LEVEL_RANK[configuredLevel];
3340
+ }
3341
+ function createRuntimeLogger(options = {}) {
3342
+ const level = options.level ?? "warn";
3343
+ const sink = options.logger;
3344
+ return {
3345
+ level,
3346
+ emit(event) {
3347
+ if (!shouldEmitDiagnostic(event.level, level)) {
3348
+ return;
3349
+ }
3350
+ if (typeof sink === "function") {
3351
+ sink(event);
3352
+ return;
3353
+ }
3354
+ sink?.emit(event);
3355
+ }
3356
+ };
3357
+ }
3358
+
3312
3359
  // ../toolcraft/src/package-metadata.ts
3313
3360
  import { existsSync, readFileSync, statSync } from "node:fs";
3314
3361
  import path from "node:path";
@@ -7777,13 +7824,13 @@ function formatAvailableApprovalCommandPaths(root) {
7777
7824
  }
7778
7825
  function enumerateApprovalCommandPaths(root) {
7779
7826
  const paths = [];
7780
- const visit = (node, path25) => {
7827
+ const visit = (node, path26) => {
7781
7828
  if (node.kind === "command") {
7782
- paths.push(path25.join("."));
7829
+ paths.push(path26.join("."));
7783
7830
  return;
7784
7831
  }
7785
7832
  for (const child of getVisibleCliChildren(node)) {
7786
- visit(child, [...path25, child.name]);
7833
+ visit(child, [...path26, child.name]);
7787
7834
  }
7788
7835
  };
7789
7836
  if (root.kind === "command") {
@@ -7805,34 +7852,36 @@ function getVisibleCliChildren(root) {
7805
7852
  return root.kind === "group" ? root.children.filter(isNodeVisibleInCli) : [];
7806
7853
  }
7807
7854
  function createHandlerContext(command, params17) {
7855
+ const diagnostics = createRuntimeLogger();
7808
7856
  return {
7809
7857
  params: params17,
7810
7858
  secrets: resolveCommandSecrets(command),
7811
7859
  fetch: globalThis.fetch,
7812
7860
  fs: createFs(),
7813
7861
  env: createEnv(),
7814
- progress() {
7815
- return void 0;
7862
+ diagnostics,
7863
+ progress(message2) {
7864
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
7816
7865
  }
7817
7866
  };
7818
7867
  }
7819
7868
  function createFs() {
7820
7869
  return {
7821
- readFile: async (path25, encoding = "utf8") => readFile3(path25, { encoding }),
7822
- writeFile: async (path25, contents, options) => {
7823
- await writeFile2(path25, contents, options);
7870
+ readFile: async (path26, encoding = "utf8") => readFile3(path26, { encoding }),
7871
+ writeFile: async (path26, contents, options) => {
7872
+ await writeFile2(path26, contents, options);
7824
7873
  },
7825
- exists: async (path25) => {
7874
+ exists: async (path26) => {
7826
7875
  try {
7827
- await access(path25);
7876
+ await access(path26);
7828
7877
  return true;
7829
7878
  } catch {
7830
7879
  return false;
7831
7880
  }
7832
7881
  },
7833
- lstat: async (path25) => lstat(path25),
7882
+ lstat: async (path26) => lstat(path26),
7834
7883
  rename: async (fromPath, toPath) => rename(fromPath, toPath),
7835
- unlink: async (path25) => unlink(path25)
7884
+ unlink: async (path26) => unlink(path26)
7836
7885
  };
7837
7886
  }
7838
7887
  function createEnv(values = process.env) {
@@ -7885,11 +7934,7 @@ var showParams = S.Object({
7885
7934
  approvalId: S.String()
7886
7935
  });
7887
7936
  var runParams = S.Object({
7888
- approvalId: S.String(),
7889
- dryRun: S.Optional(S.Boolean({
7890
- description: "Preview the approval without prompting or executing it",
7891
- scope: ["cli"]
7892
- }))
7937
+ approvalId: S.String()
7893
7938
  });
7894
7939
  var approvalsGroup = markApprovalsBuiltIn(
7895
7940
  defineGroup({
@@ -7946,10 +7991,6 @@ var approvalsGroup = markApprovalsBuiltIn(
7946
7991
  scope: runScope,
7947
7992
  params: runParams,
7948
7993
  handler: async ({ params: params17, runtimeOptions, root }) => {
7949
- if (params17.dryRun === true) {
7950
- const { tasks } = await ensureApprovalList(runtimeOptions, { create: false });
7951
- return tasks.get(params17.approvalId);
7952
- }
7953
7994
  return runApproval(params17.approvalId, runtimeOptions, root);
7954
7995
  },
7955
7996
  render: {
@@ -10348,7 +10389,7 @@ var McpClient = class {
10348
10389
  await onPromptsChanged();
10349
10390
  });
10350
10391
  messageLayer.onNotification("notifications/message", async (params17) => {
10351
- if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
10392
+ if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel2(params17.level)) {
10352
10393
  return;
10353
10394
  }
10354
10395
  if (!hasOwn(params17, "data")) {
@@ -11703,7 +11744,7 @@ function hasOwn(value, property) {
11703
11744
  function isRequestId(value) {
11704
11745
  return typeof value === "string" || typeof value === "number";
11705
11746
  }
11706
- function isLogLevel(value) {
11747
+ function isLogLevel2(value) {
11707
11748
  return value === "debug" || value === "info" || value === "notice" || value === "warning" || value === "error" || value === "critical" || value === "alert" || value === "emergency";
11708
11749
  }
11709
11750
  function toRequestId(value) {
@@ -11835,13 +11876,13 @@ function convertJsonSchema(schema) {
11835
11876
  }
11836
11877
  return convertSchema(schema, schema, []);
11837
11878
  }
11838
- function convertSchema(schema, root, path25) {
11839
- const resolvedSchema = resolveReferencedSchema(schema, root, path25);
11879
+ function convertSchema(schema, root, path26) {
11880
+ const resolvedSchema = resolveReferencedSchema(schema, root, path26);
11840
11881
  const normalizedSchema = normalizeNullability(resolvedSchema);
11841
11882
  const composition = getComposition(normalizedSchema.schema);
11842
11883
  if (Array.isArray(normalizedSchema.schema.type)) {
11843
11884
  throw new Error(
11844
- `JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
11885
+ `JSON Schema "${formatJsonSchemaPath(path26)}" has an unsupported type "${formatJsonSchemaType(
11845
11886
  normalizedSchema.schema.type
11846
11887
  )}". Supported: string, number, integer, boolean, array, object.`
11847
11888
  );
@@ -11853,13 +11894,13 @@ function convertSchema(schema, root, path25) {
11853
11894
  return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
11854
11895
  }
11855
11896
  if (composition !== void 0) {
11856
- return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path25);
11897
+ return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path26);
11857
11898
  }
11858
11899
  if (isRecordSchema(normalizedSchema.schema)) {
11859
11900
  return applyMetadata(
11860
11901
  S.Record(
11861
11902
  convertSchema(normalizedSchema.schema.additionalProperties, root, [
11862
- ...path25,
11903
+ ...path26,
11863
11904
  "additionalProperties"
11864
11905
  ])
11865
11906
  ),
@@ -11908,12 +11949,12 @@ function convertSchema(schema, root, path25) {
11908
11949
  if (normalizedSchema.schema.items === void 0) {
11909
11950
  throw new Error(
11910
11951
  `JSON Schema "${formatJsonSchemaPath(
11911
- path25
11952
+ path26
11912
11953
  )}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
11913
11954
  );
11914
11955
  }
11915
11956
  return S.Array(
11916
- convertSchema(normalizedSchema.schema.items, root, [...path25, "items"]),
11957
+ convertSchema(normalizedSchema.schema.items, root, [...path26, "items"]),
11917
11958
  createCommonOptions(
11918
11959
  normalizedSchema.schema,
11919
11960
  normalizedSchema.nullable,
@@ -11923,7 +11964,7 @@ function convertSchema(schema, root, path25) {
11923
11964
  case "object":
11924
11965
  return convertObjectSchema(normalizedSchema.schema, root, {
11925
11966
  nullable: normalizedSchema.nullable,
11926
- path: path25
11967
+ path: path26
11927
11968
  });
11928
11969
  case "null":
11929
11970
  return applyMetadata(S.Json(), normalizedSchema.schema, {
@@ -11938,12 +11979,12 @@ function convertSchema(schema, root, path25) {
11938
11979
  }
11939
11980
  throw new Error(
11940
11981
  `JSON Schema "${formatJsonSchemaPath(
11941
- path25
11982
+ path26
11942
11983
  )}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
11943
11984
  );
11944
11985
  }
11945
11986
  throw new Error(
11946
- `JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
11987
+ `JSON Schema "${formatJsonSchemaPath(path26)}" has an unsupported type "${formatJsonSchemaType(
11947
11988
  normalizedSchema.schema.type
11948
11989
  )}". Supported: string, number, integer, boolean, array, object.`
11949
11990
  );
@@ -11987,21 +12028,21 @@ function convertEnumSchema(schema, nullable) {
11987
12028
  )
11988
12029
  });
11989
12030
  }
11990
- function convertCompositionSchema(schema, root, nullable, path25) {
12031
+ function convertCompositionSchema(schema, root, nullable, path26) {
11991
12032
  const composition = getComposition(schema);
11992
12033
  const branchSchemas = composition?.branches ?? [];
11993
12034
  const keyword = composition?.keyword ?? "oneOf";
11994
12035
  const branches = branchSchemas.map(
11995
- (branch, index) => resolveReferencedSchema(branch, root, [...path25, keyword, String(index)])
12036
+ (branch, index) => resolveReferencedSchema(branch, root, [...path26, keyword, String(index)])
11996
12037
  );
11997
- const discriminator = findDiscriminator(branches, root, path25);
12038
+ const discriminator = findDiscriminator(branches, root, path26);
11998
12039
  if (discriminator !== void 0) {
11999
12040
  const convertedBranches = Object.fromEntries(
12000
12041
  branches.map((branch, index) => [
12001
12042
  getDiscriminatorLiteral(branch, discriminator, root),
12002
12043
  convertObjectSchema(branch, root, {
12003
12044
  omitProperty: discriminator,
12004
- path: [...path25, keyword, String(index)]
12045
+ path: [...path26, keyword, String(index)]
12005
12046
  })
12006
12047
  ])
12007
12048
  );
@@ -12020,7 +12061,7 @@ function convertCompositionSchema(schema, root, nullable, path25) {
12020
12061
  S.Union(
12021
12062
  branches.map(
12022
12063
  (branch, index) => convertObjectSchema(branch, root, {
12023
- path: [...path25, keyword, String(index)]
12064
+ path: [...path26, keyword, String(index)]
12024
12065
  })
12025
12066
  )
12026
12067
  ),
@@ -12134,11 +12175,11 @@ function getComposition(schema) {
12134
12175
  }
12135
12176
  return void 0;
12136
12177
  }
12137
- function formatJsonSchemaPath(path25) {
12138
- if (path25.length === 0) {
12178
+ function formatJsonSchemaPath(path26) {
12179
+ if (path26.length === 0) {
12139
12180
  return "#";
12140
12181
  }
12141
- return `#/${path25.map(escapeJsonPointerSegment).join("/")}`;
12182
+ return `#/${path26.map(escapeJsonPointerSegment).join("/")}`;
12142
12183
  }
12143
12184
  function formatJsonSchemaType(type2) {
12144
12185
  return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
@@ -12154,11 +12195,11 @@ function isRecordSchema(schema) {
12154
12195
  const propertyKeys = Object.keys(schema.properties ?? {});
12155
12196
  return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
12156
12197
  }
12157
- function findDiscriminator(branches, root, path25) {
12198
+ function findDiscriminator(branches, root, path26) {
12158
12199
  const [firstBranch] = branches;
12159
12200
  if (firstBranch === void 0) {
12160
12201
  throw new Error(
12161
- `JSON Schema "${formatJsonSchemaPath(path25)}" uses oneOf/anyOf/allOf but has no branches.`
12202
+ `JSON Schema "${formatJsonSchemaPath(path26)}" uses oneOf/anyOf/allOf but has no branches.`
12162
12203
  );
12163
12204
  }
12164
12205
  const candidateKeys = Object.keys(firstBranch.properties ?? {});
@@ -12198,19 +12239,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
12198
12239
  }
12199
12240
  return void 0;
12200
12241
  }
12201
- function resolveReferencedSchema(schema, root, path25) {
12242
+ function resolveReferencedSchema(schema, root, path26) {
12202
12243
  if (schema.$ref === void 0) {
12203
12244
  return schema;
12204
12245
  }
12205
12246
  const resolvedTarget = resolveLocalRef(root, schema.$ref);
12206
12247
  if (resolvedTarget === void 0) {
12207
12248
  throw new Error(
12208
- `JSON Schema "${formatJsonSchemaPath(path25)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
12249
+ `JSON Schema "${formatJsonSchemaPath(path26)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
12209
12250
  );
12210
12251
  }
12211
12252
  const { $ref: ignoredRef, ...siblingKeywords } = schema;
12212
12253
  void ignoredRef;
12213
- const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path25);
12254
+ const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path26);
12214
12255
  if (Object.keys(siblingKeywords).length === 0) {
12215
12256
  return resolvedSchema;
12216
12257
  }
@@ -12234,9 +12275,9 @@ function mergeJsonSchemas(base, overlay) {
12234
12275
  ...mergedRequired === void 0 ? {} : { required: mergedRequired }
12235
12276
  };
12236
12277
  }
12237
- function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__PURE__ */ new Set()) {
12278
+ function hasSelfReferencingRef(schema, root, path26 = "#", activePaths = /* @__PURE__ */ new Set()) {
12238
12279
  const nextActivePaths = new Set(activePaths);
12239
- nextActivePaths.add(path25);
12280
+ nextActivePaths.add(path26);
12240
12281
  const localRefPath = getLocalRefPath(schema.$ref);
12241
12282
  if (localRefPath !== void 0) {
12242
12283
  if (nextActivePaths.has(localRefPath)) {
@@ -12247,13 +12288,13 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
12247
12288
  return true;
12248
12289
  }
12249
12290
  }
12250
- if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path25}/items`, nextActivePaths)) {
12291
+ if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path26}/items`, nextActivePaths)) {
12251
12292
  return true;
12252
12293
  }
12253
12294
  if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
12254
12295
  schema.additionalProperties,
12255
12296
  root,
12256
- `${path25}/additionalProperties`,
12297
+ `${path26}/additionalProperties`,
12257
12298
  nextActivePaths
12258
12299
  )) {
12259
12300
  return true;
@@ -12262,7 +12303,7 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
12262
12303
  if (hasSelfReferencingRef(
12263
12304
  childSchema,
12264
12305
  root,
12265
- `${path25}/properties/${escapeJsonPointerSegment(key2)}`,
12306
+ `${path26}/properties/${escapeJsonPointerSegment(key2)}`,
12266
12307
  nextActivePaths
12267
12308
  )) {
12268
12309
  return true;
@@ -12272,24 +12313,24 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
12272
12313
  if (hasSelfReferencingRef(
12273
12314
  childSchema,
12274
12315
  root,
12275
- `${path25}/$defs/${escapeJsonPointerSegment(key2)}`,
12316
+ `${path26}/$defs/${escapeJsonPointerSegment(key2)}`,
12276
12317
  nextActivePaths
12277
12318
  )) {
12278
12319
  return true;
12279
12320
  }
12280
12321
  }
12281
12322
  for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
12282
- if (hasSelfReferencingRef(childSchema, root, `${path25}/oneOf/${index}`, nextActivePaths)) {
12323
+ if (hasSelfReferencingRef(childSchema, root, `${path26}/oneOf/${index}`, nextActivePaths)) {
12283
12324
  return true;
12284
12325
  }
12285
12326
  }
12286
12327
  for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
12287
- if (hasSelfReferencingRef(childSchema, root, `${path25}/anyOf/${index}`, nextActivePaths)) {
12328
+ if (hasSelfReferencingRef(childSchema, root, `${path26}/anyOf/${index}`, nextActivePaths)) {
12288
12329
  return true;
12289
12330
  }
12290
12331
  }
12291
12332
  for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
12292
- if (hasSelfReferencingRef(childSchema, root, `${path25}/allOf/${index}`, nextActivePaths)) {
12333
+ if (hasSelfReferencingRef(childSchema, root, `${path26}/allOf/${index}`, nextActivePaths)) {
12293
12334
  return true;
12294
12335
  }
12295
12336
  }
@@ -12305,14 +12346,14 @@ function getLocalRefPath(ref) {
12305
12346
  return ref.startsWith("#/") ? ref : void 0;
12306
12347
  }
12307
12348
  function resolveLocalRef(root, ref) {
12308
- const path25 = getLocalRefPath(ref);
12309
- if (path25 === void 0) {
12349
+ const path26 = getLocalRefPath(ref);
12350
+ if (path26 === void 0) {
12310
12351
  return void 0;
12311
12352
  }
12312
- if (path25 === "#") {
12353
+ if (path26 === "#") {
12313
12354
  return root;
12314
12355
  }
12315
- const segments = path25.slice(2).split("/").map(unescapeJsonPointerSegment);
12356
+ const segments = path26.slice(2).split("/").map(unescapeJsonPointerSegment);
12316
12357
  let current = root;
12317
12358
  for (const segment of segments) {
12318
12359
  if (Array.isArray(current)) {
@@ -13383,6 +13424,125 @@ function getExpectedNumberDescription(schema) {
13383
13424
  return bounds.length === 0 ? type2 : `${type2} ${bounds.join(" and ")}`;
13384
13425
  }
13385
13426
 
13427
+ // ../toolcraft/src/api-error-summary.ts
13428
+ var REQUEST_ID_FIELDS = ["request_id", "requestId", "id"];
13429
+ var CODE_FIELDS = ["code", "error_code", "errorCode", "error"];
13430
+ var MESSAGE_FIELDS = ["message", "detail", "title", "error_description"];
13431
+ function summarizeHttpError(error3) {
13432
+ const body = redactHttpBody(error3.response.body);
13433
+ const retryAfter = getHeader(error3.response.headers, "retry-after");
13434
+ const message2 = extractMessage(body);
13435
+ const summary = {
13436
+ status: error3.response.status,
13437
+ statusText: error3.response.statusText,
13438
+ requestMethod: error3.request.method,
13439
+ requestUrl: error3.request.url,
13440
+ ...message2 === void 0 ? {} : { message: message2 },
13441
+ ...optionalString("requestId", getHeader(error3.response.headers, "x-request-id") ?? extractFirstString(body, REQUEST_ID_FIELDS)),
13442
+ ...optionalString("code", extractCode(body)),
13443
+ ...optionalString("retryAfter", retryAfter),
13444
+ ...optionalArray("fieldErrors", extractFieldErrors(body)),
13445
+ ...optionalString("hint", createHttpErrorHint(error3.response.status, retryAfter))
13446
+ };
13447
+ return summary;
13448
+ }
13449
+ function createHttpErrorHint(status, retryAfter) {
13450
+ if (status === 401 || status === 403) {
13451
+ return "Check the configured API credentials and permissions.";
13452
+ }
13453
+ if ((status === 429 || status === 503) && retryAfter !== void 0) {
13454
+ return `Retry after ${retryAfter}.`;
13455
+ }
13456
+ return void 0;
13457
+ }
13458
+ function extractMessage(body) {
13459
+ if (!isPlainObject4(body)) {
13460
+ return void 0;
13461
+ }
13462
+ const graphqlMessage = extractGraphQlMessage(body);
13463
+ if (graphqlMessage !== void 0) {
13464
+ return graphqlMessage;
13465
+ }
13466
+ return extractFirstString(body, MESSAGE_FIELDS);
13467
+ }
13468
+ function extractCode(body) {
13469
+ if (!isPlainObject4(body)) {
13470
+ return void 0;
13471
+ }
13472
+ const graphqlCode = extractGraphQlCode(body);
13473
+ if (graphqlCode !== void 0) {
13474
+ return graphqlCode;
13475
+ }
13476
+ return extractFirstString(body, CODE_FIELDS);
13477
+ }
13478
+ function extractGraphQlMessage(body) {
13479
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13480
+ return isPlainObject4(first) && typeof first.message === "string" ? first.message : void 0;
13481
+ }
13482
+ function extractGraphQlCode(body) {
13483
+ const [first] = Array.isArray(body.errors) ? body.errors : [];
13484
+ if (!isPlainObject4(first) || !isPlainObject4(first.extensions)) {
13485
+ return void 0;
13486
+ }
13487
+ return typeof first.extensions.code === "string" ? first.extensions.code : void 0;
13488
+ }
13489
+ function extractFieldErrors(body) {
13490
+ if (!isPlainObject4(body)) {
13491
+ return void 0;
13492
+ }
13493
+ const candidates = [body.field_errors, body.fieldErrors, body.errors, body.non_field_errors];
13494
+ const flattened = candidates.flatMap((candidate) => flattenFieldErrors(candidate, []));
13495
+ return flattened.length === 0 ? void 0 : flattened;
13496
+ }
13497
+ function flattenFieldErrors(value, path26) {
13498
+ if (typeof value === "string") {
13499
+ return [{ path: formatPath2(path26), message: value }];
13500
+ }
13501
+ if (Array.isArray(value)) {
13502
+ if (value.every((entry) => typeof entry === "string")) {
13503
+ return value.map((message2) => ({ path: formatPath2(path26), message: message2 }));
13504
+ }
13505
+ return value.flatMap((entry, index) => flattenFieldErrors(entry, [...path26, String(index)]));
13506
+ }
13507
+ if (!isPlainObject4(value)) {
13508
+ return [];
13509
+ }
13510
+ return Object.entries(value).flatMap(([key2, nested]) => flattenFieldErrors(nested, [...path26, key2]));
13511
+ }
13512
+ function formatPath2(path26) {
13513
+ return path26.length === 0 ? "error" : path26.join(".");
13514
+ }
13515
+ function extractFirstString(body, fields) {
13516
+ if (!isPlainObject4(body)) {
13517
+ return void 0;
13518
+ }
13519
+ for (const field of fields) {
13520
+ const value = body[field];
13521
+ if (typeof value === "string" && value.length > 0) {
13522
+ return value;
13523
+ }
13524
+ }
13525
+ return void 0;
13526
+ }
13527
+ function getHeader(headers, name) {
13528
+ const lowerName = name.toLowerCase();
13529
+ for (const [key2, value] of Object.entries(headers)) {
13530
+ if (key2.toLowerCase() === lowerName && value.length > 0) {
13531
+ return value;
13532
+ }
13533
+ }
13534
+ return void 0;
13535
+ }
13536
+ function optionalString(name, value) {
13537
+ return value === void 0 ? {} : { [name]: value };
13538
+ }
13539
+ function optionalArray(name, value) {
13540
+ return value === void 0 ? {} : { [name]: value };
13541
+ }
13542
+ function isPlainObject4(value) {
13543
+ return typeof value === "object" && value !== null && !Array.isArray(value);
13544
+ }
13545
+
13386
13546
  // ../toolcraft/src/renderer.ts
13387
13547
  import YAML from "yaml";
13388
13548
  function isObject(value) {
@@ -13430,6 +13590,9 @@ function unwrapMcpEnvelope(result) {
13430
13590
  function isArrayOfObjects(value) {
13431
13591
  return Array.isArray(value) && value.every((entry) => isObject(entry));
13432
13592
  }
13593
+ function isNonEmptyArrayOfObjects(value) {
13594
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => isObject(entry));
13595
+ }
13433
13596
  function stringifyValue2(value) {
13434
13597
  if (value === void 0) {
13435
13598
  return "";
@@ -13484,10 +13647,26 @@ function detailRows(result, depth = 0) {
13484
13647
  rows.push(...detailRows(value, depth + 1));
13485
13648
  continue;
13486
13649
  }
13650
+ if (isNonEmptyArrayOfObjects(value)) {
13651
+ rows.push({ label, value: "" });
13652
+ rows.push(...arrayObjectDetailRows(value, depth + 1));
13653
+ continue;
13654
+ }
13487
13655
  rows.push({ label, value: displayScalar(value) });
13488
13656
  }
13489
13657
  return rows;
13490
13658
  }
13659
+ function arrayObjectDetailRows(value, depth) {
13660
+ return value.flatMap((entry, index) => {
13661
+ if (value.length === 1) {
13662
+ return detailRows(entry, depth);
13663
+ }
13664
+ return [
13665
+ { label: `${" ".repeat(depth)}${index + 1}`, value: "" },
13666
+ ...detailRows(entry, depth + 1)
13667
+ ];
13668
+ });
13669
+ }
13491
13670
  function displayScalar(value) {
13492
13671
  if (typeof value === "boolean") {
13493
13672
  return value ? "Yes" : "No";
@@ -13518,17 +13697,31 @@ function directScalarRows(result) {
13518
13697
  function directObjectSections(result) {
13519
13698
  return Object.entries(result).filter(([, value]) => isObject(value)).map(([key2, value]) => ({ title: humanizeKey(key2), rows: detailRows(value) })).filter((section) => section.rows.length > 0);
13520
13699
  }
13700
+ function directArrayObjectSections(result) {
13701
+ return Object.entries(result).flatMap(([key2, value]) => {
13702
+ if (!isNonEmptyArrayOfObjects(value)) {
13703
+ return [];
13704
+ }
13705
+ const title = humanizeKey(key2);
13706
+ return value.map((entry, index) => ({
13707
+ title: value.length === 1 ? title : `${title} ${index + 1}`,
13708
+ rows: detailRows(entry)
13709
+ })).filter((section) => section.rows.length > 0);
13710
+ });
13711
+ }
13521
13712
  function renderObjectCard(result, primitives, title) {
13522
13713
  const scalarRows = directScalarRows(result);
13523
13714
  const nestedSections = directObjectSections(result);
13524
- const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13715
+ const arrayObjectSections = directArrayObjectSections(result);
13716
+ const listRows = Object.entries(result).filter(([, value]) => Array.isArray(value) && !isNonEmptyArrayOfObjects(value)).map(([key2, value]) => ({ label: humanizeKey(key2), value: displayScalar(value) }));
13525
13717
  return renderDetailCard({
13526
13718
  theme: primitives.getTheme(),
13527
13719
  title,
13528
13720
  sections: [
13529
13721
  { rows: scalarRows },
13530
13722
  ...nestedSections,
13531
- { title: "Lists", rows: listRows }
13723
+ { title: "Lists", rows: listRows },
13724
+ ...arrayObjectSections
13532
13725
  ]
13533
13726
  });
13534
13727
  }
@@ -13817,11 +14010,12 @@ var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
13817
14010
  "fetch",
13818
14011
  "fs",
13819
14012
  "env",
14013
+ "diagnostics",
13820
14014
  "progress",
13821
14015
  "runtimeOptions",
13822
14016
  "root"
13823
14017
  ]);
13824
- var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
14018
+ var RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
13825
14019
  var NULL_OPTION_VALUE = /* @__PURE__ */ Symbol("toolcraft.cli.null");
13826
14020
  function inferProgramName(argv) {
13827
14021
  const entrypoint = argv[1];
@@ -13886,11 +14080,11 @@ function formatSegment(segment, casing) {
13886
14080
  const separator = casing === "snake" ? "_" : "-";
13887
14081
  return splitWords3(segment).join(separator);
13888
14082
  }
13889
- function toOptionFlag(path25, casing) {
13890
- return `--${path25.map((segment) => formatSegment(segment, casing)).join(".")}`;
14083
+ function toOptionFlag(path26, casing) {
14084
+ return `--${path26.map((segment) => formatSegment(segment, casing)).join(".")}`;
13891
14085
  }
13892
- function toOptionAttribute(path25, casing) {
13893
- return path25.map((segment) => {
14086
+ function toOptionAttribute(path26, casing) {
14087
+ return path26.map((segment) => {
13894
14088
  const formatted = formatSegment(segment, casing);
13895
14089
  if (casing === "snake") {
13896
14090
  return formatted;
@@ -13901,23 +14095,23 @@ function toOptionAttribute(path25, casing) {
13901
14095
  ).join("");
13902
14096
  }).join(".");
13903
14097
  }
13904
- function toDisplayPath(path25) {
13905
- return path25.join(".");
14098
+ function toDisplayPath(path26) {
14099
+ return path26.join(".");
13906
14100
  }
13907
- function toUnionKindControlPath(path25) {
13908
- if (path25.length === 0) {
14101
+ function toUnionKindControlPath(path26) {
14102
+ if (path26.length === 0) {
13909
14103
  return ["kind"];
13910
14104
  }
13911
- const head = path25.slice(0, -1);
13912
- const tail = path25[path25.length - 1] ?? "";
14105
+ const head = path26.slice(0, -1);
14106
+ const tail = path26[path26.length - 1] ?? "";
13913
14107
  return [...head, `${tail}Kind`];
13914
14108
  }
13915
- function toUnionKindDisplayPath(path25) {
13916
- if (path25.length === 0) {
14109
+ function toUnionKindDisplayPath(path26) {
14110
+ if (path26.length === 0) {
13917
14111
  return "kind";
13918
14112
  }
13919
- const head = path25.slice(0, -1);
13920
- const tail = path25[path25.length - 1] ?? "";
14113
+ const head = path26.slice(0, -1);
14114
+ const tail = path26[path26.length - 1] ?? "";
13921
14115
  return [...head, `${tail}-kind`].join(".");
13922
14116
  }
13923
14117
  function createSyntheticEnumSchema(values) {
@@ -13933,14 +14127,14 @@ function getRequiredBranchFingerprint(branch, casing) {
13933
14127
  const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
13934
14128
  return requiredKeys.join("+");
13935
14129
  }
13936
- function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inheritedOptional = false, variantContext) {
14130
+ function collectFields(schema, casing, globalLongOptionFlags, path26 = [], inheritedOptional = false, variantContext) {
13937
14131
  const collected = {
13938
14132
  dynamicFields: [],
13939
14133
  fields: [],
13940
14134
  variants: []
13941
14135
  };
13942
14136
  for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
13943
- const nextPath = [...path25, key2];
14137
+ const nextPath = [...path26, key2];
13944
14138
  const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
13945
14139
  const childSchema = unwrapOptional2(rawChildSchema);
13946
14140
  const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
@@ -14126,9 +14320,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inher
14126
14320
  }
14127
14321
  return collected;
14128
14322
  }
14129
- function toCommanderOptionAttribute(path25, casing, globalLongOptionFlags) {
14130
- const optionAttribute = toOptionAttribute(path25, casing);
14131
- const optionFlag = toOptionFlag(path25, casing);
14323
+ function toCommanderOptionAttribute(path26, casing, globalLongOptionFlags) {
14324
+ const optionAttribute = toOptionAttribute(path26, casing);
14325
+ const optionFlag = toOptionFlag(path26, casing);
14132
14326
  if (!globalLongOptionFlags.has(optionFlag)) {
14133
14327
  return optionAttribute;
14134
14328
  }
@@ -14458,6 +14652,7 @@ function createOption(field, globalLongOptionFlags) {
14458
14652
  function resolveCLIControls(controls) {
14459
14653
  return {
14460
14654
  debug: controls?.debug === true,
14655
+ logLevel: controls?.logLevel === true,
14461
14656
  output: controls?.output === true,
14462
14657
  verbose: controls?.verbose === true,
14463
14658
  yes: controls?.yes === true
@@ -14477,6 +14672,9 @@ function getGlobalLongOptionFlags(presetsEnabled, versionEnabled, controls) {
14477
14672
  if (controls.debug) {
14478
14673
  flags.push("--debug");
14479
14674
  }
14675
+ if (controls.logLevel) {
14676
+ flags.push("--log-level");
14677
+ }
14480
14678
  if (controls.verbose) {
14481
14679
  flags.push("--verbose");
14482
14680
  }
@@ -14520,6 +14718,9 @@ function createCommanderOption(flags, description, field) {
14520
14718
  function hasHelpFlag(argv) {
14521
14719
  return argv.some((token) => HELP_FLAGS.has(token));
14522
14720
  }
14721
+ function normalizeVerboseAlias(argv) {
14722
+ return argv.map((token) => token === "-v" ? "--verbose" : token);
14723
+ }
14523
14724
  function resolveHelpOutput(argv) {
14524
14725
  for (let index = 0; index < argv.length; index += 1) {
14525
14726
  const token = argv[index] ?? "";
@@ -14567,7 +14768,7 @@ function findVisibleChild(group, token, scope) {
14567
14768
  (child) => child.name === token || child.aliases.includes(token)
14568
14769
  );
14569
14770
  }
14570
- function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14771
+ function resolveHelpTarget(root, argv, scope, rootUsageName, rootDisplayName) {
14571
14772
  const breadcrumb = [rootDisplayName ?? root.name];
14572
14773
  let current = root;
14573
14774
  for (const token of argv.slice(2)) {
@@ -14579,7 +14780,9 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14579
14780
  }
14580
14781
  const child = findVisibleChild(current, token, scope);
14581
14782
  if (child === void 0) {
14582
- break;
14783
+ throw new UserError(
14784
+ formatUnknownHelpCommandMessage(current, token, scope, rootUsageName, breadcrumb)
14785
+ );
14583
14786
  }
14584
14787
  breadcrumb.push(child.name);
14585
14788
  current = child;
@@ -14589,6 +14792,16 @@ function resolveHelpTarget(root, argv, scope, rootDisplayName) {
14589
14792
  node: current
14590
14793
  };
14591
14794
  }
14795
+ function formatUnknownHelpCommandMessage(group, input, scope, rootUsageName, breadcrumb) {
14796
+ const suggestions = suggest(
14797
+ input,
14798
+ getHelpChildren(group, scope).map((child) => child.name)
14799
+ );
14800
+ const commandPath = breadcrumb.slice(1).join(" ");
14801
+ const helpTarget = commandPath.length === 0 ? rootUsageName : `${rootUsageName} ${commandPath}`;
14802
+ return `${formatSuggestionMessage(`Unknown command "${input}".`, suggestions)}
14803
+ Run ${helpTarget} --help for usage.`;
14804
+ }
14592
14805
  function formatHelpFieldFlags(field, globalLongOptionFlags) {
14593
14806
  if (field.positionalIndex !== void 0) {
14594
14807
  return formatPositionalToken(field);
@@ -14925,11 +15138,17 @@ function formatGlobalOptionsLine(ctx) {
14925
15138
  if (ctx.controls.output) {
14926
15139
  flags.push("--output <format>");
14927
15140
  }
15141
+ if (ctx.controls.verbose) {
15142
+ flags.push("-v, --verbose");
15143
+ }
14928
15144
  if (ctx.showVersion) {
14929
15145
  flags.push("--version");
14930
15146
  }
14931
15147
  return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
14932
15148
  }
15149
+ function formatLeafGlobalOptionsLine(ctx) {
15150
+ return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
15151
+ }
14933
15152
  function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
14934
15153
  const seen = /* @__PURE__ */ new Map();
14935
15154
  const visit = (node) => {
@@ -15047,6 +15266,10 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
15047
15266
  sections.push(`${text.sectionHeader("Options")}
15048
15267
  ${formatHelpOptionList(optionRows)}`);
15049
15268
  }
15269
+ const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
15270
+ if (builtInLine.length > 0) {
15271
+ sections.push(builtInLine);
15272
+ }
15050
15273
  const secretRows = formatSecretRows(command.secrets);
15051
15274
  if (secretRows.length > 0) {
15052
15275
  sections.push(
@@ -15071,6 +15294,91 @@ ${formatExampleRows(command.examples, breadcrumb, rootUsageName).join("\n")}`
15071
15294
  sections
15072
15295
  });
15073
15296
  }
15297
+ function renderJsonHelp(target, root, casing, globalOptions, rootUsageName) {
15298
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
15299
+ globalOptions.presetsEnabled,
15300
+ globalOptions.showVersion,
15301
+ globalOptions.controls
15302
+ );
15303
+ const node = target.node;
15304
+ if (node.kind === "group") {
15305
+ const commandRows = formatCommandRows(node, "cli", casing, globalLongOptionFlags);
15306
+ const isRoot = node === root;
15307
+ return `${JSON.stringify(
15308
+ {
15309
+ schemaVersion: 1,
15310
+ kind: "group",
15311
+ name: target.breadcrumb.at(-1) ?? rootUsageName,
15312
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15313
+ usage: buildUsageLine(
15314
+ target.breadcrumb,
15315
+ rootUsageName,
15316
+ formatGroupUsageSuffix(node, "cli", casing, globalLongOptionFlags)
15317
+ ),
15318
+ ...node.description === void 0 ? {} : { description: node.description },
15319
+ commands: commandRows.map((row) => ({ name: row.name, description: row.description })),
15320
+ options: isRoot ? collectSchemaGlobalFieldRows(node, "cli", casing, globalLongOptionFlags).map((row) => ({
15321
+ name: row.flags.split(/[ ,]+/)[0]?.replace(/^--/, "") ?? row.flags,
15322
+ flags: row.flags.split(", "),
15323
+ type: "unknown",
15324
+ description: row.description,
15325
+ required: false
15326
+ })) : []
15327
+ },
15328
+ null,
15329
+ 2
15330
+ )}
15331
+ `;
15332
+ }
15333
+ const collected = collectFields(node.params, casing, globalLongOptionFlags);
15334
+ const fields = assignPositionals(collected.fields, node.positional);
15335
+ const positionalFields = fields.filter((field) => field.positionalIndex !== void 0);
15336
+ const usageSuffix = positionalFields.length > 0 ? `[OPTIONS] ${positionalFields.map(formatPositionalToken).join(" ")}` : "[OPTIONS]";
15337
+ return `${JSON.stringify(
15338
+ {
15339
+ schemaVersion: 1,
15340
+ kind: "command",
15341
+ name: node.name,
15342
+ path: target.breadcrumb.filter((segment) => segment.length > 0),
15343
+ usage: buildUsageLine(target.breadcrumb, rootUsageName, usageSuffix),
15344
+ ...node.description === void 0 ? {} : { description: node.description },
15345
+ options: fields.filter((field) => field.global !== true).map((field) => formatJsonHelpOption(field, globalLongOptionFlags)),
15346
+ secrets: Object.entries(node.secrets).map(([name, secret]) => ({
15347
+ name,
15348
+ env: secret.env,
15349
+ required: secret.optional !== true,
15350
+ ...secret.description === void 0 ? {} : { description: secret.description }
15351
+ })),
15352
+ examples: node.examples
15353
+ },
15354
+ null,
15355
+ 2
15356
+ )}
15357
+ `;
15358
+ }
15359
+ function formatJsonHelpOption(field, globalLongOptionFlags) {
15360
+ return {
15361
+ name: field.displayPath,
15362
+ flags: formatHelpFieldFlags(field, globalLongOptionFlags).split(", "),
15363
+ type: formatJsonHelpSchemaType(field.schema),
15364
+ ...field.description === void 0 ? {} : { description: field.description },
15365
+ required: field.requiredWhenActive,
15366
+ ...field.hasDefault ? { default: field.defaultValue } : {},
15367
+ ...field.positionalIndex === void 0 ? {} : { positional: true }
15368
+ };
15369
+ }
15370
+ function formatJsonHelpSchemaType(schema) {
15371
+ if (schema.kind === "enum") {
15372
+ return "enum";
15373
+ }
15374
+ if (schema.kind === "array") {
15375
+ return "array";
15376
+ }
15377
+ if (schema.kind === "json") {
15378
+ return "json";
15379
+ }
15380
+ return schema.kind;
15381
+ }
15074
15382
  function renderHelpDocument(input) {
15075
15383
  const title = input.breadcrumb.filter((segment) => segment.length > 0).join(" ") || input.rootUsageName;
15076
15384
  const description = input.description ?? "";
@@ -15094,11 +15402,27 @@ function renderHelpDocument(input) {
15094
15402
  `;
15095
15403
  }
15096
15404
  async function renderGeneratedHelp(root, argv, options) {
15097
- const target = resolveHelpTarget(root, argv, "cli", options.rootDisplayName);
15098
15405
  const output = resolveHelpOutput(argv);
15099
15406
  const casing = options.casing ?? "kebab";
15100
15407
  const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
15408
+ const target = resolveHelpTarget(root, argv, "cli", rootUsageName, options.rootDisplayName);
15101
15409
  const controls = resolveCLIControls(options.controls);
15410
+ if (output === "json") {
15411
+ process.stdout.write(
15412
+ renderJsonHelp(
15413
+ target,
15414
+ root,
15415
+ casing,
15416
+ {
15417
+ controls,
15418
+ showVersion: options.version !== void 0,
15419
+ presetsEnabled: options.presets === true
15420
+ },
15421
+ rootUsageName
15422
+ )
15423
+ );
15424
+ return;
15425
+ }
15102
15426
  await withOutputFormat2(output, async () => {
15103
15427
  const rendered = target.node.kind === "group" ? renderGroupHelp(
15104
15428
  target.node,
@@ -15218,9 +15542,11 @@ function addCommanderChild(parent, child, isDefault, siblingNames) {
15218
15542
  parent,
15219
15543
  "_toolcraftHiddenDefaultNames",
15220
15544
  getToolcraftHiddenDefaultNames(parent).concat([
15221
- ...new Set([Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15222
- (name) => typeof name === "string" && name.length > 0
15223
- ))
15545
+ ...new Set(
15546
+ [Reflect.get(child, "_toolcraftOriginalName"), ...child.aliases()].filter(
15547
+ (name) => typeof name === "string" && name.length > 0
15548
+ )
15549
+ )
15224
15550
  ])
15225
15551
  );
15226
15552
  parent.addCommand(child, { hidden: true, isDefault: true });
@@ -15277,6 +15603,13 @@ function addGlobalOptions(command, presetsEnabled, controls) {
15277
15603
  new Option("--debug [mode]", "Print stack traces for unexpected errors.").preset("trim").argParser(parseDebugStackMode)
15278
15604
  );
15279
15605
  }
15606
+ if (controls.logLevel) {
15607
+ options.push(
15608
+ new Option("--log-level <level>", "Set runtime diagnostic log level.").argParser(
15609
+ parseLogLevel
15610
+ )
15611
+ );
15612
+ }
15280
15613
  if (controls.verbose) {
15281
15614
  options.push(new Option("--verbose", "Print detailed runtime diagnostics."));
15282
15615
  }
@@ -15296,10 +15629,33 @@ function parseDebugStackMode(value) {
15296
15629
  formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
15297
15630
  );
15298
15631
  }
15299
- function setNestedValue(target, path25, value) {
15632
+ function parseLogLevel(value) {
15633
+ if (isLogLevel(value)) {
15634
+ return value;
15635
+ }
15636
+ throw new InvalidArgumentError(
15637
+ formatInvalidEnumMessage("--log-level", value, [...LOG_LEVELS], {
15638
+ candidates: ["warn", "debug", "trace"],
15639
+ threshold: 3
15640
+ })
15641
+ );
15642
+ }
15643
+ function writeCLIDiagnosticEvent(event) {
15644
+ const transcript = event.data?.transcript;
15645
+ if (typeof transcript === "string") {
15646
+ process.stderr.write(transcript);
15647
+ return;
15648
+ }
15649
+ if (event.category === "progress" || event.level === "trace") {
15650
+ return;
15651
+ }
15652
+ process.stderr.write(`${event.message}
15653
+ `);
15654
+ }
15655
+ function setNestedValue(target, path26, value) {
15300
15656
  let cursor2 = target;
15301
- for (let index = 0; index < path25.length - 1; index += 1) {
15302
- const segment = path25[index] ?? "";
15657
+ for (let index = 0; index < path26.length - 1; index += 1) {
15658
+ const segment = path26[index] ?? "";
15303
15659
  const existing = Object.prototype.hasOwnProperty.call(cursor2, segment) ? cursor2[segment] : void 0;
15304
15660
  if (typeof existing === "object" && existing !== null) {
15305
15661
  cursor2 = existing;
@@ -15314,7 +15670,7 @@ function setNestedValue(target, path25, value) {
15314
15670
  });
15315
15671
  cursor2 = next;
15316
15672
  }
15317
- const leaf = path25[path25.length - 1];
15673
+ const leaf = path26[path26.length - 1];
15318
15674
  if (leaf !== void 0) {
15319
15675
  Object.defineProperty(cursor2, leaf, {
15320
15676
  value,
@@ -15462,21 +15818,21 @@ async function withOutputFormat2(output, fn) {
15462
15818
  }
15463
15819
  function createFs2() {
15464
15820
  return {
15465
- readFile: async (path25, encoding = "utf8") => readFile5(path25, { encoding }),
15466
- writeFile: async (path25, contents, options) => {
15467
- await writeFile5(path25, contents, options);
15821
+ readFile: async (path26, encoding = "utf8") => readFile5(path26, { encoding }),
15822
+ writeFile: async (path26, contents, options) => {
15823
+ await writeFile5(path26, contents, options);
15468
15824
  },
15469
- exists: async (path25) => {
15825
+ exists: async (path26) => {
15470
15826
  try {
15471
- await access2(path25);
15827
+ await access2(path26);
15472
15828
  return true;
15473
15829
  } catch {
15474
15830
  return false;
15475
15831
  }
15476
15832
  },
15477
- lstat: async (path25) => lstat3(path25),
15833
+ lstat: async (path26) => lstat3(path26),
15478
15834
  rename: async (fromPath, toPath) => rename3(fromPath, toPath),
15479
- unlink: async (path25) => unlink3(path25)
15835
+ unlink: async (path26) => unlink3(path26)
15480
15836
  };
15481
15837
  }
15482
15838
  function createEnv2(values = process.env) {
@@ -15486,15 +15842,15 @@ function createEnv2(values = process.env) {
15486
15842
  }
15487
15843
  };
15488
15844
  }
15489
- function isPlainObject4(value) {
15845
+ function isPlainObject5(value) {
15490
15846
  return typeof value === "object" && value !== null && !Array.isArray(value);
15491
15847
  }
15492
15848
  function hasFieldValue(value) {
15493
15849
  return value !== void 0;
15494
15850
  }
15495
- function hasNestedField(fields, path25) {
15851
+ function hasNestedField(fields, path26) {
15496
15852
  return fields.some(
15497
- (field) => path25.length < field.path.length && path25.every((segment, index) => field.path[index] === segment)
15853
+ (field) => path26.length < field.path.length && path26.every((segment, index) => field.path[index] === segment)
15498
15854
  );
15499
15855
  }
15500
15856
  function describeExpectedPresetValue(schema) {
@@ -15618,14 +15974,14 @@ async function loadPresetValues(fields, presetPath) {
15618
15974
  { cause: error3 }
15619
15975
  );
15620
15976
  }
15621
- if (!isPlainObject4(parsedPreset)) {
15977
+ if (!isPlainObject5(parsedPreset)) {
15622
15978
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
15623
15979
  }
15624
15980
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
15625
15981
  const presetValues = {};
15626
- function visitObject(current, path25) {
15982
+ function visitObject(current, path26) {
15627
15983
  for (const [key2, value] of Object.entries(current)) {
15628
- const nextPath = [...path25, key2];
15984
+ const nextPath = [...path26, key2];
15629
15985
  const displayPath = toDisplayPath(nextPath);
15630
15986
  const field = fieldByPath.get(displayPath);
15631
15987
  if (field !== void 0) {
@@ -15637,7 +15993,7 @@ async function loadPresetValues(fields, presetPath) {
15637
15993
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
15638
15994
  );
15639
15995
  }
15640
- if (!isPlainObject4(value)) {
15996
+ if (!isPlainObject5(value)) {
15641
15997
  throw new UserError(
15642
15998
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
15643
15999
  );
@@ -15680,8 +16036,8 @@ function matchesFixtureValue(expected, actual) {
15680
16036
  }
15681
16037
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
15682
16038
  }
15683
- if (isPlainObject4(expected)) {
15684
- if (!isPlainObject4(actual)) {
16039
+ if (isPlainObject5(expected)) {
16040
+ if (!isPlainObject5(actual)) {
15685
16041
  return false;
15686
16042
  }
15687
16043
  return Object.entries(expected).every(
@@ -15744,9 +16100,9 @@ function createFixtureFetch(entries) {
15744
16100
  };
15745
16101
  }
15746
16102
  function createFixtureFs(definition) {
15747
- const fsDefinition = isPlainObject4(definition) ? definition : {};
15748
- const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
15749
- const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
16103
+ const fsDefinition = isPlainObject5(definition) ? definition : {};
16104
+ const readFileEntries = isPlainObject5(fsDefinition.readFile) ? fsDefinition.readFile : {};
16105
+ const existsEntries = isPlainObject5(fsDefinition.exists) ? fsDefinition.exists : {};
15750
16106
  return {
15751
16107
  readFile: async (filePath) => {
15752
16108
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -15769,10 +16125,10 @@ function createFixtureFs(definition) {
15769
16125
  function resolveFixtureMethodResult(methodName, definition, args) {
15770
16126
  if (Array.isArray(definition)) {
15771
16127
  for (const entry of definition) {
15772
- if (!isPlainObject4(entry)) {
16128
+ if (!isPlainObject5(entry)) {
15773
16129
  continue;
15774
16130
  }
15775
- const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
16131
+ const explicitMatcher = isPlainObject5(entry.request) ? entry.request : void 0;
15776
16132
  const matcher = explicitMatcher ?? Object.fromEntries(
15777
16133
  Object.entries(entry).filter(
15778
16134
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -15784,7 +16140,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15784
16140
  matched = matchesFixtureValue(matcher.args, args);
15785
16141
  } else if (Object.keys(matcher).length === 0) {
15786
16142
  matched = true;
15787
- } else if (isPlainObject4(firstArg)) {
16143
+ } else if (isPlainObject5(firstArg)) {
15788
16144
  matched = matchesFixtureValue(matcher, firstArg);
15789
16145
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
15790
16146
  const [[, expectedValue]] = Object.entries(matcher);
@@ -15805,7 +16161,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15805
16161
  return Promise.resolve(null);
15806
16162
  }
15807
16163
  }
15808
- if (isPlainObject4(definition)) {
16164
+ if (isPlainObject5(definition)) {
15809
16165
  const firstArg = args[0];
15810
16166
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
15811
16167
  return Promise.resolve(definition[firstArg]);
@@ -15817,7 +16173,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
15817
16173
  return Promise.resolve(null);
15818
16174
  }
15819
16175
  function createFixtureService(definition) {
15820
- const methods = isPlainObject4(definition) ? definition : {};
16176
+ const methods = isPlainObject5(definition) ? definition : {};
15821
16177
  return new Proxy(
15822
16178
  {},
15823
16179
  {
@@ -15915,7 +16271,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions, runt
15915
16271
  };
15916
16272
  }
15917
16273
  const scenario = await loadFixtureScenario(command, selector);
15918
- const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
16274
+ const scenarioServices = isPlainObject5(scenario.services) ? scenario.services : {};
15919
16275
  const customServiceNames = /* @__PURE__ */ new Set([
15920
16276
  ...Object.keys(services),
15921
16277
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -15975,6 +16331,19 @@ function renderCliErrorPattern(pattern) {
15975
16331
  process.exitCode = 1;
15976
16332
  return;
15977
16333
  }
16334
+ if (pattern.kind === "definition") {
16335
+ logger2.error(
16336
+ `Command definition error: ${pattern.error.message}
16337
+ This is a bug in the generated command definition, not in your command arguments.
16338
+ Run with --debug for a stack trace.`
16339
+ );
16340
+ if (pattern.debugStackMode !== void 0 && pattern.error.stack) {
16341
+ process.stderr.write(`${formatDebugStack(pattern.error.stack, pattern.debugStackMode)}
16342
+ `);
16343
+ }
16344
+ process.exitCode = 1;
16345
+ return;
16346
+ }
15978
16347
  if (pattern.kind === "toolcraft-bug") {
15979
16348
  logger2.error(
15980
16349
  `toolcraft hit an internal invariant: ${pattern.error.message}
@@ -16005,8 +16374,8 @@ function validateServices(services) {
16005
16374
  }
16006
16375
  }
16007
16376
  }
16008
- function getNestedValue(target, path25) {
16009
- return path25.reduce(
16377
+ function getNestedValue(target, path26) {
16378
+ return path26.reduce(
16010
16379
  (current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
16011
16380
  target
16012
16381
  );
@@ -16241,7 +16610,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16241
16610
  if (itemSchema.kind !== "object") {
16242
16611
  return value;
16243
16612
  }
16244
- if (!isPlainObject4(value)) {
16613
+ if (!isPlainObject5(value)) {
16245
16614
  errors2.push({
16246
16615
  path: displayPath,
16247
16616
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -16276,7 +16645,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16276
16645
  );
16277
16646
  }
16278
16647
  case "object": {
16279
- if (!isPlainObject4(value)) {
16648
+ if (!isPlainObject5(value)) {
16280
16649
  errors2.push({
16281
16650
  path: displayPath,
16282
16651
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16307,7 +16676,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
16307
16676
  return result;
16308
16677
  }
16309
16678
  case "record": {
16310
- if (!isPlainObject4(value)) {
16679
+ if (!isPlainObject5(value)) {
16311
16680
  errors2.push({
16312
16681
  path: displayPath,
16313
16682
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -16637,7 +17006,7 @@ function getResolvedFlags(command) {
16637
17006
  const flags = command.optsWithGlobals();
16638
17007
  return flags;
16639
17008
  }
16640
- async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, onErrorReportContext) {
17009
+ async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, diagnosticsOptions, onErrorReportContext) {
16641
17010
  const logger2 = createLogger();
16642
17011
  const primitives = {
16643
17012
  logger: logger2,
@@ -16648,6 +17017,10 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16648
17017
  const optionValues = state.actionCommand.optsWithGlobals();
16649
17018
  const resolvedFlags = optionValues;
16650
17019
  const output = resolveOutput(resolvedFlags);
17020
+ const diagnostics = createRuntimeLogger({
17021
+ level: resolvedFlags.logLevel ?? (diagnosticsOptions.verboseControlEnabled && resolvedFlags.verbose ? "trace" : diagnosticsOptions.logLevel),
17022
+ logger: diagnosticsOptions.logger ?? writeCLIDiagnosticEvent
17023
+ });
16651
17024
  const shouldPrompt = !resolvedFlags.yes && Boolean(process.stdin.isTTY);
16652
17025
  const runtime = await resolveFixtureRuntime(
16653
17026
  state.command,
@@ -16661,7 +17034,9 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16661
17034
  fetch: runtime.fetch,
16662
17035
  fs: runtime.fs,
16663
17036
  env: runtime.env,
17037
+ diagnostics,
16664
17038
  progress(message2) {
17039
+ diagnostics.emit({ level: "info", message: message2, category: "progress" });
16665
17040
  logger2.info(message2);
16666
17041
  }
16667
17042
  };
@@ -16738,18 +17113,18 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
16738
17113
  }
16739
17114
  }
16740
17115
  function isStringRecord(value) {
16741
- return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
17116
+ return isPlainObject5(value) && Object.values(value).every((entry) => typeof entry === "string");
16742
17117
  }
16743
17118
  function isHttpErrorLike(error3) {
16744
- if (!isPlainObject4(error3)) {
17119
+ if (!isPlainObject5(error3)) {
16745
17120
  return false;
16746
17121
  }
16747
- if (error3.name !== "HttpError" || typeof error3.message !== "string") {
17122
+ if (typeof error3.name !== "string" || typeof error3.message !== "string") {
16748
17123
  return false;
16749
17124
  }
16750
17125
  const request = error3.request;
16751
17126
  const response = error3.response;
16752
- return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && hasOwnProperty3(response, "body");
17127
+ return isPlainObject5(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject5(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && hasOwnProperty3(response, "body");
16753
17128
  }
16754
17129
  function hasTypedOptionalField(value, field, type2) {
16755
17130
  return !hasOwnProperty3(value, field) || typeof value[field] === type2;
@@ -16758,7 +17133,7 @@ function isNonEmptyString(value) {
16758
17133
  return typeof value === "string" && value.trim().length > 0;
16759
17134
  }
16760
17135
  function isProblemDetailsLike(body) {
16761
- if (!isPlainObject4(body)) {
17136
+ if (!isPlainObject5(body)) {
16762
17137
  return false;
16763
17138
  }
16764
17139
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -16779,11 +17154,11 @@ function isProblemDetailsLike(body) {
16779
17154
  return hasOwnNonEmptyString(body, "title") || hasOwnNonEmptyString(body, "detail");
16780
17155
  }
16781
17156
  function isGraphQLErrorEnvelopeLike(body) {
16782
- if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
17157
+ if (!isPlainObject5(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
16783
17158
  return false;
16784
17159
  }
16785
17160
  return body.errors.every((error3) => {
16786
- if (!isPlainObject4(error3) || typeof error3.message !== "string") {
17161
+ if (!isPlainObject5(error3) || typeof error3.message !== "string") {
16787
17162
  return false;
16788
17163
  }
16789
17164
  if (hasOwnProperty3(error3, "path")) {
@@ -16793,7 +17168,7 @@ function isGraphQLErrorEnvelopeLike(body) {
16793
17168
  }
16794
17169
  }
16795
17170
  if (hasOwnProperty3(error3, "extensions")) {
16796
- if (!isPlainObject4(error3.extensions)) {
17171
+ if (!isPlainObject5(error3.extensions)) {
16797
17172
  return false;
16798
17173
  }
16799
17174
  if (hasOwnProperty3(error3.extensions, "code") && typeof error3.extensions.code !== "string") {
@@ -16876,6 +17251,7 @@ function formatHttpErrorSnippet(body) {
16876
17251
  }
16877
17252
  function renderHttpError(error3, options) {
16878
17253
  const detailed = options.verbose || options.debugStackMode !== void 0;
17254
+ const summary = summarizeHttpError(error3);
16879
17255
  const lines = [
16880
17256
  styleHttpErrorLine(`Request: ${error3.request.method} ${error3.request.url}`, text.muted)
16881
17257
  ];
@@ -16902,11 +17278,27 @@ function renderHttpError(error3, options) {
16902
17278
  indentHttpErrorBlock(formatHttpErrorBody(error3.response.body))
16903
17279
  );
16904
17280
  } else {
16905
- lines.push(
16906
- "",
16907
- `Response body: ${formatHttpErrorSnippet(error3.response.body)}`,
16908
- "Re-run with --verbose to see headers and full body."
16909
- );
17281
+ const summaryLines = [
17282
+ summary.code === void 0 ? void 0 : `Code: ${summary.code}`,
17283
+ summary.message === void 0 ? void 0 : `Message: ${summary.message}`,
17284
+ summary.requestId === void 0 ? void 0 : `Request id: ${summary.requestId}`,
17285
+ summary.retryAfter === void 0 ? void 0 : `Retry after: ${summary.retryAfter}`,
17286
+ summary.hint === void 0 ? void 0 : `Hint: ${summary.hint}`
17287
+ ].filter((line) => line !== void 0);
17288
+ if (summary.fieldErrors !== void 0 && summary.fieldErrors.length > 0) {
17289
+ summaryLines.push(
17290
+ "",
17291
+ "Field errors:",
17292
+ ...summary.fieldErrors.map((fieldError) => ` ${fieldError.path}: ${fieldError.message}`)
17293
+ );
17294
+ }
17295
+ lines.push("");
17296
+ if (summaryLines.length > 0) {
17297
+ lines.push(...summaryLines);
17298
+ } else {
17299
+ lines.push(`Response body: ${formatHttpErrorSnippet(error3.response.body)}`);
17300
+ }
17301
+ lines.push("Re-run with --verbose to see headers and full body.");
16910
17302
  }
16911
17303
  process.stderr.write(`${lines.join("\n")}
16912
17304
  `);
@@ -16921,7 +17313,11 @@ async function handleRunError(error3, options) {
16921
17313
  await withOutputFormat2(options.output, async () => {
16922
17314
  if (error3 instanceof UserError) {
16923
17315
  renderCliErrorPattern(
16924
- options.userErrorPattern === "usage" ? {
17316
+ options.userErrorPattern === "definition" ? {
17317
+ kind: "definition",
17318
+ error: error3,
17319
+ debugStackMode: options.debugStackMode
17320
+ } : options.userErrorPattern === "usage" ? {
16925
17321
  kind: "usage",
16926
17322
  message: error3.message,
16927
17323
  rootUsageName: options.rootUsageName,
@@ -17159,13 +17555,23 @@ function findUnknownCommanderCommand(program, argv) {
17159
17555
  commandPath: pathSegments.join(" ")
17160
17556
  };
17161
17557
  }
17162
- if (current.commands.length === 0 || getDefaultCommanderCommandName(current) !== void 0) {
17558
+ if (current.commands.length === 0) {
17163
17559
  return void 0;
17164
17560
  }
17165
17561
  const child = current.commands.find(
17166
17562
  (command) => command.name() === token || command.aliases().includes(token)
17167
17563
  );
17168
17564
  if (child === void 0) {
17565
+ if (getDefaultCommanderCommandName(current) !== void 0) {
17566
+ if (shouldRejectDefaultCommandToken(current, token, pathSegments)) {
17567
+ return {
17568
+ input: token,
17569
+ currentCommand: current,
17570
+ commandPath: pathSegments.join(" ")
17571
+ };
17572
+ }
17573
+ return void 0;
17574
+ }
17169
17575
  return {
17170
17576
  input: token,
17171
17577
  currentCommand: current,
@@ -17177,6 +17583,36 @@ function findUnknownCommanderCommand(program, argv) {
17177
17583
  }
17178
17584
  return void 0;
17179
17585
  }
17586
+ function shouldRejectDefaultCommandToken(command, token, pathSegments) {
17587
+ return pathSegments.length === 0 && isBareCommandLikeToken(token) && hasNonDefaultPublicChildCommand(command);
17588
+ }
17589
+ function hasNonDefaultPublicChildCommand(command) {
17590
+ const defaultName = getDefaultCommanderCommandName(command);
17591
+ return command.commands.some(
17592
+ (child) => child.name() !== defaultName && !isToolcraftHiddenCommander(child) && !getToolcraftReservedChildNames(command).includes(child.name())
17593
+ );
17594
+ }
17595
+ function isBareCommandLikeToken(token) {
17596
+ if (token.length === 0) {
17597
+ return false;
17598
+ }
17599
+ for (const character of token) {
17600
+ if (!isCommandNameCharacter(character)) {
17601
+ return false;
17602
+ }
17603
+ }
17604
+ return true;
17605
+ }
17606
+ function isCommandNameCharacter(character) {
17607
+ const code = character.codePointAt(0);
17608
+ if (code === void 0) {
17609
+ return false;
17610
+ }
17611
+ const isLowercaseLetter = code >= 97 && code <= 122;
17612
+ const isUppercaseLetter = code >= 65 && code <= 90;
17613
+ const isDigit = code >= 48 && code <= 57;
17614
+ return isLowercaseLetter || isUppercaseLetter || isDigit || character === "-" || character === "_";
17615
+ }
17180
17616
  function getDefaultCommanderCommandName(command) {
17181
17617
  const candidate = command;
17182
17618
  return typeof candidate._defaultCommandName === "string" ? candidate._defaultCommandName : void 0;
@@ -17195,101 +17631,116 @@ function configureCommanderSuggestionOutput(command) {
17195
17631
  }
17196
17632
  async function runCLI(roots, options = {}) {
17197
17633
  enableSourceMaps();
17198
- const argv = [...options.argv ?? process.argv];
17199
- const normalizedRoot = normalizeRoots(roots, argv);
17200
- const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17201
- await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17202
- const casing = options.casing ?? "kebab";
17203
- const services = options.services ?? {};
17204
- const runtimeOptions = options.humanInLoop ?? {};
17205
- const runtimeFetch = options.fetch ?? globalThis.fetch;
17206
- const version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
17207
- const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
17208
17634
  const controls = resolveCLIControls(options.controls);
17209
- const servicesWithBuiltIns = {
17210
- ...services,
17211
- runtimeOptions,
17212
- root
17213
- };
17214
- const requirementOptions = {
17215
- apiVersion: options.apiVersion
17216
- };
17217
- validateServices(services);
17218
- if (hasHelpFlag(argv)) {
17219
- await renderGeneratedHelp(root, argv, { ...options, version });
17220
- return;
17221
- }
17222
- const program = new CommanderCommand();
17223
- program.name(root.name);
17224
- program.exitOverride();
17225
- program.showHelpAfterError();
17226
- program.addHelpCommand(false);
17227
- const presetsEnabled = options.presets === true;
17228
- const globalLongOptionFlags = getGlobalLongOptionFlags(
17229
- presetsEnabled,
17230
- version !== void 0,
17231
- controls
17232
- );
17233
- addGlobalOptions(program, presetsEnabled, controls);
17234
- if (version !== void 0) {
17235
- program.version(version, "--version");
17236
- }
17237
- Reflect.set(
17238
- program,
17239
- "_toolcraftReservedChildNames",
17240
- root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17241
- );
17635
+ const argv = controls.verbose ? normalizeVerboseAlias([...options.argv ?? process.argv]) : [...options.argv ?? process.argv];
17636
+ const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
17242
17637
  let lastActionCommand;
17243
17638
  let resolvedCommandPath = "";
17639
+ let program;
17640
+ let version;
17641
+ let userErrorPattern = "definition";
17244
17642
  let errorReportContext;
17245
- const execute = async (state) => {
17246
- lastActionCommand = state.actionCommand;
17247
- resolvedCommandPath = formatCliCommandPath(state.commandPath);
17248
- await executeCommand(
17249
- state,
17250
- servicesWithBuiltIns,
17251
- requirementOptions,
17252
- runtimeFetch,
17643
+ try {
17644
+ const normalizedRoot = normalizeRoots(roots, argv);
17645
+ const root = options.approvals === true ? mergeApprovalsGroup(normalizedRoot) : normalizedRoot;
17646
+ await resolveMcpProxies(root, { projectRoot: options.projectRoot });
17647
+ const casing = options.casing ?? "kebab";
17648
+ const services = options.services ?? {};
17649
+ const runtimeOptions = options.humanInLoop ?? {};
17650
+ const runtimeFetch = options.fetch ?? globalThis.fetch;
17651
+ version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
17652
+ const servicesWithBuiltIns = {
17653
+ ...services,
17253
17654
  runtimeOptions,
17254
- (context) => {
17255
- errorReportContext = context;
17256
- }
17257
- );
17258
- };
17259
- const rootChildNames = new Set(
17260
- root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17261
- );
17262
- for (const child of root.children) {
17263
- const command = createNodeCommand(
17264
- child,
17265
- casing,
17266
- globalLongOptionFlags,
17267
- execute,
17655
+ root
17656
+ };
17657
+ const requirementOptions = {
17658
+ apiVersion: options.apiVersion
17659
+ };
17660
+ validateServices(services);
17661
+ if (hasHelpFlag(argv)) {
17662
+ userErrorPattern = "usage";
17663
+ await renderGeneratedHelp(root, argv, { ...options, version });
17664
+ return;
17665
+ }
17666
+ if (argv.length <= 2 && root.default?.scope.includes("cli") !== true) {
17667
+ userErrorPattern = "usage";
17668
+ await renderGeneratedHelp(root, argv, { ...options, version });
17669
+ return;
17670
+ }
17671
+ program = new CommanderCommand();
17672
+ program.name(root.name);
17673
+ program.exitOverride();
17674
+ program.showHelpAfterError();
17675
+ program.addHelpCommand(false);
17676
+ const presetsEnabled = options.presets === true;
17677
+ const globalLongOptionFlags = getGlobalLongOptionFlags(
17268
17678
  presetsEnabled,
17679
+ version !== void 0,
17269
17680
  controls
17270
17681
  );
17271
- if (command === null) {
17272
- continue;
17682
+ addGlobalOptions(program, presetsEnabled, controls);
17683
+ if (version !== void 0) {
17684
+ program.version(version, "--version");
17273
17685
  }
17274
- const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17275
- addCommanderChild(program, command, isDefaultChild, rootChildNames);
17276
- }
17277
- configureCommanderSuggestionOutput(program);
17278
- const unknownCommand = findUnknownCommanderCommand(program, argv);
17279
- if (unknownCommand !== void 0) {
17280
- createLogger().error(
17281
- appendUsagePointer(
17282
- formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17686
+ Reflect.set(
17687
+ program,
17688
+ "_toolcraftReservedChildNames",
17689
+ root.children.filter((child) => !isNodeVisibleInScope(child, "cli")).flatMap((child) => getNodeCommandNames(child))
17690
+ );
17691
+ const execute = async (state) => {
17692
+ lastActionCommand = state.actionCommand;
17693
+ resolvedCommandPath = formatCliCommandPath(state.commandPath);
17694
+ await executeCommand(
17695
+ state,
17696
+ servicesWithBuiltIns,
17697
+ requirementOptions,
17698
+ runtimeFetch,
17699
+ runtimeOptions,
17283
17700
  {
17284
- rootUsageName,
17285
- commandPath: unknownCommand.commandPath
17701
+ logLevel: options.logLevel,
17702
+ logger: options.logger,
17703
+ verboseControlEnabled: controls.verbose
17704
+ },
17705
+ (context) => {
17706
+ errorReportContext = context;
17286
17707
  }
17287
- )
17708
+ );
17709
+ };
17710
+ const rootChildNames = new Set(
17711
+ root.children.filter((candidate) => isNodeVisibleInScope(candidate, "cli")).map((candidate) => candidate.name)
17288
17712
  );
17289
- process.exitCode = 1;
17290
- return;
17291
- }
17292
- try {
17713
+ for (const child of root.children) {
17714
+ const command = createNodeCommand(
17715
+ child,
17716
+ casing,
17717
+ globalLongOptionFlags,
17718
+ execute,
17719
+ presetsEnabled,
17720
+ controls
17721
+ );
17722
+ if (command === null) {
17723
+ continue;
17724
+ }
17725
+ const isDefaultChild = root.default !== void 0 && root.default.scope.includes("cli") && (command.name() === root.default.name || command.aliases().includes(root.default.name));
17726
+ addCommanderChild(program, command, isDefaultChild, rootChildNames);
17727
+ }
17728
+ configureCommanderSuggestionOutput(program);
17729
+ const unknownCommand = findUnknownCommanderCommand(program, argv);
17730
+ if (unknownCommand !== void 0) {
17731
+ createLogger().error(
17732
+ appendUsagePointer(
17733
+ formatUnknownCommandMessage(unknownCommand.input, unknownCommand.currentCommand),
17734
+ {
17735
+ rootUsageName,
17736
+ commandPath: unknownCommand.commandPath
17737
+ }
17738
+ )
17739
+ );
17740
+ process.exitCode = 1;
17741
+ return;
17742
+ }
17743
+ userErrorPattern = "usage";
17293
17744
  await program.parseAsync(argv);
17294
17745
  } catch (error3) {
17295
17746
  if (error3 instanceof ApprovalDeclinedError) {
@@ -17321,7 +17772,7 @@ async function runCLI(roots, options = {}) {
17321
17772
  argv,
17322
17773
  rootUsageName,
17323
17774
  commandPath: resolvedCommandPath,
17324
- userErrorPattern: errorReportContext?.params === void 0 ? "usage" : "runtime-user"
17775
+ userErrorPattern: errorReportContext?.params === void 0 ? userErrorPattern : "runtime-user"
17325
17776
  });
17326
17777
  }
17327
17778
  }
@@ -19445,22 +19896,22 @@ function prune(obj, shape) {
19445
19896
  }
19446
19897
  return { changed, result };
19447
19898
  }
19448
- function modifyAtPath(content, path25, value) {
19899
+ function modifyAtPath(content, path26, value) {
19449
19900
  const indent = detectIndent(content);
19450
19901
  const formattingOptions = {
19451
19902
  tabSize: indent === " " ? 1 : indent.length,
19452
19903
  insertSpaces: indent !== " ",
19453
19904
  eol: "\n"
19454
19905
  };
19455
- const edits = jsonc.modify(content, path25, value, { formattingOptions });
19906
+ const edits = jsonc.modify(content, path26, value, { formattingOptions });
19456
19907
  let result = jsonc.applyEdits(content, edits);
19457
19908
  if (!result.endsWith("\n")) {
19458
19909
  result += "\n";
19459
19910
  }
19460
19911
  return result;
19461
19912
  }
19462
- function removeAtPath(content, path25) {
19463
- return modifyAtPath(content, path25, void 0);
19913
+ function removeAtPath(content, path26) {
19914
+ return modifyAtPath(content, path26, void 0);
19464
19915
  }
19465
19916
  function serializeUpdate(content, current, next) {
19466
19917
  let result = content || "{}";
@@ -19470,15 +19921,15 @@ function serializeUpdate(content, current, next) {
19470
19921
  }
19471
19922
  return result;
19472
19923
  }
19473
- function applyObjectUpdate(content, path25, current, next) {
19924
+ function applyObjectUpdate(content, path26, current, next) {
19474
19925
  let result = content;
19475
19926
  for (const key2 of Object.keys(current)) {
19476
19927
  if (!hasConfigEntry(next, key2)) {
19477
- result = removeAtPath(result, [...path25, key2]);
19928
+ result = removeAtPath(result, [...path26, key2]);
19478
19929
  }
19479
19930
  }
19480
19931
  for (const [key2, nextValue] of Object.entries(next)) {
19481
- const nextPath = [...path25, key2];
19932
+ const nextPath = [...path26, key2];
19482
19933
  const hasCurrent = hasConfigEntry(current, key2);
19483
19934
  const currentValue = hasCurrent ? current[key2] : void 0;
19484
19935
  if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
@@ -19678,16 +20129,16 @@ function getConfigFormat(pathOrFormat) {
19678
20129
  }
19679
20130
  return formatRegistry[formatName];
19680
20131
  }
19681
- function detectFormat(path25) {
19682
- const ext = getExtension(path25);
20132
+ function detectFormat(path26) {
20133
+ const ext = getExtension(path26);
19683
20134
  return extensionMap[ext];
19684
20135
  }
19685
- function getExtension(path25) {
19686
- const lastDot = path25.lastIndexOf(".");
20136
+ function getExtension(path26) {
20137
+ const lastDot = path26.lastIndexOf(".");
19687
20138
  if (lastDot === -1) {
19688
20139
  return "";
19689
20140
  }
19690
- return path25.slice(lastDot).toLowerCase();
20141
+ return path26.slice(lastDot).toLowerCase();
19691
20142
  }
19692
20143
 
19693
20144
  // ../config-mutations/src/execution/path-utils.ts
@@ -22305,6 +22756,394 @@ function createTerminalPilotGroup() {
22305
22756
  }
22306
22757
  var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
22307
22758
 
22759
+ // src/commands/daemon-runtime.ts
22760
+ import { spawn as spawn7 } from "node:child_process";
22761
+ import { createHash as createHash5 } from "node:crypto";
22762
+ import { mkdir as mkdir3, unlink as unlink4 } from "node:fs/promises";
22763
+ import net from "node:net";
22764
+ import os4 from "node:os";
22765
+ import path24 from "node:path";
22766
+ var RUNTIME_DIR_ENV = "TERMINAL_PILOT_RUNTIME_DIR";
22767
+ var DAEMON_ARG = "__daemon";
22768
+ var START_TIMEOUT_MS = 5e3;
22769
+ var IDLE_SHUTDOWN_MS = 1e3;
22770
+ function isTerminalPilotDaemonArgv(argv) {
22771
+ return argv[2] === DAEMON_ARG;
22772
+ }
22773
+ async function runTerminalPilotDaemon() {
22774
+ const runtime = createTerminalPilotRuntime();
22775
+ const socketPath = resolveSocketPath(process.env);
22776
+ await mkdir3(path24.dirname(socketPath), { recursive: true });
22777
+ if (process.platform !== "win32") {
22778
+ await unlink4(socketPath).catch(() => void 0);
22779
+ }
22780
+ let idleTimer;
22781
+ const server = net.createServer((socket) => {
22782
+ let buffer = "";
22783
+ socket.setEncoding("utf8");
22784
+ socket.on("data", (chunk) => {
22785
+ buffer += chunk;
22786
+ while (true) {
22787
+ const newlineIndex = buffer.indexOf("\n");
22788
+ if (newlineIndex < 0) {
22789
+ break;
22790
+ }
22791
+ const line = buffer.slice(0, newlineIndex);
22792
+ buffer = buffer.slice(newlineIndex + 1);
22793
+ void handleRequestLine(runtime, line).then((response) => {
22794
+ socket.write(`${JSON.stringify(response)}
22795
+ `);
22796
+ scheduleIdleShutdown();
22797
+ });
22798
+ }
22799
+ });
22800
+ });
22801
+ async function shutdown() {
22802
+ if (idleTimer !== void 0) {
22803
+ clearTimeout(idleTimer);
22804
+ idleTimer = void 0;
22805
+ }
22806
+ await runtime.close();
22807
+ await new Promise((resolve) => {
22808
+ server.close(() => resolve());
22809
+ });
22810
+ if (process.platform !== "win32") {
22811
+ await unlink4(socketPath).catch(() => void 0);
22812
+ }
22813
+ }
22814
+ async function scheduleIdleShutdown() {
22815
+ if (idleTimer !== void 0) {
22816
+ clearTimeout(idleTimer);
22817
+ idleTimer = void 0;
22818
+ }
22819
+ const sessions = await runtime.listSessions();
22820
+ if (sessions.length > 0) {
22821
+ return;
22822
+ }
22823
+ idleTimer = setTimeout(() => {
22824
+ void shutdown().then(() => {
22825
+ process.exit(0);
22826
+ });
22827
+ }, IDLE_SHUTDOWN_MS);
22828
+ }
22829
+ await new Promise((resolve, reject) => {
22830
+ server.once("error", reject);
22831
+ server.listen(socketPath, () => {
22832
+ server.off("error", reject);
22833
+ resolve();
22834
+ });
22835
+ });
22836
+ }
22837
+ function createDaemonTerminalPilotRuntime() {
22838
+ let nextId = 1;
22839
+ async function request(method, params17) {
22840
+ await ensureDaemon();
22841
+ return sendRequest(method, params17, nextId++);
22842
+ }
22843
+ function proxySession(name, info2) {
22844
+ return {
22845
+ id: info2.id,
22846
+ command: info2.command,
22847
+ pid: info2.pid,
22848
+ exitCode: info2.exitCode,
22849
+ fill: async (text4) => {
22850
+ await request("sessionAction", { name, action: "fill", args: [text4] });
22851
+ },
22852
+ type: async (text4) => {
22853
+ await request("sessionAction", { name, action: "type", args: [text4] });
22854
+ },
22855
+ press: async (key2) => {
22856
+ await request("sessionAction", { name, action: "press", args: [key2] });
22857
+ },
22858
+ signal: async (signal) => {
22859
+ await request("sessionAction", { name, action: "signal", args: [signal] });
22860
+ },
22861
+ waitFor: async (pattern, options) => request("sessionAction", {
22862
+ name,
22863
+ action: "waitFor",
22864
+ args: [serializePattern(pattern), options]
22865
+ }),
22866
+ waitForExit: async (options) => request("sessionAction", { name, action: "waitForExit", args: [options] }),
22867
+ screen: async () => request("sessionAction", { name, action: "screen", args: [] }),
22868
+ history: async (options) => request("sessionAction", { name, action: "history", args: [options] }),
22869
+ resize: async (cols, rows) => {
22870
+ await request("sessionAction", { name, action: "resize", args: [cols, rows] });
22871
+ },
22872
+ close: async () => {
22873
+ const result = await request("closeSession", { name });
22874
+ return result.exitCode;
22875
+ }
22876
+ };
22877
+ }
22878
+ return {
22879
+ async createSession(params17, env) {
22880
+ const result = await request("createSession", {
22881
+ params: params17,
22882
+ envSession: env?.get(SESSION_ENV_VAR)
22883
+ });
22884
+ return { name: result.name, session: proxySession(result.name, result.session) };
22885
+ },
22886
+ async resolveSession(name, env) {
22887
+ const result = await request("resolveSession", {
22888
+ name,
22889
+ envSession: env?.get(SESSION_ENV_VAR)
22890
+ });
22891
+ return { name: result.name, session: proxySession(result.name, result.session) };
22892
+ },
22893
+ async closeSession(name, env) {
22894
+ return request("closeSession", {
22895
+ name,
22896
+ envSession: env?.get(SESSION_ENV_VAR)
22897
+ });
22898
+ },
22899
+ async listSessions() {
22900
+ const sessions = await request("listSessions");
22901
+ return sessions.map((entry) => ({
22902
+ name: entry.name,
22903
+ session: proxySession(entry.name, entry.session)
22904
+ }));
22905
+ },
22906
+ async close() {
22907
+ await request("shutdown").catch(() => void 0);
22908
+ }
22909
+ };
22910
+ }
22911
+ async function handleRequestLine(runtime, line) {
22912
+ let request;
22913
+ try {
22914
+ request = JSON.parse(line);
22915
+ } catch (error3) {
22916
+ return {
22917
+ id: 0,
22918
+ ok: false,
22919
+ error: { message: error3 instanceof Error ? error3.message : "Invalid request" }
22920
+ };
22921
+ }
22922
+ try {
22923
+ const result = await handleRequest(runtime, request);
22924
+ return { id: request.id, ok: true, result };
22925
+ } catch (error3) {
22926
+ return {
22927
+ id: request.id,
22928
+ ok: false,
22929
+ error: { message: error3 instanceof Error ? error3.message : String(error3) }
22930
+ };
22931
+ }
22932
+ }
22933
+ async function handleRequest(runtime, request) {
22934
+ const params17 = isRecord6(request.params) ? request.params : {};
22935
+ if (request.method === "ping") {
22936
+ return { ok: true };
22937
+ }
22938
+ if (request.method === "createSession") {
22939
+ const createParams = isRecord6(params17.params) ? params17.params : {};
22940
+ const namedSession = await runtime.createSession(
22941
+ createParams,
22942
+ envFromValue(params17.envSession)
22943
+ );
22944
+ return formatNamedSession(namedSession);
22945
+ }
22946
+ if (request.method === "resolveSession") {
22947
+ const namedSession = await runtime.resolveSession(
22948
+ optionalString2(params17.name),
22949
+ envFromValue(params17.envSession)
22950
+ );
22951
+ return formatNamedSession(namedSession);
22952
+ }
22953
+ if (request.method === "listSessions") {
22954
+ const sessions = await runtime.listSessions();
22955
+ return sessions.map(formatNamedSession);
22956
+ }
22957
+ if (request.method === "closeSession") {
22958
+ return runtime.closeSession(optionalString2(params17.name), envFromValue(params17.envSession));
22959
+ }
22960
+ if (request.method === "sessionAction") {
22961
+ return runSessionAction(runtime, params17);
22962
+ }
22963
+ if (request.method === "shutdown") {
22964
+ await runtime.close();
22965
+ process.exit(0);
22966
+ }
22967
+ throw new UserError(`Unknown terminal-pilot daemon method: ${request.method}`);
22968
+ }
22969
+ async function runSessionAction(runtime, params17) {
22970
+ const name = optionalString2(params17.name);
22971
+ const action = optionalString2(params17.action);
22972
+ const args = Array.isArray(params17.args) ? params17.args : [];
22973
+ const namedSession = await runtime.resolveSession(name);
22974
+ const session = namedSession.session;
22975
+ if (action === "fill") {
22976
+ await session.fill(String(args[0] ?? ""));
22977
+ return void 0;
22978
+ }
22979
+ if (action === "type") {
22980
+ await session.type(String(args[0] ?? ""));
22981
+ return void 0;
22982
+ }
22983
+ if (action === "press") {
22984
+ await session.press(String(args[0] ?? ""));
22985
+ return void 0;
22986
+ }
22987
+ if (action === "signal") {
22988
+ await session.signal(String(args[0] ?? ""));
22989
+ return void 0;
22990
+ }
22991
+ if (action === "waitFor") {
22992
+ return session.waitFor(deserializePattern(args[0]), optionalRecord(args[1]));
22993
+ }
22994
+ if (action === "waitForExit") {
22995
+ return session.waitForExit(optionalRecord(args[0]));
22996
+ }
22997
+ if (action === "screen") {
22998
+ const screen = await session.screen();
22999
+ return {
23000
+ lines: [...screen.lines],
23001
+ rawLines: [...screen.rawLines],
23002
+ cursor: { ...screen.cursor },
23003
+ size: { ...screen.size }
23004
+ };
23005
+ }
23006
+ if (action === "history") {
23007
+ return session.history(optionalRecord(args[0]));
23008
+ }
23009
+ if (action === "resize") {
23010
+ await session.resize(Number(args[0]), Number(args[1]));
23011
+ return void 0;
23012
+ }
23013
+ throw new UserError(`Unknown terminal-pilot session action: ${action ?? "<missing>"}`);
23014
+ }
23015
+ async function ensureDaemon() {
23016
+ try {
23017
+ await sendRequest("ping", void 0, 0, { start: false });
23018
+ return;
23019
+ } catch {
23020
+ }
23021
+ const socketPath = resolveSocketPath(process.env);
23022
+ await mkdir3(path24.dirname(socketPath), { recursive: true });
23023
+ if (process.platform !== "win32") {
23024
+ await unlink4(socketPath).catch(() => void 0);
23025
+ }
23026
+ const entryPoint = process.argv[1];
23027
+ if (typeof entryPoint !== "string" || entryPoint.length === 0) {
23028
+ throw new UserError("Cannot start terminal-pilot daemon: entrypoint is unknown.");
23029
+ }
23030
+ const child = spawn7(process.execPath, [...process.execArgv, entryPoint, DAEMON_ARG], {
23031
+ detached: true,
23032
+ stdio: "ignore",
23033
+ env: process.env
23034
+ });
23035
+ child.unref();
23036
+ const startedAt = Date.now();
23037
+ while (Date.now() - startedAt <= START_TIMEOUT_MS) {
23038
+ try {
23039
+ await sendRequest("ping", void 0, 0, { start: false });
23040
+ return;
23041
+ } catch {
23042
+ await sleep2(50);
23043
+ }
23044
+ }
23045
+ throw new UserError("Timed out waiting for terminal-pilot daemon to start.");
23046
+ }
23047
+ function sendRequest(method, params17, id, options = {}) {
23048
+ const socketPath = resolveSocketPath(process.env);
23049
+ return new Promise((resolve, reject) => {
23050
+ const socket = net.createConnection(socketPath);
23051
+ let buffer = "";
23052
+ socket.setEncoding("utf8");
23053
+ socket.on("connect", () => {
23054
+ const request = { id, method, params: params17 };
23055
+ socket.write(`${JSON.stringify(request)}
23056
+ `);
23057
+ });
23058
+ socket.on("data", (chunk) => {
23059
+ buffer += chunk;
23060
+ const newlineIndex = buffer.indexOf("\n");
23061
+ if (newlineIndex < 0) {
23062
+ return;
23063
+ }
23064
+ const line = buffer.slice(0, newlineIndex);
23065
+ socket.end();
23066
+ try {
23067
+ const response = JSON.parse(line);
23068
+ if (response.ok) {
23069
+ resolve(response.result);
23070
+ } else {
23071
+ reject(new UserError(response.error.message));
23072
+ }
23073
+ } catch (error3) {
23074
+ reject(error3);
23075
+ }
23076
+ });
23077
+ socket.on("error", (error3) => {
23078
+ if (options.start === false) {
23079
+ reject(error3);
23080
+ return;
23081
+ }
23082
+ reject(new UserError(error3.message));
23083
+ });
23084
+ });
23085
+ }
23086
+ function resolveSocketPath(env) {
23087
+ const runtimeDir = env[RUNTIME_DIR_ENV] ?? path24.join(os4.tmpdir(), `terminal-pilot-${process.getuid?.() ?? "user"}`);
23088
+ if (process.platform === "win32") {
23089
+ const hash = createHash5("sha256").update(runtimeDir).digest("hex").slice(0, 16);
23090
+ return `\\\\.\\pipe\\terminal-pilot-${hash}`;
23091
+ }
23092
+ return path24.join(runtimeDir, "daemon.sock");
23093
+ }
23094
+ function formatNamedSession(namedSession) {
23095
+ return {
23096
+ name: namedSession.name,
23097
+ session: formatSession(namedSession.session)
23098
+ };
23099
+ }
23100
+ function formatSession(session) {
23101
+ return {
23102
+ id: session.id,
23103
+ command: session.command,
23104
+ pid: session.pid,
23105
+ exitCode: session.exitCode
23106
+ };
23107
+ }
23108
+ function envFromValue(value) {
23109
+ const sessionName = optionalString2(value);
23110
+ if (sessionName === void 0) {
23111
+ return void 0;
23112
+ }
23113
+ return {
23114
+ get(key2) {
23115
+ return key2 === SESSION_ENV_VAR ? sessionName : void 0;
23116
+ }
23117
+ };
23118
+ }
23119
+ function serializePattern(pattern) {
23120
+ if (typeof pattern === "string") {
23121
+ return { kind: "literal", value: pattern };
23122
+ }
23123
+ return { kind: "regex", source: pattern.source, flags: pattern.flags };
23124
+ }
23125
+ function deserializePattern(value) {
23126
+ if (!isRecord6(value)) {
23127
+ return String(value ?? "");
23128
+ }
23129
+ if (value.kind === "regex") {
23130
+ return new RegExp(String(value.source ?? ""), String(value.flags ?? ""));
23131
+ }
23132
+ return String(value.value ?? "");
23133
+ }
23134
+ function optionalRecord(value) {
23135
+ return isRecord6(value) ? value : void 0;
23136
+ }
23137
+ function optionalString2(value) {
23138
+ return typeof value === "string" ? value : void 0;
23139
+ }
23140
+ function isRecord6(value) {
23141
+ return typeof value === "object" && value !== null && !Array.isArray(value);
23142
+ }
23143
+ function sleep2(ms) {
23144
+ return new Promise((resolve) => setTimeout(resolve, ms));
23145
+ }
23146
+
22308
23147
  // src/cli.ts
22309
23148
  configureTheme({ brand: "green", label: "Terminal Pilot" });
22310
23149
  function normalizeArgv(argv) {
@@ -22313,11 +23152,18 @@ function normalizeArgv(argv) {
22313
23152
  }
22314
23153
  return argv;
22315
23154
  }
22316
- async function main(argv = process.argv) {
23155
+ async function main(argv = process.argv, options = {}) {
23156
+ if (isTerminalPilotDaemonArgv(argv)) {
23157
+ await runTerminalPilotDaemon();
23158
+ return;
23159
+ }
22317
23160
  const originalArgv = process.argv;
22318
23161
  process.argv = normalizeArgv(argv);
22319
23162
  try {
22320
23163
  await runCLI(createTerminalPilotGroup(), {
23164
+ services: {
23165
+ terminalPilotRuntime: options.terminalPilotRuntime ?? createDaemonTerminalPilotRuntime()
23166
+ },
22321
23167
  controls: {
22322
23168
  debug: true,
22323
23169
  output: true,
@@ -22337,7 +23183,7 @@ async function isDirectExecution(argv) {
22337
23183
  try {
22338
23184
  const modulePath = fileURLToPath5(import.meta.url);
22339
23185
  const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
22340
- realpath3(path24.resolve(entryPoint)),
23186
+ realpath3(path25.resolve(entryPoint)),
22341
23187
  realpath3(modulePath)
22342
23188
  ]);
22343
23189
  return resolvedEntryPoint === resolvedModulePath;