terminal-pilot 0.0.34 → 0.0.36

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.
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
@@ -2746,17 +2746,17 @@ function validate(schema, value) {
2746
2746
  }
2747
2747
  return { ok: true, value: result.present ? result.value : void 0 };
2748
2748
  }
2749
- function walkSchema(schema, value, path25, state) {
2749
+ function walkSchema(schema, value, path26, state) {
2750
2750
  if (schema.kind === "optional") {
2751
- return walkOptional(schema, value, path25, state);
2751
+ return walkOptional(schema, value, path26, state);
2752
2752
  }
2753
2753
  if (value === missingValue) {
2754
2754
  addIssue(
2755
2755
  state,
2756
- path25,
2756
+ path26,
2757
2757
  expectedFor(schema),
2758
2758
  "missing",
2759
- `Expected ${expectedFor(schema)} at ${formatPath(path25)}`
2759
+ `Expected ${expectedFor(schema)} at ${formatPath(path26)}`
2760
2760
  );
2761
2761
  return { present: false };
2762
2762
  }
@@ -2765,149 +2765,149 @@ function walkSchema(schema, value, path25, state) {
2765
2765
  }
2766
2766
  switch (schema.kind) {
2767
2767
  case "string":
2768
- return walkString(schema, value, path25, state);
2768
+ return walkString(schema, value, path26, state);
2769
2769
  case "number":
2770
- return walkNumber(schema, value, path25, state);
2770
+ return walkNumber(schema, value, path26, state);
2771
2771
  case "boolean":
2772
- return walkBoolean(value, path25, state);
2772
+ return walkBoolean(value, path26, state);
2773
2773
  case "enum":
2774
- return walkEnum(schema, value, path25, state);
2774
+ return walkEnum(schema, value, path26, state);
2775
2775
  case "array":
2776
- return walkArray(schema, value, path25, state);
2776
+ return walkArray(schema, value, path26, state);
2777
2777
  case "object":
2778
- return walkObject(schema, value, path25, state);
2778
+ return walkObject(schema, value, path26, state);
2779
2779
  case "oneOf":
2780
- return walkOneOf(schema, value, path25, state);
2780
+ return walkOneOf(schema, value, path26, state);
2781
2781
  case "union":
2782
- return walkUnion(schema, value, path25, state);
2782
+ return walkUnion(schema, value, path26, state);
2783
2783
  case "record":
2784
- return walkRecord(schema, value, path25, state);
2784
+ return walkRecord(schema, value, path26, state);
2785
2785
  case "json":
2786
- return walkJson(value, path25, state);
2786
+ return walkJson(value, path26, state);
2787
2787
  }
2788
2788
  }
2789
- function walkOptional(schema, value, path25, state) {
2789
+ function walkOptional(schema, value, path26, state) {
2790
2790
  if (value === missingValue || value === void 0) {
2791
2791
  const defaultValue = getDefault(schema.inner);
2792
2792
  if (defaultValue.present) {
2793
- return walkSchema(schema.inner, cloneDefault(defaultValue.value), path25, state);
2793
+ return walkSchema(schema.inner, cloneDefault(defaultValue.value), path26, state);
2794
2794
  }
2795
2795
  return { present: false };
2796
2796
  }
2797
- return walkSchema(schema.inner, value, path25, state);
2797
+ return walkSchema(schema.inner, value, path26, state);
2798
2798
  }
2799
- function walkString(schema, value, path25, state) {
2799
+ function walkString(schema, value, path26, state) {
2800
2800
  if (typeof value !== "string") {
2801
- addExpectedIssue(state, path25, "string", value);
2801
+ addExpectedIssue(state, path26, "string", value);
2802
2802
  return { present: true, value };
2803
2803
  }
2804
2804
  if (schema.minLength !== void 0 && value.length < schema.minLength) {
2805
2805
  const expected = `string with length at least ${schema.minLength}`;
2806
2806
  addIssue(
2807
2807
  state,
2808
- path25,
2808
+ path26,
2809
2809
  expected,
2810
2810
  `string with length ${value.length}`,
2811
- `Expected ${expected} at ${formatPath(path25)}`
2811
+ `Expected ${expected} at ${formatPath(path26)}`
2812
2812
  );
2813
2813
  }
2814
2814
  if (schema.maxLength !== void 0 && value.length > schema.maxLength) {
2815
2815
  const expected = `string with length at most ${schema.maxLength}`;
2816
2816
  addIssue(
2817
2817
  state,
2818
- path25,
2818
+ path26,
2819
2819
  expected,
2820
2820
  `string with length ${value.length}`,
2821
- `Expected ${expected} at ${formatPath(path25)}`
2821
+ `Expected ${expected} at ${formatPath(path26)}`
2822
2822
  );
2823
2823
  }
2824
2824
  if (schema.pattern !== void 0) {
2825
2825
  const pattern = compilePattern(schema.pattern);
2826
2826
  if (pattern === void 0 || !pattern.test(value)) {
2827
2827
  const expected = `string matching pattern ${schema.pattern}`;
2828
- addIssue(state, path25, expected, value, `Expected ${expected} at ${formatPath(path25)}`);
2828
+ addIssue(state, path26, expected, value, `Expected ${expected} at ${formatPath(path26)}`);
2829
2829
  }
2830
2830
  }
2831
2831
  return { present: true, value };
2832
2832
  }
2833
- function walkNumber(schema, value, path25, state) {
2833
+ function walkNumber(schema, value, path26, state) {
2834
2834
  if (typeof value !== "number" || !Number.isFinite(value)) {
2835
- addExpectedIssue(state, path25, schema.jsonType === "integer" ? "integer" : "number", value);
2835
+ addExpectedIssue(state, path26, schema.jsonType === "integer" ? "integer" : "number", value);
2836
2836
  return { present: true, value };
2837
2837
  }
2838
2838
  if (schema.jsonType === "integer" && !Number.isInteger(value)) {
2839
- addExpectedIssue(state, path25, "integer", value);
2839
+ addExpectedIssue(state, path26, "integer", value);
2840
2840
  }
2841
2841
  if (schema.minimum !== void 0 && value < schema.minimum) {
2842
2842
  const expected = `number greater than or equal to ${schema.minimum}`;
2843
- addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
2843
+ addIssue(state, path26, expected, String(value), `Expected ${expected} at ${formatPath(path26)}`);
2844
2844
  }
2845
2845
  if (schema.maximum !== void 0 && value > schema.maximum) {
2846
2846
  const expected = `number less than or equal to ${schema.maximum}`;
2847
- addIssue(state, path25, expected, String(value), `Expected ${expected} at ${formatPath(path25)}`);
2847
+ addIssue(state, path26, expected, String(value), `Expected ${expected} at ${formatPath(path26)}`);
2848
2848
  }
2849
2849
  return { present: true, value };
2850
2850
  }
2851
- function walkBoolean(value, path25, state) {
2851
+ function walkBoolean(value, path26, state) {
2852
2852
  if (typeof value !== "boolean") {
2853
- addExpectedIssue(state, path25, "boolean", value);
2853
+ addExpectedIssue(state, path26, "boolean", value);
2854
2854
  }
2855
2855
  return { present: true, value };
2856
2856
  }
2857
- function walkEnum(schema, value, path25, state) {
2857
+ function walkEnum(schema, value, path26, state) {
2858
2858
  if (!schema.values.includes(value)) {
2859
2859
  const expected = `one of ${schema.values.join(", ")}`;
2860
2860
  addIssue(
2861
2861
  state,
2862
- path25,
2862
+ path26,
2863
2863
  expected,
2864
2864
  receivedValue(value),
2865
- `Expected ${expected} at ${formatPath(path25)}`
2865
+ `Expected ${expected} at ${formatPath(path26)}`
2866
2866
  );
2867
2867
  }
2868
2868
  return { present: true, value };
2869
2869
  }
2870
- function walkArray(schema, value, path25, state) {
2870
+ function walkArray(schema, value, path26, state) {
2871
2871
  if (!Array.isArray(value)) {
2872
- addExpectedIssue(state, path25, "array", value);
2872
+ addExpectedIssue(state, path26, "array", value);
2873
2873
  return { present: true, value };
2874
2874
  }
2875
2875
  if (schema.minItems !== void 0 && value.length < schema.minItems) {
2876
2876
  const expected = `array with at least ${schema.minItems} items`;
2877
2877
  addIssue(
2878
2878
  state,
2879
- path25,
2879
+ path26,
2880
2880
  expected,
2881
2881
  `array with ${value.length} items`,
2882
- `Expected ${expected} at ${formatPath(path25)}`
2882
+ `Expected ${expected} at ${formatPath(path26)}`
2883
2883
  );
2884
2884
  }
2885
2885
  if (schema.maxItems !== void 0 && value.length > schema.maxItems) {
2886
2886
  const expected = `array with at most ${schema.maxItems} items`;
2887
2887
  addIssue(
2888
2888
  state,
2889
- path25,
2889
+ path26,
2890
2890
  expected,
2891
2891
  `array with ${value.length} items`,
2892
- `Expected ${expected} at ${formatPath(path25)}`
2892
+ `Expected ${expected} at ${formatPath(path26)}`
2893
2893
  );
2894
2894
  }
2895
2895
  const nextValue = value.map((item, index) => {
2896
- const result = walkSchema(schema.item, item, [...path25, String(index)], state);
2896
+ const result = walkSchema(schema.item, item, [...path26, String(index)], state);
2897
2897
  return result.present ? result.value : item;
2898
2898
  });
2899
2899
  return { present: true, value: nextValue };
2900
2900
  }
2901
- function walkObject(schema, value, path25, state, injectedProperties = {}) {
2901
+ function walkObject(schema, value, path26, state, injectedProperties = {}) {
2902
2902
  if (!isPlainRecord(value)) {
2903
- addExpectedIssue(state, path25, "object", value);
2903
+ addExpectedIssue(state, path26, "object", value);
2904
2904
  return { present: true, value };
2905
2905
  }
2906
2906
  const nextValue = {};
2907
2907
  const allowedKeys = /* @__PURE__ */ new Set([...Object.keys(schema.shape), ...Object.keys(injectedProperties)]);
2908
2908
  for (const [key2, propertySchema] of Object.entries(schema.shape)) {
2909
2909
  const propertyValue = Object.hasOwn(value, key2) ? value[key2] : missingValue;
2910
- const result = walkSchema(propertySchema, propertyValue, [...path25, key2], state);
2910
+ const result = walkSchema(propertySchema, propertyValue, [...path26, key2], state);
2911
2911
  if (result.present) {
2912
2912
  setOwnValue(nextValue, key2, result.value);
2913
2913
  }
@@ -2926,18 +2926,18 @@ function walkObject(schema, value, path25, state, injectedProperties = {}) {
2926
2926
  if (schema.additionalProperties === true) {
2927
2927
  setOwnValue(nextValue, key2, propertyValue);
2928
2928
  } else {
2929
- addUnexpectedPropertyIssue(state, [...path25, key2]);
2929
+ addUnexpectedPropertyIssue(state, [...path26, key2]);
2930
2930
  }
2931
2931
  }
2932
2932
  return { present: true, value: nextValue };
2933
2933
  }
2934
- function walkOneOf(schema, value, path25, state) {
2934
+ function walkOneOf(schema, value, path26, state) {
2935
2935
  if (!isPlainRecord(value)) {
2936
- addExpectedIssue(state, path25, "object", value);
2936
+ addExpectedIssue(state, path26, "object", value);
2937
2937
  return { present: true, value };
2938
2938
  }
2939
2939
  const discriminatorValue = value[schema.discriminator];
2940
- const discriminatorPath = [...path25, schema.discriminator];
2940
+ const discriminatorPath = [...path26, schema.discriminator];
2941
2941
  const branchValues = Object.keys(schema.branches);
2942
2942
  const expected = `one of ${branchValues.join(", ")}`;
2943
2943
  if (!Object.hasOwn(value, schema.discriminator)) {
@@ -2946,7 +2946,7 @@ function walkOneOf(schema, value, path25, state) {
2946
2946
  discriminatorPath,
2947
2947
  expected,
2948
2948
  "missing",
2949
- `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(", ")}.`
2950
2950
  );
2951
2951
  return { present: true, value };
2952
2952
  }
@@ -2960,21 +2960,21 @@ function walkOneOf(schema, value, path25, state) {
2960
2960
  );
2961
2961
  return { present: true, value };
2962
2962
  }
2963
- return walkObject(schema.branches[discriminatorValue], value, path25, state, {
2963
+ return walkObject(schema.branches[discriminatorValue], value, path26, state, {
2964
2964
  [schema.discriminator]: discriminatorValue
2965
2965
  });
2966
2966
  }
2967
- function walkUnion(schema, value, path25, state) {
2967
+ function walkUnion(schema, value, path26, state) {
2968
2968
  if (isPlainRecord(value)) {
2969
2969
  const candidateBranches = schema.branches.filter((branch) => hasRequiredKeys(branch, value));
2970
2970
  if (candidateBranches.length === 1) {
2971
- return walkObject(candidateBranches[0], value, path25, state);
2971
+ return walkObject(candidateBranches[0], value, path26, state);
2972
2972
  }
2973
2973
  }
2974
2974
  const matches = [];
2975
2975
  for (const branch of schema.branches) {
2976
2976
  const branchState = { issues: [] };
2977
- const result = walkObject(branch, value, path25, branchState);
2977
+ const result = walkObject(branch, value, path26, branchState);
2978
2978
  if (branchState.issues.length === 0 && result.present) {
2979
2979
  matches.push({ fingerprint: getRequiredKeyFingerprint(branch), value: result.value });
2980
2980
  }
@@ -2986,19 +2986,19 @@ function walkUnion(schema, value, path25, state) {
2986
2986
  const branchDescriptions = schema.branches.map((branch) => getRequiredKeyFingerprint(branch));
2987
2987
  addIssueWithMessage(
2988
2988
  state,
2989
- path25,
2989
+ path26,
2990
2990
  "exactly one union branch",
2991
2991
  "0 matching branches",
2992
- `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(" | ")}.`
2993
2993
  );
2994
2994
  return { present: true, value };
2995
2995
  }
2996
2996
  addIssueWithMessage(
2997
2997
  state,
2998
- path25,
2998
+ path26,
2999
2999
  "exactly one union branch",
3000
3000
  `${matches.length} matching branches`,
3001
- `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(" | ")}`
3002
3002
  );
3003
3003
  return { present: true, value };
3004
3004
  }
@@ -3010,25 +3010,25 @@ function hasRequiredKeys(schema, value) {
3010
3010
  }
3011
3011
  return true;
3012
3012
  }
3013
- function walkRecord(schema, value, path25, state) {
3013
+ function walkRecord(schema, value, path26, state) {
3014
3014
  if (!isPlainRecord(value)) {
3015
- addExpectedIssue(state, path25, "object", value);
3015
+ addExpectedIssue(state, path26, "object", value);
3016
3016
  return { present: true, value };
3017
3017
  }
3018
3018
  const nextValue = {};
3019
3019
  for (const [key2, propertyValue] of Object.entries(value)) {
3020
- const result = walkSchema(schema.value, propertyValue, [...path25, key2], state);
3020
+ const result = walkSchema(schema.value, propertyValue, [...path26, key2], state);
3021
3021
  if (result.present) {
3022
3022
  setOwnValue(nextValue, key2, result.value);
3023
3023
  }
3024
3024
  }
3025
3025
  return { present: true, value: nextValue };
3026
3026
  }
3027
- function walkJson(value, path25, state) {
3027
+ function walkJson(value, path26, state) {
3028
3028
  if (isJsonValue(value)) {
3029
3029
  return { present: true, value };
3030
3030
  }
3031
- addExpectedIssue(state, path25, "JSON value", value);
3031
+ addExpectedIssue(state, path26, "JSON value", value);
3032
3032
  return { present: true, value };
3033
3033
  }
3034
3034
  function getDefault(schema) {
@@ -3106,45 +3106,45 @@ function expectedFor(schema) {
3106
3106
  return expectedFor(schema.inner);
3107
3107
  }
3108
3108
  }
3109
- function addExpectedIssue(state, path25, expected, value) {
3109
+ function addExpectedIssue(state, path26, expected, value) {
3110
3110
  addIssue(
3111
3111
  state,
3112
- path25,
3112
+ path26,
3113
3113
  expected,
3114
3114
  receivedType(value),
3115
- `Expected ${expected} at ${formatPath(path25)}`
3115
+ `Expected ${expected} at ${formatPath(path26)}`
3116
3116
  );
3117
3117
  }
3118
- function addUnexpectedPropertyIssue(state, path25) {
3118
+ function addUnexpectedPropertyIssue(state, path26) {
3119
3119
  addIssue(
3120
3120
  state,
3121
- path25,
3121
+ path26,
3122
3122
  "no additional properties",
3123
3123
  "unknown property",
3124
- `Unexpected property ${formatPath(path25)}`
3124
+ `Unexpected property ${formatPath(path26)}`
3125
3125
  );
3126
3126
  }
3127
- function addIssue(state, path25, expected, received, _message) {
3127
+ function addIssue(state, path26, expected, received, _message) {
3128
3128
  state.issues.push({
3129
- path: path25,
3129
+ path: path26,
3130
3130
  expected,
3131
3131
  received,
3132
- message: formatIssueMessage(expected, path25, received)
3132
+ message: formatIssueMessage(expected, path26, received)
3133
3133
  });
3134
3134
  }
3135
- function addIssueWithMessage(state, path25, expected, received, message2) {
3135
+ function addIssueWithMessage(state, path26, expected, received, message2) {
3136
3136
  state.issues.push({
3137
- path: path25,
3137
+ path: path26,
3138
3138
  expected,
3139
3139
  received,
3140
3140
  message: message2
3141
3141
  });
3142
3142
  }
3143
- function formatIssueMessage(expected, path25, received) {
3144
- return `Expected ${expected} at ${formatPath(path25)}, got ${received}`;
3143
+ function formatIssueMessage(expected, path26, received) {
3144
+ return `Expected ${expected} at ${formatPath(path26)}, got ${received}`;
3145
3145
  }
3146
- function formatPath(path25) {
3147
- return path25.length === 0 ? "value" : path25.join(".");
3146
+ function formatPath(path26) {
3147
+ return path26.length === 0 ? "value" : path26.join(".");
3148
3148
  }
3149
3149
  function compilePattern(pattern) {
3150
3150
  try {
@@ -7824,13 +7824,13 @@ function formatAvailableApprovalCommandPaths(root) {
7824
7824
  }
7825
7825
  function enumerateApprovalCommandPaths(root) {
7826
7826
  const paths = [];
7827
- const visit = (node, path25) => {
7827
+ const visit = (node, path26) => {
7828
7828
  if (node.kind === "command") {
7829
- paths.push(path25.join("."));
7829
+ paths.push(path26.join("."));
7830
7830
  return;
7831
7831
  }
7832
7832
  for (const child of getVisibleCliChildren(node)) {
7833
- visit(child, [...path25, child.name]);
7833
+ visit(child, [...path26, child.name]);
7834
7834
  }
7835
7835
  };
7836
7836
  if (root.kind === "command") {
@@ -7867,21 +7867,21 @@ function createHandlerContext(command, params17) {
7867
7867
  }
7868
7868
  function createFs() {
7869
7869
  return {
7870
- readFile: async (path25, encoding = "utf8") => readFile3(path25, { encoding }),
7871
- writeFile: async (path25, contents, options) => {
7872
- 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);
7873
7873
  },
7874
- exists: async (path25) => {
7874
+ exists: async (path26) => {
7875
7875
  try {
7876
- await access(path25);
7876
+ await access(path26);
7877
7877
  return true;
7878
7878
  } catch {
7879
7879
  return false;
7880
7880
  }
7881
7881
  },
7882
- lstat: async (path25) => lstat(path25),
7882
+ lstat: async (path26) => lstat(path26),
7883
7883
  rename: async (fromPath, toPath) => rename(fromPath, toPath),
7884
- unlink: async (path25) => unlink(path25)
7884
+ unlink: async (path26) => unlink(path26)
7885
7885
  };
7886
7886
  }
7887
7887
  function createEnv(values = process.env) {
@@ -11876,13 +11876,13 @@ function convertJsonSchema(schema) {
11876
11876
  }
11877
11877
  return convertSchema(schema, schema, []);
11878
11878
  }
11879
- function convertSchema(schema, root, path25) {
11880
- const resolvedSchema = resolveReferencedSchema(schema, root, path25);
11879
+ function convertSchema(schema, root, path26) {
11880
+ const resolvedSchema = resolveReferencedSchema(schema, root, path26);
11881
11881
  const normalizedSchema = normalizeNullability(resolvedSchema);
11882
11882
  const composition = getComposition(normalizedSchema.schema);
11883
11883
  if (Array.isArray(normalizedSchema.schema.type)) {
11884
11884
  throw new Error(
11885
- `JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
11885
+ `JSON Schema "${formatJsonSchemaPath(path26)}" has an unsupported type "${formatJsonSchemaType(
11886
11886
  normalizedSchema.schema.type
11887
11887
  )}". Supported: string, number, integer, boolean, array, object.`
11888
11888
  );
@@ -11894,13 +11894,13 @@ function convertSchema(schema, root, path25) {
11894
11894
  return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
11895
11895
  }
11896
11896
  if (composition !== void 0) {
11897
- return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path25);
11897
+ return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path26);
11898
11898
  }
11899
11899
  if (isRecordSchema(normalizedSchema.schema)) {
11900
11900
  return applyMetadata(
11901
11901
  S.Record(
11902
11902
  convertSchema(normalizedSchema.schema.additionalProperties, root, [
11903
- ...path25,
11903
+ ...path26,
11904
11904
  "additionalProperties"
11905
11905
  ])
11906
11906
  ),
@@ -11949,12 +11949,12 @@ function convertSchema(schema, root, path25) {
11949
11949
  if (normalizedSchema.schema.items === void 0) {
11950
11950
  throw new Error(
11951
11951
  `JSON Schema "${formatJsonSchemaPath(
11952
- path25
11952
+ path26
11953
11953
  )}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
11954
11954
  );
11955
11955
  }
11956
11956
  return S.Array(
11957
- convertSchema(normalizedSchema.schema.items, root, [...path25, "items"]),
11957
+ convertSchema(normalizedSchema.schema.items, root, [...path26, "items"]),
11958
11958
  createCommonOptions(
11959
11959
  normalizedSchema.schema,
11960
11960
  normalizedSchema.nullable,
@@ -11964,7 +11964,7 @@ function convertSchema(schema, root, path25) {
11964
11964
  case "object":
11965
11965
  return convertObjectSchema(normalizedSchema.schema, root, {
11966
11966
  nullable: normalizedSchema.nullable,
11967
- path: path25
11967
+ path: path26
11968
11968
  });
11969
11969
  case "null":
11970
11970
  return applyMetadata(S.Json(), normalizedSchema.schema, {
@@ -11979,12 +11979,12 @@ function convertSchema(schema, root, path25) {
11979
11979
  }
11980
11980
  throw new Error(
11981
11981
  `JSON Schema "${formatJsonSchemaPath(
11982
- path25
11982
+ path26
11983
11983
  )}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
11984
11984
  );
11985
11985
  }
11986
11986
  throw new Error(
11987
- `JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
11987
+ `JSON Schema "${formatJsonSchemaPath(path26)}" has an unsupported type "${formatJsonSchemaType(
11988
11988
  normalizedSchema.schema.type
11989
11989
  )}". Supported: string, number, integer, boolean, array, object.`
11990
11990
  );
@@ -12028,21 +12028,21 @@ function convertEnumSchema(schema, nullable) {
12028
12028
  )
12029
12029
  });
12030
12030
  }
12031
- function convertCompositionSchema(schema, root, nullable, path25) {
12031
+ function convertCompositionSchema(schema, root, nullable, path26) {
12032
12032
  const composition = getComposition(schema);
12033
12033
  const branchSchemas = composition?.branches ?? [];
12034
12034
  const keyword = composition?.keyword ?? "oneOf";
12035
12035
  const branches = branchSchemas.map(
12036
- (branch, index) => resolveReferencedSchema(branch, root, [...path25, keyword, String(index)])
12036
+ (branch, index) => resolveReferencedSchema(branch, root, [...path26, keyword, String(index)])
12037
12037
  );
12038
- const discriminator = findDiscriminator(branches, root, path25);
12038
+ const discriminator = findDiscriminator(branches, root, path26);
12039
12039
  if (discriminator !== void 0) {
12040
12040
  const convertedBranches = Object.fromEntries(
12041
12041
  branches.map((branch, index) => [
12042
12042
  getDiscriminatorLiteral(branch, discriminator, root),
12043
12043
  convertObjectSchema(branch, root, {
12044
12044
  omitProperty: discriminator,
12045
- path: [...path25, keyword, String(index)]
12045
+ path: [...path26, keyword, String(index)]
12046
12046
  })
12047
12047
  ])
12048
12048
  );
@@ -12061,7 +12061,7 @@ function convertCompositionSchema(schema, root, nullable, path25) {
12061
12061
  S.Union(
12062
12062
  branches.map(
12063
12063
  (branch, index) => convertObjectSchema(branch, root, {
12064
- path: [...path25, keyword, String(index)]
12064
+ path: [...path26, keyword, String(index)]
12065
12065
  })
12066
12066
  )
12067
12067
  ),
@@ -12175,11 +12175,11 @@ function getComposition(schema) {
12175
12175
  }
12176
12176
  return void 0;
12177
12177
  }
12178
- function formatJsonSchemaPath(path25) {
12179
- if (path25.length === 0) {
12178
+ function formatJsonSchemaPath(path26) {
12179
+ if (path26.length === 0) {
12180
12180
  return "#";
12181
12181
  }
12182
- return `#/${path25.map(escapeJsonPointerSegment).join("/")}`;
12182
+ return `#/${path26.map(escapeJsonPointerSegment).join("/")}`;
12183
12183
  }
12184
12184
  function formatJsonSchemaType(type2) {
12185
12185
  return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
@@ -12195,11 +12195,11 @@ function isRecordSchema(schema) {
12195
12195
  const propertyKeys = Object.keys(schema.properties ?? {});
12196
12196
  return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
12197
12197
  }
12198
- function findDiscriminator(branches, root, path25) {
12198
+ function findDiscriminator(branches, root, path26) {
12199
12199
  const [firstBranch] = branches;
12200
12200
  if (firstBranch === void 0) {
12201
12201
  throw new Error(
12202
- `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.`
12203
12203
  );
12204
12204
  }
12205
12205
  const candidateKeys = Object.keys(firstBranch.properties ?? {});
@@ -12239,19 +12239,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
12239
12239
  }
12240
12240
  return void 0;
12241
12241
  }
12242
- function resolveReferencedSchema(schema, root, path25) {
12242
+ function resolveReferencedSchema(schema, root, path26) {
12243
12243
  if (schema.$ref === void 0) {
12244
12244
  return schema;
12245
12245
  }
12246
12246
  const resolvedTarget = resolveLocalRef(root, schema.$ref);
12247
12247
  if (resolvedTarget === void 0) {
12248
12248
  throw new Error(
12249
- `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".`
12250
12250
  );
12251
12251
  }
12252
12252
  const { $ref: ignoredRef, ...siblingKeywords } = schema;
12253
12253
  void ignoredRef;
12254
- const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path25);
12254
+ const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path26);
12255
12255
  if (Object.keys(siblingKeywords).length === 0) {
12256
12256
  return resolvedSchema;
12257
12257
  }
@@ -12275,9 +12275,9 @@ function mergeJsonSchemas(base, overlay) {
12275
12275
  ...mergedRequired === void 0 ? {} : { required: mergedRequired }
12276
12276
  };
12277
12277
  }
12278
- function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__PURE__ */ new Set()) {
12278
+ function hasSelfReferencingRef(schema, root, path26 = "#", activePaths = /* @__PURE__ */ new Set()) {
12279
12279
  const nextActivePaths = new Set(activePaths);
12280
- nextActivePaths.add(path25);
12280
+ nextActivePaths.add(path26);
12281
12281
  const localRefPath = getLocalRefPath(schema.$ref);
12282
12282
  if (localRefPath !== void 0) {
12283
12283
  if (nextActivePaths.has(localRefPath)) {
@@ -12288,13 +12288,13 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
12288
12288
  return true;
12289
12289
  }
12290
12290
  }
12291
- 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)) {
12292
12292
  return true;
12293
12293
  }
12294
12294
  if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
12295
12295
  schema.additionalProperties,
12296
12296
  root,
12297
- `${path25}/additionalProperties`,
12297
+ `${path26}/additionalProperties`,
12298
12298
  nextActivePaths
12299
12299
  )) {
12300
12300
  return true;
@@ -12303,7 +12303,7 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
12303
12303
  if (hasSelfReferencingRef(
12304
12304
  childSchema,
12305
12305
  root,
12306
- `${path25}/properties/${escapeJsonPointerSegment(key2)}`,
12306
+ `${path26}/properties/${escapeJsonPointerSegment(key2)}`,
12307
12307
  nextActivePaths
12308
12308
  )) {
12309
12309
  return true;
@@ -12313,24 +12313,24 @@ function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__P
12313
12313
  if (hasSelfReferencingRef(
12314
12314
  childSchema,
12315
12315
  root,
12316
- `${path25}/$defs/${escapeJsonPointerSegment(key2)}`,
12316
+ `${path26}/$defs/${escapeJsonPointerSegment(key2)}`,
12317
12317
  nextActivePaths
12318
12318
  )) {
12319
12319
  return true;
12320
12320
  }
12321
12321
  }
12322
12322
  for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
12323
- if (hasSelfReferencingRef(childSchema, root, `${path25}/oneOf/${index}`, nextActivePaths)) {
12323
+ if (hasSelfReferencingRef(childSchema, root, `${path26}/oneOf/${index}`, nextActivePaths)) {
12324
12324
  return true;
12325
12325
  }
12326
12326
  }
12327
12327
  for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
12328
- if (hasSelfReferencingRef(childSchema, root, `${path25}/anyOf/${index}`, nextActivePaths)) {
12328
+ if (hasSelfReferencingRef(childSchema, root, `${path26}/anyOf/${index}`, nextActivePaths)) {
12329
12329
  return true;
12330
12330
  }
12331
12331
  }
12332
12332
  for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
12333
- if (hasSelfReferencingRef(childSchema, root, `${path25}/allOf/${index}`, nextActivePaths)) {
12333
+ if (hasSelfReferencingRef(childSchema, root, `${path26}/allOf/${index}`, nextActivePaths)) {
12334
12334
  return true;
12335
12335
  }
12336
12336
  }
@@ -12346,14 +12346,14 @@ function getLocalRefPath(ref) {
12346
12346
  return ref.startsWith("#/") ? ref : void 0;
12347
12347
  }
12348
12348
  function resolveLocalRef(root, ref) {
12349
- const path25 = getLocalRefPath(ref);
12350
- if (path25 === void 0) {
12349
+ const path26 = getLocalRefPath(ref);
12350
+ if (path26 === void 0) {
12351
12351
  return void 0;
12352
12352
  }
12353
- if (path25 === "#") {
12353
+ if (path26 === "#") {
12354
12354
  return root;
12355
12355
  }
12356
- const segments = path25.slice(2).split("/").map(unescapeJsonPointerSegment);
12356
+ const segments = path26.slice(2).split("/").map(unescapeJsonPointerSegment);
12357
12357
  let current = root;
12358
12358
  for (const segment of segments) {
12359
12359
  if (Array.isArray(current)) {
@@ -13494,23 +13494,23 @@ function extractFieldErrors(body) {
13494
13494
  const flattened = candidates.flatMap((candidate) => flattenFieldErrors(candidate, []));
13495
13495
  return flattened.length === 0 ? void 0 : flattened;
13496
13496
  }
13497
- function flattenFieldErrors(value, path25) {
13497
+ function flattenFieldErrors(value, path26) {
13498
13498
  if (typeof value === "string") {
13499
- return [{ path: formatPath2(path25), message: value }];
13499
+ return [{ path: formatPath2(path26), message: value }];
13500
13500
  }
13501
13501
  if (Array.isArray(value)) {
13502
13502
  if (value.every((entry) => typeof entry === "string")) {
13503
- return value.map((message2) => ({ path: formatPath2(path25), message: message2 }));
13503
+ return value.map((message2) => ({ path: formatPath2(path26), message: message2 }));
13504
13504
  }
13505
- return value.flatMap((entry, index) => flattenFieldErrors(entry, [...path25, String(index)]));
13505
+ return value.flatMap((entry, index) => flattenFieldErrors(entry, [...path26, String(index)]));
13506
13506
  }
13507
13507
  if (!isPlainObject4(value)) {
13508
13508
  return [];
13509
13509
  }
13510
- return Object.entries(value).flatMap(([key2, nested]) => flattenFieldErrors(nested, [...path25, key2]));
13510
+ return Object.entries(value).flatMap(([key2, nested]) => flattenFieldErrors(nested, [...path26, key2]));
13511
13511
  }
13512
- function formatPath2(path25) {
13513
- return path25.length === 0 ? "error" : path25.join(".");
13512
+ function formatPath2(path26) {
13513
+ return path26.length === 0 ? "error" : path26.join(".");
13514
13514
  }
13515
13515
  function extractFirstString(body, fields) {
13516
13516
  if (!isPlainObject4(body)) {
@@ -14080,11 +14080,11 @@ function formatSegment(segment, casing) {
14080
14080
  const separator = casing === "snake" ? "_" : "-";
14081
14081
  return splitWords3(segment).join(separator);
14082
14082
  }
14083
- function toOptionFlag(path25, casing) {
14084
- return `--${path25.map((segment) => formatSegment(segment, casing)).join(".")}`;
14083
+ function toOptionFlag(path26, casing) {
14084
+ return `--${path26.map((segment) => formatSegment(segment, casing)).join(".")}`;
14085
14085
  }
14086
- function toOptionAttribute(path25, casing) {
14087
- return path25.map((segment) => {
14086
+ function toOptionAttribute(path26, casing) {
14087
+ return path26.map((segment) => {
14088
14088
  const formatted = formatSegment(segment, casing);
14089
14089
  if (casing === "snake") {
14090
14090
  return formatted;
@@ -14095,23 +14095,23 @@ function toOptionAttribute(path25, casing) {
14095
14095
  ).join("");
14096
14096
  }).join(".");
14097
14097
  }
14098
- function toDisplayPath(path25) {
14099
- return path25.join(".");
14098
+ function toDisplayPath(path26) {
14099
+ return path26.join(".");
14100
14100
  }
14101
- function toUnionKindControlPath(path25) {
14102
- if (path25.length === 0) {
14101
+ function toUnionKindControlPath(path26) {
14102
+ if (path26.length === 0) {
14103
14103
  return ["kind"];
14104
14104
  }
14105
- const head = path25.slice(0, -1);
14106
- const tail = path25[path25.length - 1] ?? "";
14105
+ const head = path26.slice(0, -1);
14106
+ const tail = path26[path26.length - 1] ?? "";
14107
14107
  return [...head, `${tail}Kind`];
14108
14108
  }
14109
- function toUnionKindDisplayPath(path25) {
14110
- if (path25.length === 0) {
14109
+ function toUnionKindDisplayPath(path26) {
14110
+ if (path26.length === 0) {
14111
14111
  return "kind";
14112
14112
  }
14113
- const head = path25.slice(0, -1);
14114
- const tail = path25[path25.length - 1] ?? "";
14113
+ const head = path26.slice(0, -1);
14114
+ const tail = path26[path26.length - 1] ?? "";
14115
14115
  return [...head, `${tail}-kind`].join(".");
14116
14116
  }
14117
14117
  function createSyntheticEnumSchema(values) {
@@ -14127,14 +14127,14 @@ function getRequiredBranchFingerprint(branch, casing) {
14127
14127
  const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
14128
14128
  return requiredKeys.join("+");
14129
14129
  }
14130
- function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inheritedOptional = false, variantContext) {
14130
+ function collectFields(schema, casing, globalLongOptionFlags, path26 = [], inheritedOptional = false, variantContext) {
14131
14131
  const collected = {
14132
14132
  dynamicFields: [],
14133
14133
  fields: [],
14134
14134
  variants: []
14135
14135
  };
14136
14136
  for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
14137
- const nextPath = [...path25, key2];
14137
+ const nextPath = [...path26, key2];
14138
14138
  const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
14139
14139
  const childSchema = unwrapOptional2(rawChildSchema);
14140
14140
  const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
@@ -14320,9 +14320,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inher
14320
14320
  }
14321
14321
  return collected;
14322
14322
  }
14323
- function toCommanderOptionAttribute(path25, casing, globalLongOptionFlags) {
14324
- const optionAttribute = toOptionAttribute(path25, casing);
14325
- const optionFlag = toOptionFlag(path25, casing);
14323
+ function toCommanderOptionAttribute(path26, casing, globalLongOptionFlags) {
14324
+ const optionAttribute = toOptionAttribute(path26, casing);
14325
+ const optionFlag = toOptionFlag(path26, casing);
14326
14326
  if (!globalLongOptionFlags.has(optionFlag)) {
14327
14327
  return optionAttribute;
14328
14328
  }
@@ -15652,10 +15652,10 @@ function writeCLIDiagnosticEvent(event) {
15652
15652
  process.stderr.write(`${event.message}
15653
15653
  `);
15654
15654
  }
15655
- function setNestedValue(target, path25, value) {
15655
+ function setNestedValue(target, path26, value) {
15656
15656
  let cursor2 = target;
15657
- for (let index = 0; index < path25.length - 1; index += 1) {
15658
- const segment = path25[index] ?? "";
15657
+ for (let index = 0; index < path26.length - 1; index += 1) {
15658
+ const segment = path26[index] ?? "";
15659
15659
  const existing = Object.prototype.hasOwnProperty.call(cursor2, segment) ? cursor2[segment] : void 0;
15660
15660
  if (typeof existing === "object" && existing !== null) {
15661
15661
  cursor2 = existing;
@@ -15670,7 +15670,7 @@ function setNestedValue(target, path25, value) {
15670
15670
  });
15671
15671
  cursor2 = next;
15672
15672
  }
15673
- const leaf = path25[path25.length - 1];
15673
+ const leaf = path26[path26.length - 1];
15674
15674
  if (leaf !== void 0) {
15675
15675
  Object.defineProperty(cursor2, leaf, {
15676
15676
  value,
@@ -15818,21 +15818,21 @@ async function withOutputFormat2(output, fn) {
15818
15818
  }
15819
15819
  function createFs2() {
15820
15820
  return {
15821
- readFile: async (path25, encoding = "utf8") => readFile5(path25, { encoding }),
15822
- writeFile: async (path25, contents, options) => {
15823
- 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);
15824
15824
  },
15825
- exists: async (path25) => {
15825
+ exists: async (path26) => {
15826
15826
  try {
15827
- await access2(path25);
15827
+ await access2(path26);
15828
15828
  return true;
15829
15829
  } catch {
15830
15830
  return false;
15831
15831
  }
15832
15832
  },
15833
- lstat: async (path25) => lstat3(path25),
15833
+ lstat: async (path26) => lstat3(path26),
15834
15834
  rename: async (fromPath, toPath) => rename3(fromPath, toPath),
15835
- unlink: async (path25) => unlink3(path25)
15835
+ unlink: async (path26) => unlink3(path26)
15836
15836
  };
15837
15837
  }
15838
15838
  function createEnv2(values = process.env) {
@@ -15848,9 +15848,9 @@ function isPlainObject5(value) {
15848
15848
  function hasFieldValue(value) {
15849
15849
  return value !== void 0;
15850
15850
  }
15851
- function hasNestedField(fields, path25) {
15851
+ function hasNestedField(fields, path26) {
15852
15852
  return fields.some(
15853
- (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)
15854
15854
  );
15855
15855
  }
15856
15856
  function describeExpectedPresetValue(schema) {
@@ -15979,9 +15979,9 @@ async function loadPresetValues(fields, presetPath) {
15979
15979
  }
15980
15980
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
15981
15981
  const presetValues = {};
15982
- function visitObject(current, path25) {
15982
+ function visitObject(current, path26) {
15983
15983
  for (const [key2, value] of Object.entries(current)) {
15984
- const nextPath = [...path25, key2];
15984
+ const nextPath = [...path26, key2];
15985
15985
  const displayPath = toDisplayPath(nextPath);
15986
15986
  const field = fieldByPath.get(displayPath);
15987
15987
  if (field !== void 0) {
@@ -16374,8 +16374,8 @@ function validateServices(services) {
16374
16374
  }
16375
16375
  }
16376
16376
  }
16377
- function getNestedValue(target, path25) {
16378
- return path25.reduce(
16377
+ function getNestedValue(target, path26) {
16378
+ return path26.reduce(
16379
16379
  (current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
16380
16380
  target
16381
16381
  );
@@ -19896,22 +19896,22 @@ function prune(obj, shape) {
19896
19896
  }
19897
19897
  return { changed, result };
19898
19898
  }
19899
- function modifyAtPath(content, path25, value) {
19899
+ function modifyAtPath(content, path26, value) {
19900
19900
  const indent = detectIndent(content);
19901
19901
  const formattingOptions = {
19902
19902
  tabSize: indent === " " ? 1 : indent.length,
19903
19903
  insertSpaces: indent !== " ",
19904
19904
  eol: "\n"
19905
19905
  };
19906
- const edits = jsonc.modify(content, path25, value, { formattingOptions });
19906
+ const edits = jsonc.modify(content, path26, value, { formattingOptions });
19907
19907
  let result = jsonc.applyEdits(content, edits);
19908
19908
  if (!result.endsWith("\n")) {
19909
19909
  result += "\n";
19910
19910
  }
19911
19911
  return result;
19912
19912
  }
19913
- function removeAtPath(content, path25) {
19914
- return modifyAtPath(content, path25, void 0);
19913
+ function removeAtPath(content, path26) {
19914
+ return modifyAtPath(content, path26, void 0);
19915
19915
  }
19916
19916
  function serializeUpdate(content, current, next) {
19917
19917
  let result = content || "{}";
@@ -19921,15 +19921,15 @@ function serializeUpdate(content, current, next) {
19921
19921
  }
19922
19922
  return result;
19923
19923
  }
19924
- function applyObjectUpdate(content, path25, current, next) {
19924
+ function applyObjectUpdate(content, path26, current, next) {
19925
19925
  let result = content;
19926
19926
  for (const key2 of Object.keys(current)) {
19927
19927
  if (!hasConfigEntry(next, key2)) {
19928
- result = removeAtPath(result, [...path25, key2]);
19928
+ result = removeAtPath(result, [...path26, key2]);
19929
19929
  }
19930
19930
  }
19931
19931
  for (const [key2, nextValue] of Object.entries(next)) {
19932
- const nextPath = [...path25, key2];
19932
+ const nextPath = [...path26, key2];
19933
19933
  const hasCurrent = hasConfigEntry(current, key2);
19934
19934
  const currentValue = hasCurrent ? current[key2] : void 0;
19935
19935
  if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
@@ -20129,16 +20129,16 @@ function getConfigFormat(pathOrFormat) {
20129
20129
  }
20130
20130
  return formatRegistry[formatName];
20131
20131
  }
20132
- function detectFormat(path25) {
20133
- const ext = getExtension(path25);
20132
+ function detectFormat(path26) {
20133
+ const ext = getExtension(path26);
20134
20134
  return extensionMap[ext];
20135
20135
  }
20136
- function getExtension(path25) {
20137
- const lastDot = path25.lastIndexOf(".");
20136
+ function getExtension(path26) {
20137
+ const lastDot = path26.lastIndexOf(".");
20138
20138
  if (lastDot === -1) {
20139
20139
  return "";
20140
20140
  }
20141
- return path25.slice(lastDot).toLowerCase();
20141
+ return path26.slice(lastDot).toLowerCase();
20142
20142
  }
20143
20143
 
20144
20144
  // ../config-mutations/src/execution/path-utils.ts
@@ -22756,6 +22756,394 @@ function createTerminalPilotGroup() {
22756
22756
  }
22757
22757
  var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
22758
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
+
22759
23147
  // src/cli.ts
22760
23148
  configureTheme({ brand: "green", label: "Terminal Pilot" });
22761
23149
  function normalizeArgv(argv) {
@@ -22764,11 +23152,18 @@ function normalizeArgv(argv) {
22764
23152
  }
22765
23153
  return argv;
22766
23154
  }
22767
- async function main(argv = process.argv) {
23155
+ async function main(argv = process.argv, options = {}) {
23156
+ if (isTerminalPilotDaemonArgv(argv)) {
23157
+ await runTerminalPilotDaemon();
23158
+ return;
23159
+ }
22768
23160
  const originalArgv = process.argv;
22769
23161
  process.argv = normalizeArgv(argv);
22770
23162
  try {
22771
23163
  await runCLI(createTerminalPilotGroup(), {
23164
+ services: {
23165
+ terminalPilotRuntime: options.terminalPilotRuntime ?? createDaemonTerminalPilotRuntime()
23166
+ },
22772
23167
  controls: {
22773
23168
  debug: true,
22774
23169
  output: true,
@@ -22788,7 +23183,7 @@ async function isDirectExecution(argv) {
22788
23183
  try {
22789
23184
  const modulePath = fileURLToPath5(import.meta.url);
22790
23185
  const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
22791
- realpath3(path24.resolve(entryPoint)),
23186
+ realpath3(path25.resolve(entryPoint)),
22792
23187
  realpath3(modulePath)
22793
23188
  ]);
22794
23189
  return resolvedEntryPoint === resolvedModulePath;