terminal-pilot 0.0.20 → 0.0.22

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 (58) hide show
  1. package/dist/cli.js +1011 -452
  2. package/dist/cli.js.map +4 -4
  3. package/dist/commands/close-session.js +6 -4
  4. package/dist/commands/close-session.js.map +3 -3
  5. package/dist/commands/create-session.js +6 -4
  6. package/dist/commands/create-session.js.map +3 -3
  7. package/dist/commands/fill.js +6 -4
  8. package/dist/commands/fill.js.map +3 -3
  9. package/dist/commands/get-session.js +6 -4
  10. package/dist/commands/get-session.js.map +3 -3
  11. package/dist/commands/index.js +299 -159
  12. package/dist/commands/index.js.map +4 -4
  13. package/dist/commands/install.js +251 -113
  14. package/dist/commands/install.js.map +4 -4
  15. package/dist/commands/installer.js +190 -62
  16. package/dist/commands/installer.js.map +4 -4
  17. package/dist/commands/list-sessions.js +6 -4
  18. package/dist/commands/list-sessions.js.map +3 -3
  19. package/dist/commands/press-key.js +6 -4
  20. package/dist/commands/press-key.js.map +3 -3
  21. package/dist/commands/read-history.js +6 -4
  22. package/dist/commands/read-history.js.map +3 -3
  23. package/dist/commands/read-screen.js +6 -4
  24. package/dist/commands/read-screen.js.map +3 -3
  25. package/dist/commands/resize.js +6 -4
  26. package/dist/commands/resize.js.map +3 -3
  27. package/dist/commands/runtime.js +6 -4
  28. package/dist/commands/runtime.js.map +3 -3
  29. package/dist/commands/screenshot.js +17 -8
  30. package/dist/commands/screenshot.js.map +3 -3
  31. package/dist/commands/send-signal.js +6 -4
  32. package/dist/commands/send-signal.js.map +3 -3
  33. package/dist/commands/type.js +6 -4
  34. package/dist/commands/type.js.map +3 -3
  35. package/dist/commands/uninstall.js +226 -98
  36. package/dist/commands/uninstall.js.map +4 -4
  37. package/dist/commands/wait-for-exit.js +6 -4
  38. package/dist/commands/wait-for-exit.js.map +3 -3
  39. package/dist/commands/wait-for.js +6 -4
  40. package/dist/commands/wait-for.js.map +3 -3
  41. package/dist/errors.d.ts +1 -0
  42. package/dist/errors.js +8 -0
  43. package/dist/errors.js.map +7 -0
  44. package/dist/index.js +8 -4
  45. package/dist/index.js.map +3 -3
  46. package/dist/terminal-pilot.js +6 -4
  47. package/dist/terminal-pilot.js.map +3 -3
  48. package/dist/terminal-session.js +6 -4
  49. package/dist/terminal-session.js.map +3 -3
  50. package/dist/testing/cli-repl.js +1011 -452
  51. package/dist/testing/cli-repl.js.map +4 -4
  52. package/dist/testing/qa-cli.js +1011 -452
  53. package/dist/testing/qa-cli.js.map +4 -4
  54. package/node_modules/@poe-code/agent-skill-config/dist/apply.js +4 -1
  55. package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +1 -1
  56. package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +17 -9
  57. package/node_modules/@poe-code/agent-skill-config/dist/templates.js +4 -1
  58. package/package.json +2 -1
package/dist/cli.js CHANGED
@@ -6,12 +6,12 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/cli.ts
9
- import { realpath as realpath2 } from "node:fs/promises";
9
+ import { realpath as realpath3 } from "node:fs/promises";
10
10
  import path23 from "node:path";
11
11
  import { fileURLToPath as fileURLToPath5 } from "node:url";
12
12
 
13
13
  // ../toolcraft/src/cli.ts
14
- import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
14
+ import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
15
15
  import path14 from "node:path";
16
16
  import {
17
17
  Command as CommanderCommand,
@@ -20,7 +20,7 @@ import {
20
20
  Option
21
21
  } from "commander";
22
22
 
23
- // ../design-system/src/internal/color-support.ts
23
+ // ../toolcraft-design/src/internal/color-support.ts
24
24
  function supportsColor(env = process.env, stream = process.stdout) {
25
25
  if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
26
26
  return true;
@@ -34,7 +34,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
34
34
  return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
35
35
  }
36
36
 
37
- // ../design-system/src/components/color.ts
37
+ // ../toolcraft-design/src/components/color.ts
38
38
  var reset = "\x1B[0m";
39
39
  var ansiStyles = {
40
40
  reset: { open: reset },
@@ -136,41 +136,135 @@ function createColor(styles = []) {
136
136
  }
137
137
  var color = createColor();
138
138
 
139
- // ../design-system/src/tokens/colors.ts
140
- var dark = {
141
- header: (text5) => color.magentaBright.bold(text5),
142
- divider: (text5) => color.dim(text5),
143
- prompt: (text5) => color.cyan(text5),
144
- number: (text5) => color.cyanBright(text5),
145
- intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
146
- resolvedSymbol: color.magenta("\u25C7"),
147
- errorSymbol: color.red("\u25A0"),
148
- accent: (text5) => color.cyan(text5),
149
- muted: (text5) => color.dim(text5),
150
- success: (text5) => color.green(text5),
151
- warning: (text5) => color.yellow(text5),
152
- error: (text5) => color.red(text5),
153
- info: (text5) => color.magenta(text5),
154
- badge: (text5) => color.bgYellow.black(` ${text5} `)
139
+ // ../toolcraft-design/src/tokens/brand.ts
140
+ var brands = {
141
+ purple: { name: "purple", primary: "#a200ff" },
142
+ blue: { name: "blue", primary: "#2f6fed" },
143
+ green: { name: "green", primary: "#1f9d57" }
155
144
  };
156
- var light = {
157
- header: (text5) => color.hex("#a200ff").bold(text5),
158
- divider: (text5) => color.hex("#666666")(text5),
159
- prompt: (text5) => color.hex("#006699").bold(text5),
160
- number: (text5) => color.hex("#0077cc").bold(text5),
161
- intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
162
- resolvedSymbol: color.hex("#a200ff")("\u25C7"),
163
- errorSymbol: color.hex("#cc0000")("\u25A0"),
164
- accent: (text5) => color.hex("#006699").bold(text5),
165
- muted: (text5) => color.hex("#666666")(text5),
166
- success: (text5) => color.hex("#008800")(text5),
167
- warning: (text5) => color.hex("#cc6600")(text5),
168
- error: (text5) => color.hex("#cc0000")(text5),
169
- info: (text5) => color.hex("#a200ff")(text5),
170
- badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
145
+
146
+ // ../toolcraft-design/src/internal/theme-state.ts
147
+ var defaults = {
148
+ brand: "purple",
149
+ label: "Poe"
171
150
  };
151
+ var config = { ...defaults };
152
+ var revision = 0;
153
+ var brandConfigured = false;
154
+ function configureTheme(patch) {
155
+ if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
156
+ throw new Error(`Unknown brand: ${patch.brand}`);
157
+ }
158
+ config = {
159
+ brand: patch.brand ?? config.brand,
160
+ label: patch.label ?? config.label
161
+ };
162
+ if (patch.brand !== void 0) {
163
+ brandConfigured = true;
164
+ }
165
+ revision += 1;
166
+ }
167
+ function getThemeConfig() {
168
+ return { ...config };
169
+ }
170
+ function getThemeRevision() {
171
+ return revision;
172
+ }
173
+ function isThemeBrandConfigured() {
174
+ return brandConfigured;
175
+ }
176
+
177
+ // ../toolcraft-design/src/tokens/colors.ts
178
+ var brand = brands.purple.primary;
179
+ function withStyles(palette, styles) {
180
+ return Object.defineProperty(palette, "styles", {
181
+ value: styles,
182
+ enumerable: false
183
+ });
184
+ }
185
+ function brandColor(activeBrand, purple) {
186
+ return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
187
+ }
188
+ function brandBackground(activeBrand, purple) {
189
+ return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
190
+ }
191
+ function createPalette(activeBrand, mode) {
192
+ const isPurple = activeBrand.name === "purple";
193
+ if (mode === "light") {
194
+ const active2 = color.hex(activeBrand.primary);
195
+ const prompt2 = isPurple ? color.hex("#006699") : active2;
196
+ const number2 = isPurple ? color.hex("#0077cc") : active2;
197
+ return withStyles(
198
+ {
199
+ header: (text5) => active2.bold(text5),
200
+ divider: (text5) => color.hex("#666666")(text5),
201
+ prompt: (text5) => prompt2.bold(text5),
202
+ number: (text5) => number2.bold(text5),
203
+ intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
204
+ get resolvedSymbol() {
205
+ return active2("\u25C7");
206
+ },
207
+ get errorSymbol() {
208
+ return color.hex("#cc0000")("\u25A0");
209
+ },
210
+ accent: (text5) => prompt2.bold(text5),
211
+ muted: (text5) => color.hex("#666666")(text5),
212
+ success: (text5) => color.hex("#008800")(text5),
213
+ warning: (text5) => color.hex("#cc6600")(text5),
214
+ error: (text5) => color.hex("#cc0000")(text5),
215
+ info: (text5) => active2(text5),
216
+ badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
217
+ },
218
+ {
219
+ accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
220
+ muted: { fg: "#666666" },
221
+ success: { fg: "#008800" },
222
+ warning: { fg: "#cc6600" },
223
+ error: { fg: "#cc0000" },
224
+ info: { fg: activeBrand.primary }
225
+ }
226
+ );
227
+ }
228
+ const active = brandColor(activeBrand, color.magenta);
229
+ const activeBright = brandColor(activeBrand, color.magentaBright);
230
+ const activeBackground = brandBackground(activeBrand, color.bgMagenta);
231
+ const prompt = isPurple ? color.cyan : active;
232
+ const number = isPurple ? color.cyanBright : active;
233
+ return withStyles(
234
+ {
235
+ header: (text5) => activeBright.bold(text5),
236
+ divider: (text5) => color.dim(text5),
237
+ prompt: (text5) => prompt(text5),
238
+ number: (text5) => number(text5),
239
+ intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
240
+ get resolvedSymbol() {
241
+ return active("\u25C7");
242
+ },
243
+ get errorSymbol() {
244
+ return color.red("\u25A0");
245
+ },
246
+ accent: (text5) => prompt(text5),
247
+ muted: (text5) => color.dim(text5),
248
+ success: (text5) => color.green(text5),
249
+ warning: (text5) => color.yellow(text5),
250
+ error: (text5) => color.red(text5),
251
+ info: (text5) => active(text5),
252
+ badge: (text5) => color.bgYellow.black(` ${text5} `)
253
+ },
254
+ {
255
+ accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
256
+ muted: { dim: true },
257
+ success: { fg: "green" },
258
+ warning: { fg: "yellow" },
259
+ error: { fg: "red" },
260
+ info: { fg: isPurple ? "magenta" : activeBrand.primary }
261
+ }
262
+ );
263
+ }
264
+ var dark = createPalette(brands.purple, "dark");
265
+ var light = createPalette(brands.purple, "light");
172
266
 
173
- // ../design-system/src/tokens/typography.ts
267
+ // ../toolcraft-design/src/tokens/typography.ts
174
268
  var typography = {
175
269
  bold: (text5) => color.bold(text5),
176
270
  dim: (text5) => color.dim(text5),
@@ -179,14 +273,14 @@ var typography = {
179
273
  strikethrough: (text5) => color.strikethrough(text5)
180
274
  };
181
275
 
182
- // ../design-system/src/tokens/widths.ts
276
+ // ../toolcraft-design/src/tokens/widths.ts
183
277
  var widths = {
184
278
  header: 60,
185
279
  helpColumn: 24,
186
280
  maxLine: 80
187
281
  };
188
282
 
189
- // ../design-system/src/internal/output-format.ts
283
+ // ../toolcraft-design/src/internal/output-format.ts
190
284
  import { AsyncLocalStorage } from "node:async_hooks";
191
285
  var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
192
286
  var formatStorage = new AsyncLocalStorage();
@@ -207,7 +301,7 @@ function resetOutputFormatCache() {
207
301
  cached = void 0;
208
302
  }
209
303
 
210
- // ../design-system/src/internal/theme-detect.ts
304
+ // ../toolcraft-design/src/internal/theme-detect.ts
211
305
  function detectThemeFromEnv(env) {
212
306
  const apple = env.APPLE_INTERFACE_STYLE;
213
307
  if (typeof apple === "string") {
@@ -244,17 +338,30 @@ function resolveThemeName(env = process.env) {
244
338
  }
245
339
  return "dark";
246
340
  }
247
- var cachedTheme;
341
+ var themeCache = /* @__PURE__ */ new Map();
342
+ var cachedRevision = -1;
248
343
  function getTheme(env) {
344
+ const themeName = resolveThemeName(env);
345
+ const config2 = getThemeConfig();
346
+ const requestedBrand = env?.POE_BRAND?.toLowerCase();
347
+ const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
348
+ const revision2 = getThemeRevision();
349
+ if (revision2 !== cachedRevision) {
350
+ themeCache.clear();
351
+ cachedRevision = revision2;
352
+ }
353
+ const cacheKey = `${activeBrandName}:${themeName}`;
354
+ const cachedTheme = themeCache.get(cacheKey);
249
355
  if (cachedTheme) {
250
356
  return cachedTheme;
251
357
  }
252
- const themeName = resolveThemeName(env);
253
- cachedTheme = themeName === "light" ? light : dark;
254
- return cachedTheme;
358
+ const activeBrand = brands[activeBrandName];
359
+ const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
360
+ themeCache.set(cacheKey, theme);
361
+ return theme;
255
362
  }
256
363
 
257
- // ../design-system/src/components/text.ts
364
+ // ../toolcraft-design/src/components/text.ts
258
365
  function renderMarkdownInline(content) {
259
366
  return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
260
367
  }
@@ -370,7 +477,7 @@ var text = {
370
477
  }
371
478
  };
372
479
 
373
- // ../design-system/src/components/symbols.ts
480
+ // ../toolcraft-design/src/components/symbols.ts
374
481
  var symbols = {
375
482
  get info() {
376
483
  const format = resolveOutputFormat();
@@ -424,12 +531,12 @@ var symbols = {
424
531
  }
425
532
  };
426
533
 
427
- // ../design-system/src/internal/strip-ansi.ts
534
+ // ../toolcraft-design/src/internal/strip-ansi.ts
428
535
  function stripAnsi(value) {
429
536
  return value.replace(/\u001b\[[0-9;]*m/g, "");
430
537
  }
431
538
 
432
- // ../design-system/src/prompts/primitives/log.ts
539
+ // ../toolcraft-design/src/prompts/primitives/log.ts
433
540
  function renderMarkdownInline2(value) {
434
541
  return stripAnsi(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
435
542
  }
@@ -556,7 +663,7 @@ var log = {
556
663
  error
557
664
  };
558
665
 
559
- // ../design-system/src/components/logger.ts
666
+ // ../toolcraft-design/src/components/logger.ts
560
667
  function createLogger(emitter) {
561
668
  const emit = (level, message2) => {
562
669
  if (emitter) {
@@ -617,7 +724,7 @@ function createLogger(emitter) {
617
724
  }
618
725
  var logger = createLogger();
619
726
 
620
- // ../design-system/src/components/help-formatter.ts
727
+ // ../toolcraft-design/src/components/help-formatter.ts
621
728
  var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
622
729
  function normalizeInline(value) {
623
730
  return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
@@ -793,7 +900,7 @@ function formatOptionList(options) {
793
900
  });
794
901
  }
795
902
 
796
- // ../design-system/src/components/help-formatter-plain.ts
903
+ // ../toolcraft-design/src/components/help-formatter-plain.ts
797
904
  var help_formatter_plain_exports = {};
798
905
  __export(help_formatter_plain_exports, {
799
906
  formatColumns: () => formatColumns2,
@@ -930,7 +1037,7 @@ function formatOptionList2(options) {
930
1037
  });
931
1038
  }
932
1039
 
933
- // ../design-system/src/components/table.ts
1040
+ // ../toolcraft-design/src/components/table.ts
934
1041
  var reset2 = "\x1B[0m";
935
1042
  var ellipsis = "\u2026";
936
1043
  var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -1214,7 +1321,7 @@ function renderTable(options) {
1214
1321
  }
1215
1322
  }
1216
1323
 
1217
- // ../design-system/src/components/detail-card.ts
1324
+ // ../toolcraft-design/src/components/detail-card.ts
1218
1325
  function wrap(value, width) {
1219
1326
  const lines = [];
1220
1327
  for (const paragraph of value.split("\n")) {
@@ -1277,7 +1384,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
1277
1384
  return blocks.join("\n\n");
1278
1385
  }
1279
1386
 
1280
- // ../design-system/src/components/template.ts
1387
+ // ../toolcraft-design/src/components/template.ts
1281
1388
  var MAX_PARTIAL_DEPTH = 100;
1282
1389
  var HTML_ESCAPE = {
1283
1390
  "&": "&",
@@ -1689,22 +1796,22 @@ function hasProperty(value, key2) {
1689
1796
  return Object.prototype.hasOwnProperty.call(value, key2);
1690
1797
  }
1691
1798
 
1692
- // ../design-system/src/components/browser.ts
1799
+ // ../toolcraft-design/src/components/browser.ts
1693
1800
  import { spawn } from "node:child_process";
1694
1801
  import process2 from "node:process";
1695
1802
 
1696
- // ../design-system/src/acp/writer.ts
1803
+ // ../toolcraft-design/src/acp/writer.ts
1697
1804
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
1698
1805
  var storage = new AsyncLocalStorage2();
1699
1806
 
1700
- // ../design-system/src/dashboard/terminal-width.ts
1807
+ // ../toolcraft-design/src/dashboard/terminal-width.ts
1701
1808
  var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1702
1809
 
1703
- // ../design-system/src/dashboard/terminal.ts
1810
+ // ../toolcraft-design/src/dashboard/terminal.ts
1704
1811
  import readline from "node:readline";
1705
1812
  import { PassThrough } from "node:stream";
1706
1813
 
1707
- // ../design-system/src/explorer/state.ts
1814
+ // ../toolcraft-design/src/explorer/state.ts
1708
1815
  var REGION_HEADER = 1 << 0;
1709
1816
  var REGION_LIST = 1 << 1;
1710
1817
  var REGION_DETAIL = 1 << 2;
@@ -1713,10 +1820,10 @@ var REGION_MODAL = 1 << 4;
1713
1820
  var REGION_TOAST = 1 << 5;
1714
1821
  var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
1715
1822
 
1716
- // ../design-system/src/prompts/index.ts
1823
+ // ../toolcraft-design/src/prompts/index.ts
1717
1824
  import * as clack from "@clack/prompts";
1718
1825
 
1719
- // ../design-system/src/prompts/primitives/cancel.ts
1826
+ // ../toolcraft-design/src/prompts/primitives/cancel.ts
1720
1827
  import { isCancel } from "@clack/prompts";
1721
1828
  function cancel(msg = "") {
1722
1829
  if (resolveOutputFormat() !== "terminal") {
@@ -1727,7 +1834,7 @@ function cancel(msg = "") {
1727
1834
  `);
1728
1835
  }
1729
1836
 
1730
- // ../design-system/src/prompts/primitives/note.ts
1837
+ // ../toolcraft-design/src/prompts/primitives/note.ts
1731
1838
  function getVisibleWidth(value) {
1732
1839
  return stripAnsi(value).length;
1733
1840
  }
@@ -1776,10 +1883,10 @@ function note(message2, title) {
1776
1883
  `);
1777
1884
  }
1778
1885
 
1779
- // ../design-system/src/static/spinner.ts
1886
+ // ../toolcraft-design/src/static/spinner.ts
1780
1887
  var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
1781
1888
 
1782
- // ../design-system/src/prompts/index.ts
1889
+ // ../toolcraft-design/src/prompts/index.ts
1783
1890
  async function select2(opts) {
1784
1891
  return clack.select(opts);
1785
1892
  }
@@ -1822,19 +1929,19 @@ var ApprovalDeclinedError = class extends UserError {
1822
1929
  };
1823
1930
 
1824
1931
  // ../toolcraft/src/human-in-loop/config.ts
1825
- function validateHumanInLoopOnDefine(config) {
1826
- const label = Array.isArray(config.children) ? "group" : "command";
1827
- if (config.confirm === true && config.humanInLoop !== void 0 && config.humanInLoop !== null) {
1828
- throw new Error(`${label} '${config.name}': use either confirm or humanInLoop, not both`);
1932
+ function validateHumanInLoopOnDefine(config2) {
1933
+ const label = Array.isArray(config2.children) ? "group" : "command";
1934
+ if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
1935
+ throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
1829
1936
  }
1830
- if (config.humanInLoop === void 0 || config.humanInLoop === null) {
1937
+ if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
1831
1938
  return;
1832
1939
  }
1833
- if (config.humanInLoop.mode !== "sync" && config.humanInLoop.mode !== "async") {
1834
- throw new Error(`${label} '${config.name}': humanInLoop.mode must be "sync" or "async"`);
1940
+ if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
1941
+ throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
1835
1942
  }
1836
- if (typeof config.humanInLoop.message !== "function") {
1837
- throw new Error(`${label} '${config.name}': humanInLoop.message must be a function`);
1943
+ if (typeof config2.humanInLoop.message !== "function") {
1944
+ throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
1838
1945
  }
1839
1946
  }
1840
1947
  function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
@@ -1910,12 +2017,12 @@ function assertValidBranches(branches, discriminator) {
1910
2017
  }
1911
2018
  }
1912
2019
  }
1913
- function OneOf(config) {
1914
- assertValidBranches(config.branches, config.discriminator);
2020
+ function OneOf(config2) {
2021
+ assertValidBranches(config2.branches, config2.discriminator);
1915
2022
  return {
1916
2023
  kind: "oneOf",
1917
- discriminator: config.discriminator,
1918
- branches: config.branches
2024
+ discriminator: config2.discriminator,
2025
+ branches: config2.branches
1919
2026
  };
1920
2027
  }
1921
2028
 
@@ -2165,22 +2272,22 @@ function cloneStringArray(values) {
2165
2272
  function cloneStringRecord(values) {
2166
2273
  return values === void 0 ? void 0 : { ...values };
2167
2274
  }
2168
- function cloneMcpServerConfig(config) {
2169
- if (config === void 0) {
2275
+ function cloneMcpServerConfig(config2) {
2276
+ if (config2 === void 0) {
2170
2277
  return void 0;
2171
2278
  }
2172
- if (config.transport === "stdio") {
2279
+ if (config2.transport === "stdio") {
2173
2280
  return {
2174
2281
  transport: "stdio",
2175
- command: config.command,
2176
- args: cloneStringArray(config.args),
2177
- env: cloneStringRecord(config.env)
2282
+ command: config2.command,
2283
+ args: cloneStringArray(config2.args),
2284
+ env: cloneStringRecord(config2.env)
2178
2285
  };
2179
2286
  }
2180
2287
  return {
2181
2288
  transport: "http",
2182
- url: config.url,
2183
- headers: cloneStringRecord(config.headers)
2289
+ url: config2.url,
2290
+ headers: cloneStringRecord(config2.headers)
2184
2291
  };
2185
2292
  }
2186
2293
  function cloneRenameMap(rename5) {
@@ -2421,57 +2528,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
2421
2528
  function resolveGroupScope(ownScope, inheritedScope) {
2422
2529
  return cloneScope(ownScope ?? inheritedScope);
2423
2530
  }
2424
- function createBaseCommand(config) {
2531
+ function createBaseCommand(config2) {
2425
2532
  const command = {
2426
2533
  kind: "command",
2427
- name: config.name,
2428
- description: config.description,
2429
- aliases: [...config.aliases ?? []],
2430
- positional: [...config.positional ?? []],
2431
- params: config.params,
2432
- secrets: cloneSecrets(config.secrets),
2433
- scope: resolveCommandScope(config.scope, void 0),
2434
- confirm: config.confirm ?? false,
2435
- humanInLoop: config.humanInLoop,
2436
- requires: cloneRequires(config.requires),
2437
- handler: config.handler,
2438
- render: config.render
2534
+ name: config2.name,
2535
+ description: config2.description,
2536
+ aliases: [...config2.aliases ?? []],
2537
+ positional: [...config2.positional ?? []],
2538
+ params: config2.params,
2539
+ secrets: cloneSecrets(config2.secrets),
2540
+ scope: resolveCommandScope(config2.scope, void 0),
2541
+ confirm: config2.confirm ?? false,
2542
+ humanInLoop: config2.humanInLoop,
2543
+ requires: cloneRequires(config2.requires),
2544
+ handler: config2.handler,
2545
+ render: config2.render
2439
2546
  };
2440
2547
  Object.defineProperty(command, commandConfigSymbol, {
2441
2548
  value: {
2442
- scope: cloneScope(config.scope),
2443
- humanInLoop: config.humanInLoop,
2444
- secrets: cloneSecrets(config.secrets),
2445
- requires: cloneRequires(config.requires),
2549
+ scope: cloneScope(config2.scope),
2550
+ humanInLoop: config2.humanInLoop,
2551
+ secrets: cloneSecrets(config2.secrets),
2552
+ requires: cloneRequires(config2.requires),
2446
2553
  sourcePath: inferCommandSourcePath()
2447
2554
  }
2448
2555
  });
2449
2556
  return command;
2450
2557
  }
2451
- function createBaseGroup(config) {
2558
+ function createBaseGroup(config2) {
2452
2559
  const group = {
2453
2560
  kind: "group",
2454
- name: config.name,
2455
- description: config.description,
2456
- aliases: [...config.aliases ?? []],
2457
- scope: resolveGroupScope(config.scope, void 0),
2458
- humanInLoop: config.humanInLoop,
2459
- secrets: cloneSecrets(config.secrets),
2460
- requires: cloneRequires(config.requires),
2561
+ name: config2.name,
2562
+ description: config2.description,
2563
+ aliases: [...config2.aliases ?? []],
2564
+ scope: resolveGroupScope(config2.scope, void 0),
2565
+ humanInLoop: config2.humanInLoop,
2566
+ secrets: cloneSecrets(config2.secrets),
2567
+ requires: cloneRequires(config2.requires),
2461
2568
  children: [],
2462
2569
  default: void 0
2463
2570
  };
2464
2571
  Object.defineProperty(group, groupConfigSymbol, {
2465
2572
  value: {
2466
- mcp: cloneMcpServerConfig(config.mcp),
2467
- scope: cloneScope(config.scope),
2468
- humanInLoop: config.humanInLoop,
2469
- secrets: cloneSecrets(config.secrets),
2470
- tools: cloneStringArray(config.tools),
2471
- rename: cloneRenameMap(config.rename),
2472
- requires: cloneRequires(config.requires),
2473
- children: [...config.children],
2474
- default: config.default
2573
+ mcp: cloneMcpServerConfig(config2.mcp),
2574
+ scope: cloneScope(config2.scope),
2575
+ humanInLoop: config2.humanInLoop,
2576
+ secrets: cloneSecrets(config2.secrets),
2577
+ tools: cloneStringArray(config2.tools),
2578
+ rename: cloneRenameMap(config2.rename),
2579
+ requires: cloneRequires(config2.requires),
2580
+ children: [...config2.children],
2581
+ default: config2.default
2475
2582
  }
2476
2583
  });
2477
2584
  return group;
@@ -2574,10 +2681,10 @@ function materializeNode(node, inherited) {
2574
2681
  }
2575
2682
  return materializeGroup(node, inherited);
2576
2683
  }
2577
- function defineCommand(config) {
2578
- validateHumanInLoopOnDefine(config);
2684
+ function defineCommand(config2) {
2685
+ validateHumanInLoopOnDefine(config2);
2579
2686
  return materializeCommand(
2580
- createBaseCommand(config),
2687
+ createBaseCommand(config2),
2581
2688
  {
2582
2689
  scope: void 0,
2583
2690
  humanInLoop: void 0,
@@ -2586,10 +2693,10 @@ function defineCommand(config) {
2586
2693
  }
2587
2694
  );
2588
2695
  }
2589
- function defineGroup(config) {
2590
- validateRenameMap(config.rename);
2591
- validateHumanInLoopOnDefine(config);
2592
- return materializeGroup(createBaseGroup(config), {
2696
+ function defineGroup(config2) {
2697
+ validateRenameMap(config2.rename);
2698
+ validateHumanInLoopOnDefine(config2);
2699
+ return materializeGroup(createBaseGroup(config2), {
2593
2700
  scope: void 0,
2594
2701
  humanInLoop: void 0,
2595
2702
  secrets: {},
@@ -2620,27 +2727,27 @@ function validateMachine(machine) {
2620
2727
  if (!isRecord(machine)) {
2621
2728
  throw new TypeError("State machine must be an object.");
2622
2729
  }
2623
- if (!isStateList(machine.states)) {
2730
+ if (!hasOwnRecordField(machine, "states") || !isStateList(machine.states)) {
2624
2731
  throw new TypeError("State machine states must be a string array.");
2625
2732
  }
2626
2733
  const states = new Set(machine.states);
2627
- if (typeof machine.initial !== "string") {
2734
+ if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
2628
2735
  throw new TypeError("State machine initial must be a string.");
2629
2736
  }
2630
2737
  if (!states.has(machine.initial)) {
2631
2738
  throw new Error(`Initial state "${machine.initial}" is not declared.`);
2632
2739
  }
2633
- if (!isRecord(machine.events)) {
2740
+ if (!hasOwnRecordField(machine, "events") || !isRecord(machine.events)) {
2634
2741
  throw new TypeError("State machine events must be an object.");
2635
2742
  }
2636
2743
  for (const [eventName, event] of Object.entries(machine.events)) {
2637
2744
  if (!isRecord(event)) {
2638
2745
  throw new TypeError(`Event "${eventName}" must be an object.`);
2639
2746
  }
2640
- if (event.from !== "*" && !isStateList(event.from)) {
2747
+ if (!hasOwnRecordField(event, "from") || event.from !== "*" && !isStateList(event.from)) {
2641
2748
  throw new TypeError(`Event "${eventName}" has an invalid "from" definition.`);
2642
2749
  }
2643
- if (typeof event.to !== "string") {
2750
+ if (!hasOwnRecordField(event, "to") || typeof event.to !== "string") {
2644
2751
  throw new TypeError(`Event "${eventName}" target state must be a string.`);
2645
2752
  }
2646
2753
  if (!states.has(event.to)) {
@@ -2655,6 +2762,9 @@ function validateMachine(machine) {
2655
2762
  }
2656
2763
  }
2657
2764
  }
2765
+ function hasOwnRecordField(record, key2) {
2766
+ return Object.prototype.hasOwnProperty.call(record, key2);
2767
+ }
2658
2768
  function eventsFromState(machine, fromState) {
2659
2769
  const events = [];
2660
2770
  for (const [eventName, event] of Object.entries(machine.events)) {
@@ -2758,7 +2868,7 @@ import path3 from "node:path";
2758
2868
  // ../process-runner/src/docker/docker-execution-env.ts
2759
2869
  import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
2760
2870
  import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
2761
- import { readdir, readFile, writeFile } from "node:fs/promises";
2871
+ import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
2762
2872
  import { tmpdir as tmpdir2 } from "node:os";
2763
2873
  import path5 from "node:path";
2764
2874
 
@@ -2926,6 +3036,7 @@ function resolveEndpoint(options = {}) {
2926
3036
  }
2927
3037
 
2928
3038
  // ../task-list/src/backends/utils.ts
3039
+ import { randomUUID as randomUUID2 } from "node:crypto";
2929
3040
  import path6 from "node:path";
2930
3041
  function compareCreated(left, right) {
2931
3042
  const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
@@ -2946,9 +3057,8 @@ function applyOrder(entries, order) {
2946
3057
  }
2947
3058
  return entries.map((entry) => entry.task);
2948
3059
  }
2949
- var tmpFileCounter = 0;
2950
3060
  function hasErrorCode(error3, code) {
2951
- return !!error3 && typeof error3 === "object" && "code" in error3 && error3.code === code;
3061
+ return !!error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
2952
3062
  }
2953
3063
  function isRecord2(value) {
2954
3064
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -2995,18 +3105,22 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
2995
3105
  }
2996
3106
  }
2997
3107
  async function writeAtomically(fs4, filePath, content) {
2998
- const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
2999
- tmpFileCounter += 1;
3108
+ const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
3109
+ let tempCreated = false;
3000
3110
  await fs4.mkdir(path6.dirname(filePath), { recursive: true });
3001
3111
  try {
3002
3112
  await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
3113
+ tempCreated = true;
3003
3114
  await fs4.rename(tempPath, filePath);
3115
+ tempCreated = false;
3004
3116
  } catch (error3) {
3005
- try {
3006
- await fs4.unlink(tempPath);
3007
- } catch (unlinkError) {
3008
- if (!hasErrorCode(unlinkError, "ENOENT")) {
3009
- throw unlinkError;
3117
+ if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
3118
+ try {
3119
+ await fs4.unlink(tempPath);
3120
+ } catch (unlinkError) {
3121
+ if (!hasErrorCode(unlinkError, "ENOENT")) {
3122
+ throw unlinkError;
3123
+ }
3010
3124
  }
3011
3125
  }
3012
3126
  throw error3;
@@ -3020,6 +3134,7 @@ async function withFileLock(fs4, lockPath, operation) {
3020
3134
  break;
3021
3135
  } catch (error3) {
3022
3136
  if (!hasErrorCode(error3, "EEXIST")) {
3137
+ await fs4.unlink(lockPath).catch(() => void 0);
3023
3138
  throw error3;
3024
3139
  }
3025
3140
  if (await removeAbandonedLock(fs4, lockPath)) {
@@ -4303,27 +4418,30 @@ function readFrontmatter(frontmatterContent, filePath) {
4303
4418
  return parsed;
4304
4419
  }
4305
4420
  function assertValidTaskRecord(frontmatter, filePath, validStates) {
4306
- if ("$schema" in frontmatter && frontmatter.$schema !== TASK_SCHEMA_ID) {
4421
+ if (hasOwnTaskField(frontmatter, "$schema") && frontmatter.$schema !== TASK_SCHEMA_ID) {
4307
4422
  throw malformedTask(filePath, "$schema");
4308
4423
  }
4309
- if ("kind" in frontmatter && frontmatter.kind !== TASK_KIND) {
4424
+ if (hasOwnTaskField(frontmatter, "kind") && frontmatter.kind !== TASK_KIND) {
4310
4425
  throw malformedTask(filePath, "kind");
4311
4426
  }
4312
- if ("version" in frontmatter) {
4427
+ if (hasOwnTaskField(frontmatter, "version")) {
4313
4428
  if (typeof frontmatter.version !== "number" || !Number.isInteger(frontmatter.version) || frontmatter.version !== TASK_VERSION) {
4314
4429
  throw malformedTask(filePath, "version");
4315
4430
  }
4316
4431
  }
4317
- if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
4432
+ if (!hasOwnTaskField(frontmatter, "name") || typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
4318
4433
  throw malformedTask(filePath, "name");
4319
4434
  }
4320
- if (typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
4435
+ if (!hasOwnTaskField(frontmatter, "state") || typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
4321
4436
  throw malformedTask(filePath, "state");
4322
4437
  }
4323
- if ("description" in frontmatter && typeof frontmatter.description !== "string") {
4438
+ if (hasOwnTaskField(frontmatter, "description") && typeof frontmatter.description !== "string") {
4324
4439
  throw malformedTask(filePath, "description");
4325
4440
  }
4326
4441
  }
4442
+ function hasOwnTaskField(frontmatter, key2) {
4443
+ return Object.prototype.hasOwnProperty.call(frontmatter, key2);
4444
+ }
4327
4445
  function reservedFrontmatterKeys(mode) {
4328
4446
  return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
4329
4447
  }
@@ -4446,7 +4564,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
4446
4564
  }
4447
4565
  return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
4448
4566
  }
4449
- function createdFrontmatter(defaults, input, initialState, mode) {
4567
+ function createdFrontmatter(defaults2, input, initialState, mode) {
4450
4568
  const frontmatter = mode !== "passthrough" ? {
4451
4569
  $schema: TASK_SCHEMA_ID,
4452
4570
  kind: TASK_KIND,
@@ -4458,7 +4576,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
4458
4576
  state: initialState
4459
4577
  };
4460
4578
  const reservedKeys = reservedFrontmatterKeys(mode);
4461
- for (const [key2, value] of Object.entries(defaults.metadata)) {
4579
+ for (const [key2, value] of Object.entries(defaults2.metadata)) {
4462
4580
  if (!reservedKeys.has(key2)) {
4463
4581
  setOwnValue(frontmatter, key2, value);
4464
4582
  }
@@ -5172,7 +5290,8 @@ function parseQualifiedId3(qualifiedId) {
5172
5290
  };
5173
5291
  }
5174
5292
  function descriptionFromTaskRecord(taskRecord) {
5175
- return typeof taskRecord.description === "string" ? taskRecord.description : "";
5293
+ const description = getOwnEntry(taskRecord, "description");
5294
+ return typeof description === "string" ? description : "";
5176
5295
  }
5177
5296
  function metadataFromTaskRecord(taskRecord) {
5178
5297
  const metadata = /* @__PURE__ */ Object.create(null);
@@ -5188,8 +5307,8 @@ function createTask2(list, id, taskRecord, sourcePath) {
5188
5307
  list,
5189
5308
  id,
5190
5309
  qualifiedId: `${list}/${id}`,
5191
- name: taskRecord.name,
5192
- state: taskRecord.state,
5310
+ name: getOwnEntry(taskRecord, "name"),
5311
+ state: getOwnEntry(taskRecord, "state"),
5193
5312
  description: descriptionFromTaskRecord(taskRecord),
5194
5313
  metadata: metadataFromTaskRecord(taskRecord),
5195
5314
  ...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
@@ -5204,13 +5323,13 @@ function matchesFilter(task, filter) {
5204
5323
  }
5205
5324
  return true;
5206
5325
  }
5207
- function createTaskRecord(defaults, input, initialState) {
5326
+ function createTaskRecord(defaults2, input, initialState) {
5208
5327
  const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
5209
5328
  name: input.name,
5210
5329
  state: initialState,
5211
5330
  description: input.description ?? ""
5212
5331
  });
5213
- for (const [key2, value] of Object.entries(defaults.metadata)) {
5332
+ for (const [key2, value] of Object.entries(defaults2.metadata)) {
5214
5333
  if (!RESERVED_TASK_KEYS.has(key2)) {
5215
5334
  taskRecord[key2] = value;
5216
5335
  }
@@ -5286,16 +5405,17 @@ function assertValidStoreRecord(store, filePath) {
5286
5405
  if (!isRecord2(store)) {
5287
5406
  throw malformedStore(filePath, "store");
5288
5407
  }
5289
- if (store.$schema !== STORE_SCHEMA_ID) {
5408
+ if (getOwnEntry(store, "$schema") !== STORE_SCHEMA_ID) {
5290
5409
  throw malformedStore(filePath, "$schema");
5291
5410
  }
5292
- if (store.kind !== STORE_KIND) {
5411
+ if (getOwnEntry(store, "kind") !== STORE_KIND) {
5293
5412
  throw malformedStore(filePath, "kind");
5294
5413
  }
5295
- if (typeof store.version !== "number" || !Number.isInteger(store.version) || store.version !== STORE_VERSION) {
5414
+ const version = getOwnEntry(store, "version");
5415
+ if (typeof version !== "number" || !Number.isInteger(version) || version !== STORE_VERSION) {
5296
5416
  throw malformedStore(filePath, "version");
5297
5417
  }
5298
- if (!isRecord2(store.lists)) {
5418
+ if (!isRecord2(getOwnEntry(store, "lists"))) {
5299
5419
  throw malformedStore(filePath, "lists");
5300
5420
  }
5301
5421
  }
@@ -5303,29 +5423,38 @@ function assertValidTaskRecord2(taskRecord, list, id, validStates) {
5303
5423
  if (!isRecord2(taskRecord)) {
5304
5424
  throw malformedTask2(list, id, "task");
5305
5425
  }
5306
- if ("$schema" in taskRecord && taskRecord.$schema !== TASK_SCHEMA_ID2) {
5426
+ if (hasOwnTaskField2(taskRecord, "$schema") && getOwnEntry(taskRecord, "$schema") !== TASK_SCHEMA_ID2) {
5307
5427
  throw malformedTask2(list, id, "$schema");
5308
5428
  }
5309
- if ("kind" in taskRecord && taskRecord.kind !== TASK_KIND2) {
5429
+ if (hasOwnTaskField2(taskRecord, "kind") && getOwnEntry(taskRecord, "kind") !== TASK_KIND2) {
5310
5430
  throw malformedTask2(list, id, "kind");
5311
5431
  }
5312
- if ("version" in taskRecord) {
5313
- if (typeof taskRecord.version !== "number" || !Number.isInteger(taskRecord.version) || taskRecord.version !== TASK_VERSION2) {
5432
+ if (hasOwnTaskField2(taskRecord, "version")) {
5433
+ const version = getOwnEntry(taskRecord, "version");
5434
+ if (typeof version !== "number" || !Number.isInteger(version) || version !== TASK_VERSION2) {
5314
5435
  throw malformedTask2(list, id, "version");
5315
5436
  }
5316
5437
  }
5317
- if (typeof taskRecord.name !== "string" || taskRecord.name.length === 0) {
5438
+ const name = getOwnEntry(taskRecord, "name");
5439
+ if (!hasOwnTaskField2(taskRecord, "name") || typeof name !== "string" || name.length === 0) {
5318
5440
  throw malformedTask2(list, id, "name");
5319
5441
  }
5320
- if (typeof taskRecord.state !== "string" || !validStates.has(taskRecord.state)) {
5442
+ const state = getOwnEntry(taskRecord, "state");
5443
+ if (!hasOwnTaskField2(taskRecord, "state") || typeof state !== "string" || !validStates.has(state)) {
5321
5444
  throw malformedTask2(list, id, "state");
5322
5445
  }
5323
- if ("description" in taskRecord && typeof taskRecord.description !== "string") {
5446
+ if (hasOwnTaskField2(taskRecord, "description") && typeof getOwnEntry(taskRecord, "description") !== "string") {
5324
5447
  throw malformedTask2(list, id, "description");
5325
5448
  }
5326
5449
  }
5450
+ function hasOwnTaskField2(taskRecord, key2) {
5451
+ return Object.prototype.hasOwnProperty.call(taskRecord, key2);
5452
+ }
5453
+ function getOwnEntry(record, key2) {
5454
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
5455
+ }
5327
5456
  function validateStoreEntries(store, filePath, validStates) {
5328
- const lists = store.lists;
5457
+ const lists = getOwnEntry(store, "lists");
5329
5458
  if (!isRecord2(lists)) {
5330
5459
  throw malformedStore(filePath, "lists");
5331
5460
  }
@@ -5365,10 +5494,11 @@ async function readStore(fs4, filePath, validStates) {
5365
5494
  };
5366
5495
  }
5367
5496
  function getListsRecord(store) {
5368
- return store.lists;
5497
+ const lists = getOwnEntry(store, "lists");
5498
+ return isRecord2(lists) ? lists : {};
5369
5499
  }
5370
5500
  function getListRecord(store, list) {
5371
- const listRecord = getListsRecord(store)[list];
5501
+ const listRecord = getOwnEntry(getListsRecord(store), list);
5372
5502
  return isRecord2(listRecord) ? listRecord : void 0;
5373
5503
  }
5374
5504
  function getTaskRecord(store, list, id) {
@@ -5661,7 +5791,7 @@ async function yamlFileBackend(deps) {
5661
5791
  const result = [];
5662
5792
  const listNames = sortStrings(Object.keys(getListsRecord(store)));
5663
5793
  for (const listName of listNames) {
5664
- const listRecord = getListsRecord(store)[listName];
5794
+ const listRecord = getOwnEntry(getListsRecord(store), listName);
5665
5795
  if (!isRecord2(listRecord)) continue;
5666
5796
  const entries = Object.entries(listRecord).map(([id, taskRecord]) => ({
5667
5797
  task: createTask2(listName, id, taskRecord, deps.path),
@@ -6295,8 +6425,8 @@ function createHandlerContext(command, params17) {
6295
6425
  function createFs() {
6296
6426
  return {
6297
6427
  readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
6298
- writeFile: async (path24, contents) => {
6299
- await writeFile2(path24, contents);
6428
+ writeFile: async (path24, contents, options) => {
6429
+ await writeFile2(path24, contents, options);
6300
6430
  },
6301
6431
  exists: async (path24) => {
6302
6432
  try {
@@ -6584,17 +6714,17 @@ function isMissingStateError(error3) {
6584
6714
  }
6585
6715
 
6586
6716
  // ../toolcraft/src/error-report.ts
6587
- import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
6588
- import { randomUUID as randomUUID3 } from "node:crypto";
6717
+ import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
6718
+ import { randomUUID as randomUUID5 } from "node:crypto";
6589
6719
  import os from "node:os";
6590
6720
  import path13 from "node:path";
6591
6721
  import { CommanderError } from "commander";
6592
6722
 
6593
6723
  // ../toolcraft/src/mcp-proxy.ts
6594
6724
  import { existsSync as existsSync2 } from "node:fs";
6595
- import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
6725
+ import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
6596
6726
  import path12 from "node:path";
6597
- import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
6727
+ import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
6598
6728
 
6599
6729
  // ../tiny-mcp-client/src/internal.ts
6600
6730
  import { spawn as spawn5 } from "node:child_process";
@@ -6605,7 +6735,7 @@ import crypto from "node:crypto";
6605
6735
  import path11 from "node:path";
6606
6736
 
6607
6737
  // ../auth-store/src/encrypted-file-store.ts
6608
- import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
6738
+ import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
6609
6739
  import { promises as fs } from "node:fs";
6610
6740
  import { homedir, hostname, userInfo } from "node:os";
6611
6741
  import path10 from "node:path";
@@ -6616,7 +6746,6 @@ var ENCRYPTION_KEY_BYTES = 32;
6616
6746
  var ENCRYPTION_IV_BYTES = 12;
6617
6747
  var ENCRYPTION_AUTH_TAG_BYTES = 16;
6618
6748
  var ENCRYPTION_FILE_MODE = 384;
6619
- var temporaryFileSequence = 0;
6620
6749
  var EncryptedFileStore = class {
6621
6750
  fs;
6622
6751
  filePath;
@@ -6648,7 +6777,7 @@ var EncryptedFileStore = class {
6648
6777
  this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
6649
6778
  }
6650
6779
  async get() {
6651
- await this.assertRegularCredentialPath();
6780
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6652
6781
  let rawDocument;
6653
6782
  try {
6654
6783
  rawDocument = await this.fs.readFile(this.filePath, "utf8");
@@ -6679,7 +6808,7 @@ var EncryptedFileStore = class {
6679
6808
  }
6680
6809
  }
6681
6810
  async set(value) {
6682
- await this.assertRegularCredentialPath();
6811
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6683
6812
  const key2 = await this.getEncryptionKey();
6684
6813
  const iv = this.getRandomBytes(ENCRYPTION_IV_BYTES);
6685
6814
  const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key2, iv);
@@ -6695,25 +6824,28 @@ var EncryptedFileStore = class {
6695
6824
  ciphertext: ciphertext.toString("base64")
6696
6825
  };
6697
6826
  await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
6698
- await this.assertRegularCredentialPath();
6699
- const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
6827
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6828
+ const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
6829
+ let temporaryCreated = false;
6700
6830
  try {
6831
+ await this.assertCredentialPathHasNoSymbolicLinks(temporaryPath);
6701
6832
  await this.fs.writeFile(temporaryPath, JSON.stringify(document), {
6702
6833
  encoding: "utf8",
6703
6834
  flag: "wx",
6704
6835
  mode: ENCRYPTION_FILE_MODE
6705
6836
  });
6837
+ temporaryCreated = true;
6706
6838
  await this.fs.chmod(temporaryPath, ENCRYPTION_FILE_MODE);
6707
6839
  await this.fs.rename(temporaryPath, this.filePath);
6708
6840
  } catch (error3) {
6709
- if (!isAlreadyExistsError(error3)) {
6841
+ if (temporaryCreated || !isAlreadyExistsError(error3)) {
6710
6842
  await removeIfPresent(this.fs, temporaryPath).catch(() => void 0);
6711
6843
  }
6712
6844
  throw error3;
6713
6845
  }
6714
6846
  }
6715
6847
  async delete() {
6716
- await this.assertRegularCredentialPath();
6848
+ await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
6717
6849
  try {
6718
6850
  await this.fs.unlink(this.filePath);
6719
6851
  } catch (error3) {
@@ -6722,8 +6854,8 @@ var EncryptedFileStore = class {
6722
6854
  }
6723
6855
  }
6724
6856
  }
6725
- async assertRegularCredentialPath() {
6726
- const resolvedPath = path10.resolve(this.filePath);
6857
+ async assertCredentialPathHasNoSymbolicLinks(targetPath) {
6858
+ const resolvedPath = path10.resolve(targetPath);
6727
6859
  const protectedPaths = getProtectedCredentialPaths(
6728
6860
  resolvedPath,
6729
6861
  this.symbolicLinkCheckStartPath
@@ -6788,9 +6920,6 @@ async function removeIfPresent(fileSystem, filePath) {
6788
6920
  }
6789
6921
  }
6790
6922
  }
6791
- function isAlreadyExistsError(error3) {
6792
- return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "EEXIST";
6793
- }
6794
6923
  function defaultMachineIdentity() {
6795
6924
  return {
6796
6925
  hostname: hostname(),
@@ -6828,17 +6957,21 @@ function parseEncryptedDocument(raw) {
6828
6957
  if (!isRecord4(parsed)) {
6829
6958
  return null;
6830
6959
  }
6831
- if (parsed.version !== ENCRYPTION_VERSION) {
6960
+ const version = getOwnEntry2(parsed, "version");
6961
+ const iv = getOwnEntry2(parsed, "iv");
6962
+ const authTag = getOwnEntry2(parsed, "authTag");
6963
+ const ciphertext = getOwnEntry2(parsed, "ciphertext");
6964
+ if (version !== ENCRYPTION_VERSION) {
6832
6965
  return null;
6833
6966
  }
6834
- if (typeof parsed.iv !== "string" || typeof parsed.authTag !== "string" || typeof parsed.ciphertext !== "string") {
6967
+ if (typeof iv !== "string" || typeof authTag !== "string" || typeof ciphertext !== "string") {
6835
6968
  return null;
6836
6969
  }
6837
6970
  return {
6838
- version: parsed.version,
6839
- iv: parsed.iv,
6840
- authTag: parsed.authTag,
6841
- ciphertext: parsed.ciphertext
6971
+ version,
6972
+ iv,
6973
+ authTag,
6974
+ ciphertext
6842
6975
  };
6843
6976
  } catch {
6844
6977
  return null;
@@ -6847,9 +6980,17 @@ function parseEncryptedDocument(raw) {
6847
6980
  function isRecord4(value) {
6848
6981
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
6849
6982
  }
6983
+ function getOwnEntry2(record, key2) {
6984
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
6985
+ }
6850
6986
  function isNotFoundError(error3) {
6851
6987
  return Boolean(
6852
- error3 && typeof error3 === "object" && "code" in error3 && error3.code === "ENOENT"
6988
+ error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT"
6989
+ );
6990
+ }
6991
+ function isAlreadyExistsError(error3) {
6992
+ return Boolean(
6993
+ error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST"
6853
6994
  );
6854
6995
  }
6855
6996
 
@@ -6871,8 +7012,8 @@ var KeychainStore = class {
6871
7012
  ["find-generic-password", "-s", this.service, "-a", this.account, "-w"],
6872
7013
  "read secret from macOS Keychain"
6873
7014
  );
6874
- if (result.exitCode === 0) {
6875
- return stripTrailingLineBreak(result.stdout);
7015
+ if (getCommandExitCode(result) === 0) {
7016
+ return stripTrailingLineBreak(getCommandOutput(result, "stdout"));
6876
7017
  }
6877
7018
  if (isKeychainEntryNotFound(result)) {
6878
7019
  return null;
@@ -6896,7 +7037,7 @@ var KeychainStore = class {
6896
7037
  "store secret in macOS Keychain",
6897
7038
  { stdin: value }
6898
7039
  );
6899
- if (result.exitCode !== 0) {
7040
+ if (getCommandExitCode(result) !== 0) {
6900
7041
  throw createSecurityCliFailure("store secret in macOS Keychain", result);
6901
7042
  }
6902
7043
  }
@@ -6905,7 +7046,7 @@ var KeychainStore = class {
6905
7046
  ["delete-generic-password", "-s", this.service, "-a", this.account],
6906
7047
  "delete secret from macOS Keychain"
6907
7048
  );
6908
- if (result.exitCode === 0 || isKeychainEntryNotFound(result)) {
7049
+ if (getCommandExitCode(result) === 0 || isKeychainEntryNotFound(result)) {
6909
7050
  return;
6910
7051
  }
6911
7052
  throw createSecurityCliFailure("delete secret from macOS Keychain", result);
@@ -6984,16 +7125,28 @@ function stripTrailingLineBreak(value) {
6984
7125
  return value;
6985
7126
  }
6986
7127
  function isKeychainEntryNotFound(result) {
6987
- return result.exitCode === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
7128
+ return getCommandExitCode(result) === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
6988
7129
  }
6989
7130
  function createSecurityCliFailure(operation, result) {
6990
- const details = result.stderr.trim() || result.stdout.trim();
7131
+ const exitCode = getCommandExitCode(result);
7132
+ const details = getCommandOutput(result, "stderr").trim() || getCommandOutput(result, "stdout").trim();
6991
7133
  if (details) {
6992
7134
  return new Error(
6993
- `Failed to ${operation}: security exited with code ${result.exitCode}: ${details}`
7135
+ `Failed to ${operation}: security exited with code ${exitCode}: ${details}`
6994
7136
  );
6995
7137
  }
6996
- return new Error(`Failed to ${operation}: security exited with code ${result.exitCode}`);
7138
+ return new Error(`Failed to ${operation}: security exited with code ${exitCode}`);
7139
+ }
7140
+ function getCommandExitCode(result) {
7141
+ const value = getOwnEntry3(result, "exitCode");
7142
+ return typeof value === "number" && Number.isInteger(value) ? value : 1;
7143
+ }
7144
+ function getCommandOutput(result, key2) {
7145
+ const value = getOwnEntry3(result, key2);
7146
+ return typeof value === "string" ? value : "";
7147
+ }
7148
+ function getOwnEntry3(record, key2) {
7149
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
6997
7150
  }
6998
7151
 
6999
7152
  // ../auth-store/src/create-secret-store.ts
@@ -7026,7 +7179,7 @@ function createSecretStore(input) {
7026
7179
  }
7027
7180
  function resolveBackend(input) {
7028
7181
  const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
7029
- const configuredBackend = input.backend ?? input.env?.[envVar] ?? process.env[envVar];
7182
+ const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
7030
7183
  if (configuredBackend === "keychain") {
7031
7184
  return "keychain";
7032
7185
  }
@@ -7035,6 +7188,9 @@ function resolveBackend(input) {
7035
7188
  }
7036
7189
  throw new Error(`Unsupported auth store backend: ${configuredBackend}`);
7037
7190
  }
7191
+ function getOwnEnvValue(env, key2) {
7192
+ return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
7193
+ }
7038
7194
 
7039
7195
  // ../mcp-oauth/src/resource-indicator.ts
7040
7196
  function canonicalizeResourceIndicator(value) {
@@ -7088,8 +7244,13 @@ function createAuthStoreClientStore(options) {
7088
7244
  return null;
7089
7245
  }
7090
7246
  const parsed = JSON.parse(value);
7091
- if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && typeof parsed.clientId === "string") {
7092
- return parsed;
7247
+ const clientId = isObjectRecord(parsed) ? getOwnString(parsed, "clientId") : void 0;
7248
+ if (clientId !== void 0) {
7249
+ const client = { clientId };
7250
+ if (isObjectRecord(parsed) && Object.prototype.hasOwnProperty.call(parsed, "clientSecret")) {
7251
+ client.clientSecret = getOwnEntry4(parsed, "clientSecret");
7252
+ }
7253
+ return client;
7093
7254
  }
7094
7255
  throw new Error("Stored OAuth client must be a JSON object with clientId");
7095
7256
  },
@@ -7103,19 +7264,24 @@ function createAuthStoreClientStore(options) {
7103
7264
  }
7104
7265
  };
7105
7266
  }
7106
- function createNamedSecretStore(key2, options, defaults) {
7267
+ function createNamedSecretStore(key2, options, defaults2) {
7107
7268
  const hash = crypto.createHash("sha256").update(key2).digest("hex");
7108
- const parsedFilePath = options.fileStore?.filePath === void 0 ? null : path11.parse(options.fileStore.filePath);
7269
+ const configuredFilePath = options.fileStore?.filePath;
7270
+ const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
7109
7271
  const fileStore = {
7110
7272
  ...options.fileStore,
7111
- salt: options.fileStore?.salt ?? defaults.salt,
7112
- defaultDirectory: parsedFilePath?.dir || options.fileStore?.defaultDirectory || defaults.directory,
7273
+ filePath: parsedFilePath === null ? void 0 : path11.join(
7274
+ parsedFilePath.dir,
7275
+ `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
7276
+ ),
7277
+ salt: options.fileStore?.salt ?? defaults2.salt,
7278
+ defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
7113
7279
  defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
7114
7280
  };
7115
7281
  const keychainStore = {
7116
7282
  ...options.keychainStore,
7117
- service: options.keychainStore?.service ?? defaults.service,
7118
- account: `${options.keychainStore?.account ?? defaults.accountPrefix}:${hash}`
7283
+ service: options.keychainStore?.service ?? defaults2.service,
7284
+ account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
7119
7285
  };
7120
7286
  return createSecretStore({ ...options, fileStore, keychainStore }).store;
7121
7287
  }
@@ -7143,6 +7309,16 @@ function createIssuerSecretStore(issuer, options) {
7143
7309
  }
7144
7310
  );
7145
7311
  }
7312
+ function isObjectRecord(value) {
7313
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7314
+ }
7315
+ function getOwnEntry4(record, key2) {
7316
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7317
+ }
7318
+ function getOwnString(record, key2) {
7319
+ const value = getOwnEntry4(record, key2);
7320
+ return typeof value === "string" ? value : void 0;
7321
+ }
7146
7322
 
7147
7323
  // ../mcp-oauth/src/client/default-oauth-client-provider.ts
7148
7324
  import { URL as URL2 } from "node:url";
@@ -7168,17 +7344,30 @@ function parseAuthorizationState(value) {
7168
7344
  try {
7169
7345
  const decoded = Buffer.from(value, "base64url").toString("utf8");
7170
7346
  const parsed = JSON.parse(decoded);
7171
- if (parsed.v !== 1 || typeof parsed.n !== "string" || parsed.n.length === 0 || typeof parsed.i !== "string" || parsed.i.length === 0 || typeof parsed.r !== "boolean") {
7347
+ if (!isObjectRecord2(parsed)) {
7348
+ return null;
7349
+ }
7350
+ const version = getOwnEntry5(parsed, "v");
7351
+ const nonce = getOwnEntry5(parsed, "n");
7352
+ const issuer = getOwnEntry5(parsed, "i");
7353
+ const requireIssuer = getOwnEntry5(parsed, "r");
7354
+ if (version !== 1 || typeof nonce !== "string" || nonce.length === 0 || typeof issuer !== "string" || issuer.length === 0 || typeof requireIssuer !== "boolean") {
7172
7355
  return null;
7173
7356
  }
7174
7357
  return {
7175
- issuer: parsed.i,
7176
- requireIssuer: parsed.r
7358
+ issuer,
7359
+ requireIssuer
7177
7360
  };
7178
7361
  } catch {
7179
7362
  return null;
7180
7363
  }
7181
7364
  }
7365
+ function isObjectRecord2(value) {
7366
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7367
+ }
7368
+ function getOwnEntry5(record, key2) {
7369
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7370
+ }
7182
7371
 
7183
7372
  // ../mcp-oauth/src/client/loopback-authorization.ts
7184
7373
  async function createLoopbackAuthorizationSession(options = {}) {
@@ -7455,22 +7644,26 @@ async function requestTokens(input) {
7455
7644
  body: body.toString()
7456
7645
  });
7457
7646
  const payload = await readOAuthJsonObjectResponse(response);
7458
- if (typeof payload.access_token !== "string" || payload.access_token.trim().length === 0) {
7647
+ const accessToken = getOwnEntry6(payload, "access_token");
7648
+ if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
7459
7649
  throw new Error("OAuth token response missing access_token");
7460
7650
  }
7461
- const tokenType = normalizeBearerTokenType(payload.token_type);
7651
+ const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
7462
7652
  if (tokenType === null) {
7463
7653
  throw new Error("OAuth token response missing token_type=Bearer");
7464
7654
  }
7465
- if (typeof payload.expires_in === "number" && Number.isFinite(payload.expires_in) && payload.expires_in < 0) {
7655
+ const expiresIn = getOwnEntry6(payload, "expires_in");
7656
+ if (typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn < 0) {
7466
7657
  throw new Error("OAuth token response has invalid expires_in");
7467
7658
  }
7659
+ const refreshToken = getOwnEntry6(payload, "refresh_token");
7660
+ const scope = getOwnEntry6(payload, "scope");
7468
7661
  return {
7469
- accessToken: payload.access_token,
7470
- refreshToken: typeof payload.refresh_token === "string" && payload.refresh_token.length > 0 ? payload.refresh_token : void 0,
7662
+ accessToken,
7663
+ refreshToken: typeof refreshToken === "string" && refreshToken.length > 0 ? refreshToken : void 0,
7471
7664
  tokenType,
7472
- expiresAt: typeof payload.expires_in === "number" && Number.isFinite(payload.expires_in) ? input.now() + payload.expires_in * 1e3 : null,
7473
- scope: typeof payload.scope === "string" && payload.scope.length > 0 ? payload.scope : void 0
7665
+ expiresAt: typeof expiresIn === "number" && Number.isFinite(expiresIn) ? input.now() + expiresIn * 1e3 : null,
7666
+ scope: typeof scope === "string" && scope.length > 0 ? scope : void 0
7474
7667
  };
7475
7668
  }
7476
7669
  async function readOAuthJsonObjectResponse(response) {
@@ -7497,12 +7690,18 @@ async function readOAuthJsonObjectResponse(response) {
7497
7690
  return record;
7498
7691
  }
7499
7692
  function readOAuthError(payload, fallbackError = "server_error") {
7693
+ const error3 = getOwnEntry6(payload, "error");
7694
+ const errorDescription = getOwnEntry6(payload, "error_description");
7695
+ const errorUri = getOwnEntry6(payload, "error_uri");
7500
7696
  return {
7501
- error: typeof payload.error === "string" ? payload.error : fallbackError,
7502
- error_description: typeof payload.error_description === "string" ? payload.error_description : void 0,
7503
- error_uri: typeof payload.error_uri === "string" ? payload.error_uri : void 0
7697
+ error: typeof error3 === "string" ? error3 : fallbackError,
7698
+ error_description: typeof errorDescription === "string" ? errorDescription : void 0,
7699
+ error_uri: typeof errorUri === "string" ? errorUri : void 0
7504
7700
  };
7505
7701
  }
7702
+ function getOwnEntry6(record, key2) {
7703
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
7704
+ }
7506
7705
  function createFallbackOAuthError(status) {
7507
7706
  const error3 = status === 503 ? "temporarily_unavailable" : "server_error";
7508
7707
  return new OAuthError({ error: error3 }, status);
@@ -7607,7 +7806,11 @@ function createDefaultOAuthClientProvider(options) {
7607
7806
  while (true) {
7608
7807
  try {
7609
7808
  refreshedTokens = await refreshAccessToken({
7610
- tokenEndpoint: discovery.authorizationServerMetadata.token_endpoint,
7809
+ tokenEndpoint: requireOwnString(
7810
+ discovery.authorizationServerMetadata,
7811
+ "token_endpoint",
7812
+ "Authorization server metadata"
7813
+ ),
7611
7814
  clientId: session.client.clientId,
7612
7815
  clientSecret: session.client.clientSecret,
7613
7816
  refreshToken: session.tokens.refreshToken,
@@ -7695,7 +7898,11 @@ function createDefaultOAuthClientProvider(options) {
7695
7898
  });
7696
7899
  const code = await loopback.waitForCode(authorizationUrl);
7697
7900
  const tokens = await exchangeAuthorizationCode({
7698
- tokenEndpoint: discovery.authorizationServerMetadata.token_endpoint,
7901
+ tokenEndpoint: requireOwnString(
7902
+ discovery.authorizationServerMetadata,
7903
+ "token_endpoint",
7904
+ "Authorization server metadata"
7905
+ ),
7699
7906
  clientId: resolvedClient.client.clientId,
7700
7907
  clientSecret: resolvedClient.client.clientSecret,
7701
7908
  code,
@@ -7748,7 +7955,10 @@ function createDefaultOAuthClientProvider(options) {
7748
7955
  }
7749
7956
  };
7750
7957
  }
7751
- const registrationEndpoint = discovery.authorizationServerMetadata.registration_endpoint;
7958
+ const registrationEndpoint = getOwnString2(
7959
+ discovery.authorizationServerMetadata,
7960
+ "registration_endpoint"
7961
+ );
7752
7962
  if (registrationEndpoint === void 0 && options.client.clientId !== void 0) {
7753
7963
  return {
7754
7964
  kind: "static",
@@ -7800,12 +8010,14 @@ function createDefaultOAuthClientProvider(options) {
7800
8010
  body: JSON.stringify(registrationBody)
7801
8011
  });
7802
8012
  const payload = await readOAuthJsonObjectResponse(response);
7803
- if (typeof payload.client_id !== "string" || payload.client_id.trim().length === 0) {
8013
+ const clientId = getOwnString2(payload, "client_id");
8014
+ if (clientId === void 0 || clientId.trim().length === 0) {
7804
8015
  throw new Error("OAuth client registration response missing client_id");
7805
8016
  }
8017
+ const clientSecret = getOwnString2(payload, "client_secret");
7806
8018
  const registeredClient = {
7807
- clientId: payload.client_id,
7808
- clientSecret: typeof payload.client_secret === "string" && payload.client_secret.length > 0 ? payload.client_secret : void 0
8019
+ clientId,
8020
+ clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
7809
8021
  };
7810
8022
  await saveRegisteredClient(discovery.authorizationServer, registeredClient);
7811
8023
  return {
@@ -7831,12 +8043,13 @@ function createDefaultOAuthClientProvider(options) {
7831
8043
  return null;
7832
8044
  }
7833
8045
  const client = await clientStore.load(issuer);
7834
- if (client !== null && !isUsableClient(client)) {
8046
+ const normalizedClient = client === null ? null : normalizeStoredClient(client);
8047
+ if (client !== null && normalizedClient === null) {
7835
8048
  await clientStore.clear(issuer);
7836
8049
  return null;
7837
8050
  }
7838
- registeredClients.set(issuer, client);
7839
- return client;
8051
+ registeredClients.set(issuer, normalizedClient);
8052
+ return normalizedClient;
7840
8053
  }
7841
8054
  async function saveRegisteredClient(issuer, client) {
7842
8055
  registeredClients.set(issuer, client);
@@ -7852,7 +8065,7 @@ function createDefaultOAuthClientProvider(options) {
7852
8065
  }
7853
8066
  }
7854
8067
  function isProviderOptions(options) {
7855
- return "provider" in options;
8068
+ return Object.prototype.hasOwnProperty.call(options, "provider");
7856
8069
  }
7857
8070
  function isExpired(tokens, now) {
7858
8071
  return tokens.expiresAt !== null && tokens.expiresAt <= now();
@@ -7868,7 +8081,14 @@ function resolveDiscovery(discovery, session) {
7868
8081
  return void 0;
7869
8082
  }
7870
8083
  const metadata = session.discovery.authorizationServerMetadata;
7871
- if (typeof metadata.issuer !== "string" || typeof metadata.authorization_endpoint !== "string" || typeof metadata.token_endpoint !== "string" || !Array.isArray(metadata.code_challenge_methods_supported) || !metadata.code_challenge_methods_supported.includes("S256")) {
8084
+ const issuer = getOwnString2(metadata, "issuer");
8085
+ const authorizationEndpoint = getOwnString2(metadata, "authorization_endpoint");
8086
+ const tokenEndpoint = getOwnString2(metadata, "token_endpoint");
8087
+ const codeChallengeMethodsSupported = getOwnStringArray(
8088
+ metadata,
8089
+ "code_challenge_methods_supported"
8090
+ );
8091
+ if (issuer === void 0 || authorizationEndpoint === void 0 || tokenEndpoint === void 0 || codeChallengeMethodsSupported === void 0 || !codeChallengeMethodsSupported.includes("S256")) {
7872
8092
  return void 0;
7873
8093
  }
7874
8094
  return {
@@ -7892,29 +8112,94 @@ function normalizeLoadedSession(session) {
7892
8112
  if (session === null) {
7893
8113
  return null;
7894
8114
  }
7895
- if (!isUsableClient(session.client)) {
8115
+ const client = normalizeStoredClient(getOwnEntry7(session, "client"));
8116
+ if (client === null) {
7896
8117
  return { ...session, client: { clientId: "" }, tokens: void 0 };
7897
8118
  }
7898
- return isUsableTokens(session.tokens) ? session : { ...session, tokens: void 0 };
8119
+ return {
8120
+ ...session,
8121
+ client,
8122
+ tokens: normalizeStoredTokens(getOwnEntry7(session, "tokens"))
8123
+ };
7899
8124
  }
7900
- function isUsableClient(client) {
7901
- return typeof client.clientId === "string" && client.clientId.trim().length > 0 && (client.clientSecret === void 0 || typeof client.clientSecret === "string" && client.clientSecret.trim().length > 0);
8125
+ function normalizeStoredClient(value) {
8126
+ if (!isObjectRecord3(value)) {
8127
+ return null;
8128
+ }
8129
+ const clientId = getOwnString2(value, "clientId");
8130
+ if (clientId === void 0 || clientId.trim().length === 0) {
8131
+ return null;
8132
+ }
8133
+ const clientSecret = getOwnEntry7(value, "clientSecret");
8134
+ if (clientSecret === void 0) {
8135
+ return { clientId };
8136
+ }
8137
+ if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
8138
+ return null;
8139
+ }
8140
+ return { clientId, clientSecret };
7902
8141
  }
7903
- function isUsableTokens(tokens) {
7904
- if (tokens === void 0) {
7905
- return true;
8142
+ function normalizeStoredTokens(value) {
8143
+ if (value === void 0 || !isObjectRecord3(value)) {
8144
+ return void 0;
8145
+ }
8146
+ const accessToken = getOwnString2(value, "accessToken");
8147
+ const tokenType = getOwnString2(value, "tokenType");
8148
+ const expiresAt = getOwnEntry7(value, "expiresAt");
8149
+ const refreshToken = getOwnEntry7(value, "refreshToken");
8150
+ const scope = getOwnString2(value, "scope");
8151
+ const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken : void 0;
8152
+ if (accessToken === void 0 || accessToken.trim().length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isFinite(expiresAt)) || refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
8153
+ return void 0;
7906
8154
  }
7907
- return typeof tokens.accessToken === "string" && tokens.accessToken.trim().length > 0 && tokens.tokenType === "Bearer" && (tokens.expiresAt === null || typeof tokens.expiresAt === "number" && Number.isFinite(tokens.expiresAt)) && (tokens.refreshToken === void 0 || typeof tokens.refreshToken === "string" && tokens.refreshToken.trim().length > 0);
8155
+ return {
8156
+ accessToken,
8157
+ tokenType,
8158
+ expiresAt,
8159
+ ...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
8160
+ ...scope === void 0 || scope.length === 0 ? {} : { scope }
8161
+ };
7908
8162
  }
7909
8163
  function getClientMetadata(client) {
7910
8164
  return client.metadata;
7911
8165
  }
8166
+ function getOwnEntry7(record, key2) {
8167
+ return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
8168
+ }
8169
+ function isObjectRecord3(value) {
8170
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8171
+ }
8172
+ function getOwnString2(record, key2) {
8173
+ const value = getOwnEntry7(record, key2);
8174
+ return typeof value === "string" ? value : void 0;
8175
+ }
8176
+ function requireOwnString(record, key2, label) {
8177
+ const value = getOwnString2(record, key2);
8178
+ if (value === void 0) {
8179
+ throw new Error(`${label} is missing ${key2}`);
8180
+ }
8181
+ return value;
8182
+ }
8183
+ function getOwnStringArray(record, key2) {
8184
+ const value = getOwnEntry7(record, key2);
8185
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
8186
+ }
7912
8187
  function buildAuthorizationUrl(input) {
7913
- const url = new URL2(input.metadata.authorization_endpoint);
8188
+ const authorizationEndpoint = requireOwnString(
8189
+ input.metadata,
8190
+ "authorization_endpoint",
8191
+ "Authorization server metadata"
8192
+ );
8193
+ const issuer = requireOwnString(
8194
+ input.metadata,
8195
+ "issuer",
8196
+ "Authorization server metadata"
8197
+ );
8198
+ const url = new URL2(authorizationEndpoint);
7914
8199
  const resource = canonicalizeResourceIndicator(input.resource);
7915
8200
  const state = createAuthorizationState({
7916
- issuer: input.metadata.issuer,
7917
- requireIssuer: input.metadata.authorization_response_iss_parameter_supported === true
8201
+ issuer,
8202
+ requireIssuer: getOwnEntry7(input.metadata, "authorization_response_iss_parameter_supported") === true
7918
8203
  });
7919
8204
  url.searchParams.set("response_type", "code");
7920
8205
  url.searchParams.set("client_id", input.clientId);
@@ -7929,7 +8214,7 @@ function buildAuthorizationUrl(input) {
7929
8214
  return url.toString();
7930
8215
  }
7931
8216
  function assertS256PkceSupport(metadata) {
7932
- if (!metadata.code_challenge_methods_supported.includes("S256")) {
8217
+ if (!getOwnStringArray(metadata, "code_challenge_methods_supported")?.includes("S256")) {
7933
8218
  throw new Error(
7934
8219
  "Authorization server metadata must advertise code_challenge_methods_supported including S256"
7935
8220
  );
@@ -7953,13 +8238,24 @@ function assertSecureUrl(value, label) {
7953
8238
  throw new Error(`${label} must use https unless it targets a loopback host`);
7954
8239
  }
7955
8240
  function assertSecureOAuthFlowEndpoints(metadata) {
7956
- assertNoAccessTokenInUrl(metadata.authorization_endpoint, "Authorization endpoint");
7957
- assertNoAccessTokenInUrl(metadata.token_endpoint, "Token endpoint");
7958
- assertSecureUrl(metadata.authorization_endpoint, "Authorization endpoint");
7959
- assertSecureUrl(metadata.token_endpoint, "Token endpoint");
7960
- if (metadata.registration_endpoint !== void 0) {
7961
- assertNoAccessTokenInUrl(metadata.registration_endpoint, "Registration endpoint");
7962
- assertSecureUrl(metadata.registration_endpoint, "Registration endpoint");
8241
+ const authorizationEndpoint = requireOwnString(
8242
+ metadata,
8243
+ "authorization_endpoint",
8244
+ "Authorization server metadata"
8245
+ );
8246
+ const tokenEndpoint = requireOwnString(
8247
+ metadata,
8248
+ "token_endpoint",
8249
+ "Authorization server metadata"
8250
+ );
8251
+ const registrationEndpoint = getOwnString2(metadata, "registration_endpoint");
8252
+ assertNoAccessTokenInUrl(authorizationEndpoint, "Authorization endpoint");
8253
+ assertNoAccessTokenInUrl(tokenEndpoint, "Token endpoint");
8254
+ assertSecureUrl(authorizationEndpoint, "Authorization endpoint");
8255
+ assertSecureUrl(tokenEndpoint, "Token endpoint");
8256
+ if (registrationEndpoint !== void 0) {
8257
+ assertNoAccessTokenInUrl(registrationEndpoint, "Registration endpoint");
8258
+ assertSecureUrl(registrationEndpoint, "Registration endpoint");
7963
8259
  }
7964
8260
  }
7965
8261
  function assertNoAccessTokenInUrl(value, label) {
@@ -7982,17 +8278,21 @@ function buildClientRegistrationBody(metadata, redirectUri) {
7982
8278
  response_types: ["code"],
7983
8279
  token_endpoint_auth_method: "none"
7984
8280
  };
7985
- if (metadata?.clientName !== void 0 && metadata.clientName.length > 0) {
7986
- body.client_name = metadata.clientName;
8281
+ const clientName = metadata === void 0 ? void 0 : getOwnString2(metadata, "clientName");
8282
+ const scope = metadata === void 0 ? void 0 : getOwnString2(metadata, "scope");
8283
+ const softwareId = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareId");
8284
+ const softwareVersion = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareVersion");
8285
+ if (clientName !== void 0 && clientName.length > 0) {
8286
+ body.client_name = clientName;
7987
8287
  }
7988
- if (metadata?.scope !== void 0 && metadata.scope.length > 0) {
7989
- body.scope = metadata.scope;
8288
+ if (scope !== void 0 && scope.length > 0) {
8289
+ body.scope = scope;
7990
8290
  }
7991
- if (metadata?.softwareId !== void 0 && metadata.softwareId.length > 0) {
7992
- body.software_id = metadata.softwareId;
8291
+ if (softwareId !== void 0 && softwareId.length > 0) {
8292
+ body.software_id = softwareId;
7993
8293
  }
7994
- if (metadata?.softwareVersion !== void 0 && metadata.softwareVersion.length > 0) {
7995
- body.software_version = metadata.softwareVersion;
8294
+ if (softwareVersion !== void 0 && softwareVersion.length > 0) {
8295
+ body.software_version = softwareVersion;
7996
8296
  }
7997
8297
  return body;
7998
8298
  }
@@ -8028,7 +8328,7 @@ import {
8028
8328
  function defaultOAuthMetadataFetch(input, init) {
8029
8329
  return fetch(input, init);
8030
8330
  }
8031
- function isObjectRecord(value) {
8331
+ function isObjectRecord4(value) {
8032
8332
  return typeof value === "object" && value !== null && !Array.isArray(value);
8033
8333
  }
8034
8334
  function isStringArray(value) {
@@ -8051,7 +8351,7 @@ function assertSecureUrl2(url, label) {
8051
8351
  throw new Error(`${label} must use https unless it targets a loopback host`);
8052
8352
  }
8053
8353
  function validateProtectedResourceMetadata(value, resourceUrl) {
8054
- if (!isObjectRecord(value)) {
8354
+ if (!isObjectRecord4(value)) {
8055
8355
  throw new Error("Protected resource metadata must be a JSON object");
8056
8356
  }
8057
8357
  if (typeof value.resource !== "string" || value.resource.length === 0) {
@@ -8074,7 +8374,7 @@ function validateProtectedResourceMetadata(value, resourceUrl) {
8074
8374
  };
8075
8375
  }
8076
8376
  function validateAuthorizationServerMetadata(value, issuer) {
8077
- if (!isObjectRecord(value)) {
8377
+ if (!isObjectRecord4(value)) {
8078
8378
  throw new Error("Authorization server metadata must be a JSON object");
8079
8379
  }
8080
8380
  if (typeof value.issuer !== "string" || value.issuer.length === 0) {
@@ -8527,7 +8827,7 @@ var McpClient = class {
8527
8827
  await onPromptsChanged();
8528
8828
  });
8529
8829
  messageLayer.onNotification("notifications/message", async (params17) => {
8530
- if (onLog === void 0 || !isObjectRecord2(params17) || !isLogLevel(params17.level)) {
8830
+ if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
8531
8831
  return;
8532
8832
  }
8533
8833
  if (!hasOwn(params17, "data")) {
@@ -8546,7 +8846,7 @@ var McpClient = class {
8546
8846
  await onLog(message2);
8547
8847
  });
8548
8848
  messageLayer.onNotification("notifications/progress", async (params17) => {
8549
- if (onProgress === void 0 || !isObjectRecord2(params17)) {
8849
+ if (onProgress === void 0 || !isObjectRecord5(params17)) {
8550
8850
  return;
8551
8851
  }
8552
8852
  const { progressToken, progress } = params17;
@@ -8715,6 +9015,9 @@ var McpClient = class {
8715
9015
  const abortPromise = new Promise((_, reject) => {
8716
9016
  const rejectWithAbortReason = () => {
8717
9017
  sendCancellationNotification();
9018
+ if (requestId !== void 0) {
9019
+ messageLayer.cancelRequest(requestId, signal.reason);
9020
+ }
8718
9021
  reject(signal.reason);
8719
9022
  };
8720
9023
  abortListener = rejectWithAbortReason;
@@ -8889,11 +9192,13 @@ var StdioTransport = class _StdioTransport {
8889
9192
  const child = this.child;
8890
9193
  this.readable = child.stdout;
8891
9194
  this.writable = child.stdin;
9195
+ const stderrDecoder = new TextDecoder();
8892
9196
  child.stderr.on("data", (chunk) => {
8893
- this.stderrOutput += chunkToString(chunk);
8894
- if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
8895
- this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
8896
- }
9197
+ const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
9198
+ this.appendStderrOutput(decoded);
9199
+ });
9200
+ child.stderr.once("end", () => {
9201
+ this.appendStderrOutput(stderrDecoder.decode());
8897
9202
  });
8898
9203
  this.closed = new Promise((resolve) => {
8899
9204
  let settled = false;
@@ -8933,6 +9238,15 @@ var StdioTransport = class _StdioTransport {
8933
9238
  getStderrOutput() {
8934
9239
  return this.stderrOutput;
8935
9240
  }
9241
+ appendStderrOutput(chunk) {
9242
+ if (chunk.length === 0) {
9243
+ return;
9244
+ }
9245
+ this.stderrOutput += chunk;
9246
+ if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
9247
+ this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
9248
+ }
9249
+ }
8936
9250
  dispose(reason = new Error("Stdio transport disposed")) {
8937
9251
  void reason;
8938
9252
  if (this.disposed) {
@@ -9340,15 +9654,6 @@ function serializeJsonRpcMessage(message2) {
9340
9654
  return `${JSON.stringify(message2)}
9341
9655
  `;
9342
9656
  }
9343
- function chunkToString(chunk) {
9344
- if (typeof chunk === "string") {
9345
- return chunk;
9346
- }
9347
- if (chunk instanceof Uint8Array) {
9348
- return Buffer.from(chunk).toString("utf8");
9349
- }
9350
- return String(chunk);
9351
- }
9352
9657
  function normalizeLine(line) {
9353
9658
  return line.endsWith("\r") ? line.slice(0, -1) : line;
9354
9659
  }
@@ -9538,6 +9843,16 @@ var JsonRpcMessageLayer = class {
9538
9843
  }
9539
9844
  });
9540
9845
  }
9846
+ cancelRequest(requestId, reason) {
9847
+ const pending = this.pendingRequests.get(requestId);
9848
+ if (pending === void 0) {
9849
+ return false;
9850
+ }
9851
+ this.pendingRequests.delete(requestId);
9852
+ clearTimeout(pending.timeout);
9853
+ pending.reject(reason);
9854
+ return true;
9855
+ }
9541
9856
  dispose(reason = new Error("JSON-RPC message layer disposed")) {
9542
9857
  if (this.disposedError !== void 0) {
9543
9858
  return;
@@ -9732,7 +10047,7 @@ var JsonRpcMessageLayer = class {
9732
10047
  })();
9733
10048
  }
9734
10049
  handleCancellationNotification(params17) {
9735
- if (!isObjectRecord2(params17)) {
10050
+ if (!isObjectRecord5(params17)) {
9736
10051
  return;
9737
10052
  }
9738
10053
  const requestId = params17.requestId;
@@ -9747,34 +10062,34 @@ var JsonRpcMessageLayer = class {
9747
10062
  this.activeIncomingRequests.delete(requestId);
9748
10063
  }
9749
10064
  };
9750
- function isObjectRecord2(value) {
10065
+ function isObjectRecord5(value) {
9751
10066
  return typeof value === "object" && value !== null && !Array.isArray(value);
9752
10067
  }
9753
10068
  function isInitializeResult(value) {
9754
- if (!isObjectRecord2(value) || typeof value.protocolVersion !== "string") {
10069
+ if (!isObjectRecord5(value) || typeof value.protocolVersion !== "string") {
9755
10070
  return false;
9756
10071
  }
9757
10072
  if (!isServerCapabilities(value.capabilities)) {
9758
10073
  return false;
9759
10074
  }
9760
- if (!isObjectRecord2(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
10075
+ if (!isObjectRecord5(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
9761
10076
  return false;
9762
10077
  }
9763
10078
  return value.instructions === void 0 || typeof value.instructions === "string";
9764
10079
  }
9765
10080
  function isServerCapabilities(value) {
9766
- if (!isObjectRecord2(value)) {
10081
+ if (!isObjectRecord5(value)) {
9767
10082
  return false;
9768
10083
  }
9769
10084
  for (const capability of ["prompts", "resources", "tools", "logging", "completions", "experimental"]) {
9770
- if (value[capability] !== void 0 && !isObjectRecord2(value[capability])) {
10085
+ if (value[capability] !== void 0 && !isObjectRecord5(value[capability])) {
9771
10086
  return false;
9772
10087
  }
9773
10088
  }
9774
10089
  return true;
9775
10090
  }
9776
10091
  function isCallToolResult(value) {
9777
- if (!isObjectRecord2(value) || !Array.isArray(value.content)) {
10092
+ if (!isObjectRecord5(value) || !Array.isArray(value.content)) {
9778
10093
  return false;
9779
10094
  }
9780
10095
  if (value.isError !== void 0 && typeof value.isError !== "boolean") {
@@ -9783,10 +10098,10 @@ function isCallToolResult(value) {
9783
10098
  return value.content.every(isContentItem);
9784
10099
  }
9785
10100
  function isToolsListResult(value) {
9786
- return isObjectRecord2(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
10101
+ return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
9787
10102
  }
9788
10103
  function isContentItem(value) {
9789
- if (!isObjectRecord2(value)) {
10104
+ if (!isObjectRecord5(value)) {
9790
10105
  return false;
9791
10106
  }
9792
10107
  if (value.type === "text") {
@@ -9795,7 +10110,7 @@ function isContentItem(value) {
9795
10110
  if (value.type === "image" || value.type === "audio") {
9796
10111
  return typeof value.data === "string" && typeof value.mimeType === "string";
9797
10112
  }
9798
- if (value.type !== "resource" || !isObjectRecord2(value.resource)) {
10113
+ if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
9799
10114
  return false;
9800
10115
  }
9801
10116
  return typeof value.resource.uri === "string" && (value.resource.mimeType === void 0 || typeof value.resource.mimeType === "string") && (typeof value.resource.text === "string" || typeof value.resource.blob === "string");
@@ -9819,7 +10134,7 @@ function invalidRequest() {
9819
10134
  return new McpError(ERROR_INVALID_REQUEST, "Invalid Request");
9820
10135
  }
9821
10136
  function isJsonRpcErrorObject(value) {
9822
- if (!isObjectRecord2(value)) {
10137
+ if (!isObjectRecord5(value)) {
9823
10138
  return false;
9824
10139
  }
9825
10140
  if (typeof value.code !== "number" || typeof value.message !== "string") {
@@ -9828,7 +10143,7 @@ function isJsonRpcErrorObject(value) {
9828
10143
  return value.data === void 0 || hasOwn(value, "data");
9829
10144
  }
9830
10145
  function parseJsonRpcPayload(parsed) {
9831
- if (!isObjectRecord2(parsed)) {
10146
+ if (!isObjectRecord5(parsed)) {
9832
10147
  return {
9833
10148
  type: "invalid",
9834
10149
  id: null,
@@ -10155,7 +10470,11 @@ function convertObjectSchema(schema, root, options) {
10155
10470
  "properties",
10156
10471
  key2
10157
10472
  ]);
10158
- shape[key2] = requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty);
10473
+ setOwnShapeProperty(
10474
+ shape,
10475
+ key2,
10476
+ requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty)
10477
+ );
10159
10478
  }
10160
10479
  return applyMetadata(
10161
10480
  S.Object(shape, {
@@ -10167,6 +10486,14 @@ function convertObjectSchema(schema, root, options) {
10167
10486
  }
10168
10487
  );
10169
10488
  }
10489
+ function setOwnShapeProperty(shape, key2, value) {
10490
+ Object.defineProperty(shape, key2, {
10491
+ configurable: true,
10492
+ enumerable: true,
10493
+ writable: true,
10494
+ value
10495
+ });
10496
+ }
10170
10497
  function createCommonOptions(schema, nullable, defaultValue) {
10171
10498
  return {
10172
10499
  ...schema.description === void 0 ? {} : { description: schema.description },
@@ -10417,6 +10744,9 @@ function resolveLocalRef(root, ref) {
10417
10744
  if (!isPlainObject(current)) {
10418
10745
  return void 0;
10419
10746
  }
10747
+ if (!Object.prototype.hasOwnProperty.call(current, segment)) {
10748
+ return void 0;
10749
+ }
10420
10750
  current = current[segment];
10421
10751
  }
10422
10752
  return isPlainObject(current) ? current : void 0;
@@ -10606,10 +10936,10 @@ function validateRenameMap2(name, tools, rename5) {
10606
10936
  }
10607
10937
  }
10608
10938
  }
10609
- function createConnection(name, config) {
10939
+ function createConnection(name, config2) {
10610
10940
  const connection = {
10611
10941
  name,
10612
- config,
10942
+ config: config2,
10613
10943
  async dispose() {
10614
10944
  shutdownDisposers.delete(connection.dispose);
10615
10945
  connection.connecting = void 0;
@@ -10665,24 +10995,42 @@ async function readCache(cachePath) {
10665
10995
  }
10666
10996
  async function writeCache(cachePath, cache) {
10667
10997
  const directory = path12.dirname(cachePath);
10668
- const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
10998
+ const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
10999
+ let tempCreated = false;
10669
11000
  await assertCachePathHasNoSymlinks(cachePath);
10670
11001
  await assertCachePathHasNoSymlinks(tempPath);
10671
11002
  await mkdir(directory, { recursive: true });
10672
11003
  await assertCachePathHasNoSymlinks(directory);
10673
- await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
10674
- `);
10675
- await assertCachePathHasNoSymlinks(tempPath);
10676
- await assertCachePathHasNoSymlinks(cachePath);
10677
- await rename2(tempPath, cachePath);
11004
+ try {
11005
+ await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
11006
+ `, {
11007
+ encoding: "utf8",
11008
+ flag: "wx"
11009
+ });
11010
+ tempCreated = true;
11011
+ await assertCachePathHasNoSymlinks(tempPath);
11012
+ await assertCachePathHasNoSymlinks(cachePath);
11013
+ await rename2(tempPath, cachePath);
11014
+ tempCreated = false;
11015
+ } catch (error3) {
11016
+ if (tempCreated || !isAlreadyExistsError2(error3)) {
11017
+ await unlink2(tempPath).catch(() => void 0);
11018
+ }
11019
+ throw error3;
11020
+ }
10678
11021
  }
10679
- async function fetchCache(name, config) {
11022
+ function isAlreadyExistsError2(error3) {
11023
+ return Boolean(
11024
+ error3 && typeof error3 === "object" && error3.code === "EEXIST"
11025
+ );
11026
+ }
11027
+ async function fetchCache(name, config2) {
10680
11028
  const logger2 = createLogger((message2) => {
10681
11029
  process.stderr.write(`${message2}
10682
11030
  `);
10683
11031
  });
10684
11032
  logger2.info(`MCP ${name}: connecting`);
10685
- const client = await dialUpstream(name, config);
11033
+ const client = await dialUpstream(name, config2);
10686
11034
  try {
10687
11035
  logger2.info(`MCP ${name}: listing tools`);
10688
11036
  const tools = [];
@@ -10701,7 +11049,7 @@ async function fetchCache(name, config) {
10701
11049
  $schema: MCP_PROXY_SCHEMA_URL,
10702
11050
  version: 1,
10703
11051
  upstream,
10704
- configFingerprint: fingerprintMcpServerConfig(config),
11052
+ configFingerprint: fingerprintMcpServerConfig(config2),
10705
11053
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
10706
11054
  tools
10707
11055
  };
@@ -10771,8 +11119,8 @@ function isRefreshRequested(name, refresh) {
10771
11119
  }
10772
11120
  async function resolveSingleProxy(group, options) {
10773
11121
  const internal = getInternalGroupConfig2(group);
10774
- const config = internal.mcp;
10775
- if (config === void 0) {
11122
+ const config2 = internal.mcp;
11123
+ if (config2 === void 0) {
10776
11124
  return;
10777
11125
  }
10778
11126
  const name = group.name;
@@ -10782,21 +11130,21 @@ async function resolveSingleProxy(group, options) {
10782
11130
  let cache;
10783
11131
  let shouldWriteCache = false;
10784
11132
  if (isRefreshRequested(name, refresh)) {
10785
- cache = await fetchCache(name, config);
11133
+ cache = await fetchCache(name, config2);
10786
11134
  shouldWriteCache = true;
10787
11135
  } else {
10788
11136
  const storedCache = await readCache(cachePath);
10789
- if (storedCache && cacheMatchesConfig(storedCache, config)) {
11137
+ if (storedCache && cacheMatchesConfig(storedCache, config2)) {
10790
11138
  cache = storedCache;
10791
11139
  } else {
10792
- cache = await fetchCache(name, config);
11140
+ cache = await fetchCache(name, config2);
10793
11141
  shouldWriteCache = true;
10794
11142
  }
10795
11143
  }
10796
11144
  const tools = filterAllowlistedTools(cache.tools, internal.tools);
10797
11145
  validateRenameMap2(name, tools, internal.rename);
10798
11146
  const previousConnection = getProxyConnection(group);
10799
- const nextConnection = createConnection(name, config);
11147
+ const nextConnection = createConnection(name, config2);
10800
11148
  try {
10801
11149
  replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
10802
11150
  if (shouldWriteCache) {
@@ -10821,11 +11169,11 @@ async function resolveSingleProxy(group, options) {
10821
11169
  );
10822
11170
  }
10823
11171
  }
10824
- function cacheMatchesConfig(cache, config) {
10825
- return cache.configFingerprint === fingerprintMcpServerConfig(config);
11172
+ function cacheMatchesConfig(cache, config2) {
11173
+ return cache.configFingerprint === fingerprintMcpServerConfig(config2);
10826
11174
  }
10827
- function fingerprintMcpServerConfig(config) {
10828
- return createHash3("sha256").update(JSON.stringify(config)).digest("hex");
11175
+ function fingerprintMcpServerConfig(config2) {
11176
+ return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
10829
11177
  }
10830
11178
  function collectProxyGroups(root) {
10831
11179
  const groups = [];
@@ -10903,20 +11251,20 @@ function parseRefreshEnv(value) {
10903
11251
  const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
10904
11252
  return names.length === 0 ? void 0 : new Set(names);
10905
11253
  }
10906
- async function dialUpstream(name, config) {
11254
+ async function dialUpstream(name, config2) {
10907
11255
  const client = new McpClient({
10908
11256
  clientInfo: {
10909
11257
  name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
10910
11258
  version: DEFAULT_CLIENT_INFO.version
10911
11259
  }
10912
11260
  });
10913
- const transport = config.transport === "stdio" ? new StdioTransport({
10914
- command: config.command,
10915
- ...config.args === void 0 ? {} : { args: config.args },
10916
- ...config.env === void 0 ? {} : { env: config.env }
11261
+ const transport = config2.transport === "stdio" ? new StdioTransport({
11262
+ command: config2.command,
11263
+ ...config2.args === void 0 ? {} : { args: config2.args },
11264
+ ...config2.env === void 0 ? {} : { env: config2.env }
10917
11265
  }) : new HttpTransport({
10918
- url: config.url,
10919
- ...config.headers === void 0 ? {} : { headers: config.headers }
11266
+ url: config2.url,
11267
+ ...config2.headers === void 0 ? {} : { headers: config2.headers }
10920
11268
  });
10921
11269
  await client.connect(transport);
10922
11270
  return client;
@@ -10926,10 +11274,82 @@ async function resolveMcpProxies(root, options = {}) {
10926
11274
  await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
10927
11275
  }
10928
11276
 
11277
+ // ../toolcraft/src/redaction.ts
11278
+ var REDACTED_VALUE = "<redacted>";
11279
+ var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
11280
+ var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
11281
+ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
11282
+ function isPlainObject2(value) {
11283
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11284
+ }
11285
+ function normalizeName(name) {
11286
+ return name.toLowerCase().replace(/[^a-z0-9]/g, "");
11287
+ }
11288
+ function isSensitiveName(name) {
11289
+ const normalized = normalizeName(name);
11290
+ return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
11291
+ }
11292
+ function redactSecretLikeFieldsValue(value, name, seen) {
11293
+ if (name.length > 0 && isSensitiveName(name)) {
11294
+ return REDACTED_VALUE;
11295
+ }
11296
+ if (Array.isArray(value)) {
11297
+ if (seen.has(value)) {
11298
+ return "[Circular]";
11299
+ }
11300
+ seen.add(value);
11301
+ return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
11302
+ }
11303
+ if (isPlainObject2(value)) {
11304
+ if (seen.has(value)) {
11305
+ return "[Circular]";
11306
+ }
11307
+ seen.add(value);
11308
+ return Object.fromEntries(
11309
+ Object.entries(value).map(([key2, entry]) => [
11310
+ key2,
11311
+ redactSecretLikeFieldsValue(entry, key2, seen)
11312
+ ])
11313
+ );
11314
+ }
11315
+ return value;
11316
+ }
11317
+ function redactSecretLikeFields(value, name = "") {
11318
+ return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
11319
+ }
11320
+ function parseJsonObjectOrArray(value) {
11321
+ const trimmed = value.trim();
11322
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
11323
+ return void 0;
11324
+ }
11325
+ try {
11326
+ const parsed = JSON.parse(trimmed);
11327
+ return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
11328
+ } catch {
11329
+ return void 0;
11330
+ }
11331
+ }
11332
+ function redactHttpBody(body) {
11333
+ if (typeof body === "string") {
11334
+ const parsed = parseJsonObjectOrArray(body);
11335
+ return parsed === void 0 ? body : redactSecretLikeFields(parsed);
11336
+ }
11337
+ return redactSecretLikeFields(body);
11338
+ }
11339
+ function redactHttpHeaderValue(name, value) {
11340
+ const normalized = normalizeName(name);
11341
+ if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
11342
+ return "Bearer ****";
11343
+ }
11344
+ if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
11345
+ return REDACTED_VALUE;
11346
+ }
11347
+ return value;
11348
+ }
11349
+
10929
11350
  // ../toolcraft/src/error-report.ts
10930
11351
  var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
10931
- var DEFAULT_SENSITIVE_NAMES = ["password", "token", "apikey", "secret"];
10932
- function isPlainObject2(value) {
11352
+ function isPlainObject3(value) {
10933
11353
  return typeof value === "object" && value !== null && !Array.isArray(value);
10934
11354
  }
10935
11355
  function unwrapOptional(schema) {
@@ -10939,7 +11359,7 @@ function unwrapOptional(schema) {
10939
11359
  return schema;
10940
11360
  }
10941
11361
  function hasHttpContext(error3) {
10942
- return error3 instanceof Error && error3.name === "HttpError" && isPlainObject2(error3.request) && isPlainObject2(error3.response);
11362
+ return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
10943
11363
  }
10944
11364
  function isSkippedError(error3) {
10945
11365
  if (error3 instanceof ApprovalDeclinedError) {
@@ -10976,8 +11396,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
10976
11396
  throw new Error("Error report directory resolves outside project root.");
10977
11397
  }
10978
11398
  const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
10979
- realpath(projectRoot),
10980
- realpath(reportDir)
11399
+ realpath2(projectRoot),
11400
+ realpath2(reportDir)
10981
11401
  ]);
10982
11402
  if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
10983
11403
  throw new Error("Error report directory resolves outside project root.");
@@ -11032,9 +11452,24 @@ function redactValue(value) {
11032
11452
  }
11033
11453
  return `<set, ${value.length} chars>`;
11034
11454
  }
11035
- function isSensitiveName(name) {
11036
- const normalized = name.toLowerCase();
11037
- return DEFAULT_SENSITIVE_NAMES.some((candidate) => normalized.includes(candidate));
11455
+ function collectStringLeaves(value, output) {
11456
+ if (typeof value === "string") {
11457
+ if (value.length > 0) {
11458
+ output.add(value);
11459
+ }
11460
+ return;
11461
+ }
11462
+ if (Array.isArray(value)) {
11463
+ for (const entry of value) {
11464
+ collectStringLeaves(entry, output);
11465
+ }
11466
+ return;
11467
+ }
11468
+ if (isPlainObject3(value)) {
11469
+ for (const entry of Object.values(value)) {
11470
+ collectStringLeaves(entry, output);
11471
+ }
11472
+ }
11038
11473
  }
11039
11474
  function schemaSecretValue(schema) {
11040
11475
  const unwrapped = unwrapOptional(schema);
@@ -11055,7 +11490,7 @@ function redactParamsValue(value, schema, name) {
11055
11490
  return "<redacted>";
11056
11491
  }
11057
11492
  const unwrapped = unwrapOptional(schema);
11058
- if (unwrapped.kind === "object" && isPlainObject2(value)) {
11493
+ if (unwrapped.kind === "object" && isPlainObject3(value)) {
11059
11494
  return Object.fromEntries(
11060
11495
  Object.entries(value).map(([key2, childValue]) => {
11061
11496
  const childSchema = unwrapped.shape[key2];
@@ -11077,6 +11512,52 @@ function redactParams(params17, command) {
11077
11512
  }
11078
11513
  return redactParamsValue(params17, command.params, "");
11079
11514
  }
11515
+ function collectSensitiveParamValues(value, schema, name, output) {
11516
+ if (shouldRedactParam(name, schema)) {
11517
+ collectStringLeaves(value, output);
11518
+ return;
11519
+ }
11520
+ const unwrapped = unwrapOptional(schema);
11521
+ if (unwrapped.kind === "object" && isPlainObject3(value)) {
11522
+ for (const [key2, childValue] of Object.entries(value)) {
11523
+ const childSchema = unwrapped.shape[key2];
11524
+ if (childSchema !== void 0) {
11525
+ collectSensitiveParamValues(childValue, childSchema, key2, output);
11526
+ }
11527
+ }
11528
+ return;
11529
+ }
11530
+ if (unwrapped.kind === "array" && Array.isArray(value)) {
11531
+ for (const entry of value) {
11532
+ collectSensitiveParamValues(entry, unwrapped.item, name, output);
11533
+ }
11534
+ }
11535
+ }
11536
+ function createReportStringRedactor(context, env) {
11537
+ const values = /* @__PURE__ */ new Set();
11538
+ for (const value of Object.values(context.secrets ?? {})) {
11539
+ if (value !== void 0 && value.length > 0) {
11540
+ values.add(value);
11541
+ }
11542
+ }
11543
+ for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
11544
+ const value = context.secrets?.[name] ?? env[secret.env];
11545
+ if (value !== void 0 && value.length > 0) {
11546
+ values.add(value);
11547
+ }
11548
+ }
11549
+ if (context.command !== void 0) {
11550
+ collectSensitiveParamValues(context.params, context.command.params, "", values);
11551
+ }
11552
+ const orderedValues = [...values].sort((left, right) => right.length - left.length);
11553
+ return (value) => {
11554
+ let redacted = value;
11555
+ for (const secretValue of orderedValues) {
11556
+ redacted = redacted.split(secretValue).join("<redacted>");
11557
+ }
11558
+ return redacted;
11559
+ };
11560
+ }
11080
11561
  function commandSecretEnvNames(secrets) {
11081
11562
  if (secrets === void 0) {
11082
11563
  return [];
@@ -11130,28 +11611,42 @@ function redactArgv(argv, options) {
11130
11611
  function stableJson(value) {
11131
11612
  return JSON.stringify(value, null, 2) ?? "undefined";
11132
11613
  }
11133
- function redactStructuredErrorField(name, value) {
11134
- if (typeof value === "string" && name.toLowerCase() === "authorization") {
11135
- return "Bearer ****";
11614
+ function redactStructuredErrorField(name, value, redactString) {
11615
+ if (typeof value === "string") {
11616
+ const redactedHeaderValue = redactHttpHeaderValue(name, value);
11617
+ if (redactedHeaderValue !== value) {
11618
+ return redactedHeaderValue;
11619
+ }
11620
+ if (isSensitiveName(name)) {
11621
+ return "<redacted>";
11622
+ }
11623
+ return redactString(value);
11136
11624
  }
11137
11625
  if (Array.isArray(value)) {
11138
- return value.map((entry) => redactStructuredErrorField(name, entry));
11626
+ return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
11139
11627
  }
11140
- if (isPlainObject2(value)) {
11628
+ if (isPlainObject3(value)) {
11141
11629
  return Object.fromEntries(
11142
- Object.entries(value).map(([key2, entry]) => [key2, redactStructuredErrorField(key2, entry)])
11630
+ Object.entries(value).map(([key2, entry]) => [
11631
+ key2,
11632
+ redactStructuredErrorField(key2, entry, redactString)
11633
+ ])
11143
11634
  );
11144
11635
  }
11145
11636
  return value;
11146
11637
  }
11147
- function ownStructuredFields(error3) {
11638
+ function ownStructuredFields(error3, redactString) {
11148
11639
  const fields = {};
11149
11640
  for (const key2 of Object.keys(error3)) {
11150
11641
  if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
11151
11642
  continue;
11152
11643
  }
11153
11644
  Object.defineProperty(fields, key2, {
11154
- value: redactStructuredErrorField(key2, error3[key2]),
11645
+ value: redactStructuredErrorField(
11646
+ key2,
11647
+ error3[key2],
11648
+ redactString
11649
+ ),
11155
11650
  enumerable: true,
11156
11651
  configurable: true,
11157
11652
  writable: true
@@ -11159,43 +11654,44 @@ function ownStructuredFields(error3) {
11159
11654
  }
11160
11655
  return fields;
11161
11656
  }
11162
- function formatStackChain(error3) {
11657
+ function formatStackChain(error3, redactString) {
11163
11658
  const lines = [];
11164
11659
  let current = error3;
11165
11660
  let index = 0;
11166
11661
  while (current !== void 0) {
11167
11662
  if (current instanceof Error) {
11168
- lines.push(
11169
- index === 0 ? current.stack ?? String(current) : `Caused by: ${current.stack ?? String(current)}`
11170
- );
11663
+ const stack = current.stack ?? String(current);
11664
+ lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
11171
11665
  current = current.cause;
11172
11666
  } else {
11173
- lines.push(index === 0 ? String(current) : `Caused by: ${String(current)}`);
11667
+ const message2 = String(current);
11668
+ lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
11174
11669
  current = void 0;
11175
11670
  }
11176
11671
  index += 1;
11177
11672
  }
11178
11673
  return lines.join("\n");
11179
11674
  }
11180
- function formatHeaderValue(name, value) {
11181
- return name.toLowerCase() === "authorization" ? "Bearer ****" : value;
11675
+ function formatHeaderValue(name, value, redactString) {
11676
+ return redactString(redactHttpHeaderValue(name, value));
11182
11677
  }
11183
- function formatHeaders(headers) {
11184
- return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
11678
+ function formatHeaders(headers, redactString) {
11679
+ return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
11185
11680
  }
11186
- function formatBody(body) {
11187
- if (typeof body === "string") {
11188
- return body;
11681
+ function formatBody(body, redactString) {
11682
+ const redactedBody = redactHttpBody(body);
11683
+ if (typeof redactedBody === "string") {
11684
+ return redactString(redactedBody);
11189
11685
  }
11190
- return stableJson(body);
11686
+ return redactString(stableJson(redactedBody));
11191
11687
  }
11192
- function formatHttpTranscript(error3) {
11688
+ function formatHttpTranscript(error3, redactString) {
11193
11689
  const requestLines = [
11194
11690
  `${error3.request.method} ${error3.request.url}`,
11195
- formatHeaders(error3.request.headers)
11691
+ formatHeaders(error3.request.headers, redactString)
11196
11692
  ].filter((line) => line.length > 0);
11197
11693
  if (error3.request.body !== void 0) {
11198
- requestLines.push("", formatBody(error3.request.body));
11694
+ requestLines.push("", formatBody(error3.request.body, redactString));
11199
11695
  }
11200
11696
  return [
11201
11697
  "Request:",
@@ -11203,9 +11699,9 @@ function formatHttpTranscript(error3) {
11203
11699
  "",
11204
11700
  "Response:",
11205
11701
  `${error3.response.status} ${error3.response.statusText}`,
11206
- formatHeaders(error3.response.headers),
11702
+ formatHeaders(error3.response.headers, redactString),
11207
11703
  "",
11208
- formatBody(error3.response.body)
11704
+ formatBody(error3.response.body, redactString)
11209
11705
  ].join("\n");
11210
11706
  }
11211
11707
  function resolveToolcraftVersion(version) {
@@ -11214,9 +11710,10 @@ function resolveToolcraftVersion(version) {
11214
11710
  function buildReport(context) {
11215
11711
  const env = context.env ?? process.env;
11216
11712
  const error3 = context.error;
11713
+ const redactString = createReportStringRedactor(context, env);
11217
11714
  const errorName = error3 instanceof Error ? error3.name : typeof error3;
11218
- const errorMessage = error3 instanceof Error ? error3.message : String(error3);
11219
- const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
11715
+ const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
11716
+ const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
11220
11717
  const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
11221
11718
  const value = context.secrets?.[name] ?? env[secret.env];
11222
11719
  return `${secret.env}=${redactValue(value)}`;
@@ -11230,7 +11727,9 @@ function buildReport(context) {
11230
11727
  `platform: ${process.platform} ${process.arch}`,
11231
11728
  "",
11232
11729
  "Argv",
11233
- stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets })),
11730
+ redactString(
11731
+ stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
11732
+ ),
11234
11733
  "",
11235
11734
  "Resolved Secrets",
11236
11735
  ...secretLines.length === 0 ? ["<none>"] : secretLines,
@@ -11239,19 +11738,19 @@ function buildReport(context) {
11239
11738
  context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
11240
11739
  "",
11241
11740
  "Parsed Params",
11242
- stableJson(redactParams(context.params, context.command)),
11741
+ redactString(stableJson(redactParams(context.params, context.command))),
11243
11742
  "",
11244
11743
  "Error",
11245
11744
  `name: ${errorName}`,
11246
11745
  `message: ${errorMessage}`,
11247
11746
  "structured fields:",
11248
- stableJson(structuredFields),
11747
+ redactString(stableJson(structuredFields)),
11249
11748
  "",
11250
11749
  "Stack",
11251
- formatStackChain(error3)
11750
+ formatStackChain(error3, redactString)
11252
11751
  ];
11253
11752
  if (hasHttpContext(error3)) {
11254
- lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
11753
+ lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
11255
11754
  }
11256
11755
  return `${lines.join("\n")}
11257
11756
  `;
@@ -11263,7 +11762,7 @@ async function writeErrorReport(context) {
11263
11762
  }
11264
11763
  const projectRoot = resolveProjectRoot(context.projectRoot);
11265
11764
  const reportDir = resolveReportDir(context.errorReports, projectRoot);
11266
- const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
11765
+ const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
11267
11766
  const absolutePath = path13.join(reportDir, fileName);
11268
11767
  await mkdir2(reportDir, { recursive: true });
11269
11768
  if (reportDirMustStayWithinProject(context.errorReports)) {
@@ -11711,6 +12210,7 @@ ${rendered.join("\n")}`);
11711
12210
  }
11712
12211
 
11713
12212
  // ../toolcraft/src/cli.ts
12213
+ configureTheme({ brand: "blue", label: "Toolcraft" });
11714
12214
  var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
11715
12215
  "params",
11716
12216
  "secrets",
@@ -12741,10 +13241,10 @@ function renderHelpSections(sections) {
12741
13241
  return sections.filter((section) => section.length > 0).join("\n\n");
12742
13242
  }
12743
13243
  function formatHelpCommandList(rows) {
12744
- return process.stdout.isTTY === false ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
13244
+ return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
12745
13245
  }
12746
13246
  function formatHelpOptionList(rows) {
12747
- return process.stdout.isTTY === false ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
13247
+ return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
12748
13248
  }
12749
13249
  function buildUsageLine(breadcrumb, rootUsageName, suffix) {
12750
13250
  const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
@@ -13032,11 +13532,18 @@ function formatResolvedValue(value) {
13032
13532
  function fieldPromptLabel(field) {
13033
13533
  return field.positionalIndex === void 0 ? field.optionFlag : `<${field.displayPath}>`;
13034
13534
  }
13535
+ function enumOptionLabel(schema, value) {
13536
+ const key2 = String(value);
13537
+ if (schema.labels === void 0 || !Object.prototype.hasOwnProperty.call(schema.labels, key2)) {
13538
+ return key2;
13539
+ }
13540
+ return schema.labels[key2] ?? key2;
13541
+ }
13035
13542
  async function promptForField(field) {
13036
13543
  const schema = field.schema;
13037
13544
  if (schema.kind === "enum") {
13038
13545
  const options = schema.loadOptions ? await schema.loadOptions() : schema.values.map((value) => ({
13039
- label: schema.labels?.[String(value)] ?? String(value),
13546
+ label: enumOptionLabel(schema, value),
13040
13547
  value
13041
13548
  }));
13042
13549
  const selected = await select2({
@@ -13121,8 +13628,8 @@ async function withOutputFormat2(output, fn) {
13121
13628
  function createFs2() {
13122
13629
  return {
13123
13630
  readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
13124
- writeFile: async (path24, contents) => {
13125
- await writeFile5(path24, contents);
13631
+ writeFile: async (path24, contents, options) => {
13632
+ await writeFile5(path24, contents, options);
13126
13633
  },
13127
13634
  exists: async (path24) => {
13128
13635
  try {
@@ -13134,7 +13641,7 @@ function createFs2() {
13134
13641
  },
13135
13642
  lstat: async (path24) => lstat3(path24),
13136
13643
  rename: async (fromPath, toPath) => rename3(fromPath, toPath),
13137
- unlink: async (path24) => unlink2(path24)
13644
+ unlink: async (path24) => unlink3(path24)
13138
13645
  };
13139
13646
  }
13140
13647
  function createEnv2(values = process.env) {
@@ -13144,7 +13651,7 @@ function createEnv2(values = process.env) {
13144
13651
  }
13145
13652
  };
13146
13653
  }
13147
- function isPlainObject3(value) {
13654
+ function isPlainObject4(value) {
13148
13655
  return typeof value === "object" && value !== null && !Array.isArray(value);
13149
13656
  }
13150
13657
  function hasFieldValue(value) {
@@ -13253,7 +13760,7 @@ async function loadPresetValues(fields, presetPath) {
13253
13760
  { cause: error3 }
13254
13761
  );
13255
13762
  }
13256
- if (!isPlainObject3(parsedPreset)) {
13763
+ if (!isPlainObject4(parsedPreset)) {
13257
13764
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
13258
13765
  }
13259
13766
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
@@ -13272,7 +13779,7 @@ async function loadPresetValues(fields, presetPath) {
13272
13779
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
13273
13780
  );
13274
13781
  }
13275
- if (!isPlainObject3(value)) {
13782
+ if (!isPlainObject4(value)) {
13276
13783
  throw new UserError(
13277
13784
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
13278
13785
  );
@@ -13315,8 +13822,8 @@ function matchesFixtureValue(expected, actual) {
13315
13822
  }
13316
13823
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
13317
13824
  }
13318
- if (isPlainObject3(expected)) {
13319
- if (!isPlainObject3(actual)) {
13825
+ if (isPlainObject4(expected)) {
13826
+ if (!isPlainObject4(actual)) {
13320
13827
  return false;
13321
13828
  }
13322
13829
  return Object.entries(expected).every(
@@ -13379,9 +13886,9 @@ function createFixtureFetch(entries) {
13379
13886
  };
13380
13887
  }
13381
13888
  function createFixtureFs(definition) {
13382
- const fsDefinition = isPlainObject3(definition) ? definition : {};
13383
- const readFileEntries = isPlainObject3(fsDefinition.readFile) ? fsDefinition.readFile : {};
13384
- const existsEntries = isPlainObject3(fsDefinition.exists) ? fsDefinition.exists : {};
13889
+ const fsDefinition = isPlainObject4(definition) ? definition : {};
13890
+ const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
13891
+ const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
13385
13892
  return {
13386
13893
  readFile: async (filePath) => {
13387
13894
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -13404,10 +13911,10 @@ function createFixtureFs(definition) {
13404
13911
  function resolveFixtureMethodResult(methodName, definition, args) {
13405
13912
  if (Array.isArray(definition)) {
13406
13913
  for (const entry of definition) {
13407
- if (!isPlainObject3(entry)) {
13914
+ if (!isPlainObject4(entry)) {
13408
13915
  continue;
13409
13916
  }
13410
- const explicitMatcher = isPlainObject3(entry.request) ? entry.request : void 0;
13917
+ const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
13411
13918
  const matcher = explicitMatcher ?? Object.fromEntries(
13412
13919
  Object.entries(entry).filter(
13413
13920
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -13419,7 +13926,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13419
13926
  matched = matchesFixtureValue(matcher.args, args);
13420
13927
  } else if (Object.keys(matcher).length === 0) {
13421
13928
  matched = true;
13422
- } else if (isPlainObject3(firstArg)) {
13929
+ } else if (isPlainObject4(firstArg)) {
13423
13930
  matched = matchesFixtureValue(matcher, firstArg);
13424
13931
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
13425
13932
  const [[, expectedValue]] = Object.entries(matcher);
@@ -13440,7 +13947,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13440
13947
  return Promise.resolve(null);
13441
13948
  }
13442
13949
  }
13443
- if (isPlainObject3(definition)) {
13950
+ if (isPlainObject4(definition)) {
13444
13951
  const firstArg = args[0];
13445
13952
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
13446
13953
  return Promise.resolve(definition[firstArg]);
@@ -13452,7 +13959,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13452
13959
  return Promise.resolve(null);
13453
13960
  }
13454
13961
  function createFixtureService(definition) {
13455
- const methods = isPlainObject3(definition) ? definition : {};
13962
+ const methods = isPlainObject4(definition) ? definition : {};
13456
13963
  return new Proxy(
13457
13964
  {},
13458
13965
  {
@@ -13550,7 +14057,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
13550
14057
  };
13551
14058
  }
13552
14059
  const scenario = await loadFixtureScenario(command, selector);
13553
- const scenarioServices = isPlainObject3(scenario.services) ? scenario.services : {};
14060
+ const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
13554
14061
  const customServiceNames = /* @__PURE__ */ new Set([
13555
14062
  ...Object.keys(services),
13556
14063
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -13832,7 +14339,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13832
14339
  if (itemSchema.kind !== "object") {
13833
14340
  return value;
13834
14341
  }
13835
- if (!isPlainObject3(value)) {
14342
+ if (!isPlainObject4(value)) {
13836
14343
  errors2.push({
13837
14344
  path: displayPath,
13838
14345
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -13867,7 +14374,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13867
14374
  );
13868
14375
  }
13869
14376
  case "object": {
13870
- if (!isPlainObject3(value)) {
14377
+ if (!isPlainObject4(value)) {
13871
14378
  errors2.push({
13872
14379
  path: displayPath,
13873
14380
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -13898,7 +14405,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13898
14405
  return result;
13899
14406
  }
13900
14407
  case "record": {
13901
- if (!isPlainObject3(value)) {
14408
+ if (!isPlainObject4(value)) {
13902
14409
  errors2.push({
13903
14410
  path: displayPath,
13904
14411
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -14324,10 +14831,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
14324
14831
  }
14325
14832
  }
14326
14833
  function isStringRecord(value) {
14327
- return isPlainObject3(value) && Object.values(value).every((entry) => typeof entry === "string");
14834
+ return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
14328
14835
  }
14329
14836
  function isHttpErrorLike(error3) {
14330
- if (!isPlainObject3(error3)) {
14837
+ if (!isPlainObject4(error3)) {
14331
14838
  return false;
14332
14839
  }
14333
14840
  if (error3.name !== "HttpError" || typeof error3.message !== "string") {
@@ -14335,7 +14842,7 @@ function isHttpErrorLike(error3) {
14335
14842
  }
14336
14843
  const request = error3.request;
14337
14844
  const response = error3.response;
14338
- return isPlainObject3(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject3(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
14845
+ 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) && "body" in response;
14339
14846
  }
14340
14847
  function hasTypedOptionalField(value, field, type2) {
14341
14848
  return !(field in value) || typeof value[field] === type2;
@@ -14344,7 +14851,7 @@ function isNonEmptyString(value) {
14344
14851
  return typeof value === "string" && value.trim().length > 0;
14345
14852
  }
14346
14853
  function isProblemDetailsLike(body) {
14347
- if (!isPlainObject3(body)) {
14854
+ if (!isPlainObject4(body)) {
14348
14855
  return false;
14349
14856
  }
14350
14857
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -14365,11 +14872,11 @@ function isProblemDetailsLike(body) {
14365
14872
  return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
14366
14873
  }
14367
14874
  function isGraphQLErrorEnvelopeLike(body) {
14368
- if (!isPlainObject3(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
14875
+ if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
14369
14876
  return false;
14370
14877
  }
14371
14878
  return body.errors.every((error3) => {
14372
- if (!isPlainObject3(error3) || typeof error3.message !== "string") {
14879
+ if (!isPlainObject4(error3) || typeof error3.message !== "string") {
14373
14880
  return false;
14374
14881
  }
14375
14882
  if ("path" in error3) {
@@ -14379,7 +14886,7 @@ function isGraphQLErrorEnvelopeLike(body) {
14379
14886
  }
14380
14887
  }
14381
14888
  if ("extensions" in error3) {
14382
- if (!isPlainObject3(error3.extensions)) {
14889
+ if (!isPlainObject4(error3.extensions)) {
14383
14890
  return false;
14384
14891
  }
14385
14892
  if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
@@ -14390,7 +14897,7 @@ function isGraphQLErrorEnvelopeLike(body) {
14390
14897
  });
14391
14898
  }
14392
14899
  function styleHttpErrorLine(value, style) {
14393
- return process.stdout.isTTY === false ? value : style(value);
14900
+ return process.stdout.isTTY !== true ? value : style(value);
14394
14901
  }
14395
14902
  function formatHttpErrorStatus(value) {
14396
14903
  return styleHttpErrorLine(value, text.error);
@@ -14427,23 +14934,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
14427
14934
  }).join("\n\n");
14428
14935
  }
14429
14936
  function formatHttpErrorBody(body) {
14430
- if (typeof body === "string") {
14431
- return body;
14937
+ const redactedBody = redactHttpBody(body);
14938
+ if (typeof redactedBody === "string") {
14939
+ return redactedBody;
14432
14940
  }
14433
- if (isProblemDetailsLike(body)) {
14434
- return formatProblemDetailsBody(body);
14941
+ if (isProblemDetailsLike(redactedBody)) {
14942
+ return formatProblemDetailsBody(redactedBody);
14435
14943
  }
14436
- if (isGraphQLErrorEnvelopeLike(body)) {
14437
- return formatGraphQLErrorEnvelopeBody(body);
14944
+ if (isGraphQLErrorEnvelopeLike(redactedBody)) {
14945
+ return formatGraphQLErrorEnvelopeBody(redactedBody);
14438
14946
  }
14439
- const serialized = JSON.stringify(body, null, 2);
14440
- return serialized === void 0 ? String(body) : serialized;
14947
+ const serialized = JSON.stringify(redactedBody, null, 2);
14948
+ return serialized === void 0 ? String(redactedBody) : serialized;
14441
14949
  }
14442
14950
  function indentHttpErrorBlock(value) {
14443
14951
  return value.split("\n").map((line) => ` ${line}`).join("\n");
14444
14952
  }
14445
14953
  function formatHttpHeaderValue(name, value) {
14446
- return name.toLowerCase() === "authorization" ? "Bearer ****" : value;
14954
+ return redactHttpHeaderValue(name, value);
14447
14955
  }
14448
14956
  function formatHttpErrorHeaders(headers) {
14449
14957
  return Object.entries(headers).map(
@@ -14461,7 +14969,11 @@ function renderHttpError(error3, options) {
14461
14969
  if (detailed) {
14462
14970
  lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
14463
14971
  if (error3.request.body !== void 0) {
14464
- lines.push("Request body:", indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)), "");
14972
+ lines.push(
14973
+ "Request body:",
14974
+ indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
14975
+ ""
14976
+ );
14465
14977
  }
14466
14978
  }
14467
14979
  lines.push(
@@ -14867,7 +15379,7 @@ async function runCLI(roots, options = {}) {
14867
15379
  }
14868
15380
 
14869
15381
  // src/terminal-pilot.ts
14870
- import { randomUUID as randomUUID4 } from "node:crypto";
15382
+ import { randomUUID as randomUUID6 } from "node:crypto";
14871
15383
 
14872
15384
  // src/terminal-session.ts
14873
15385
  import { EventEmitter } from "node:events";
@@ -14949,6 +15461,11 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
14949
15461
  return input.length;
14950
15462
  }
14951
15463
 
15464
+ // src/errors.ts
15465
+ function hasOwnErrorCode(error3, code) {
15466
+ return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
15467
+ }
15468
+
14952
15469
  // src/terminal-buffer.ts
14953
15470
  var RESET_SGR = "\x1B[0m";
14954
15471
  var DEC_SPECIAL_GRAPHICS = {
@@ -16048,10 +16565,7 @@ function ensureSpawnHelperExecutable() {
16048
16565
  }
16049
16566
  }
16050
16567
  function isMissingFileError(error3) {
16051
- if (!(error3 instanceof Error)) {
16052
- return false;
16053
- }
16054
- return "code" in error3 && error3.code === "ENOENT";
16568
+ return hasOwnErrorCode(error3, "ENOENT");
16055
16569
  }
16056
16570
  function matchPattern(buffer, pattern) {
16057
16571
  const clean = normalizeHistoryBuffer(stripAnsi4(buffer));
@@ -16142,7 +16656,7 @@ var TerminalPilot = class _TerminalPilot {
16142
16656
  }
16143
16657
  async newSession(opts) {
16144
16658
  const session = new TerminalSession({
16145
- id: randomUUID4(),
16659
+ id: randomUUID6(),
16146
16660
  command: opts.command,
16147
16661
  args: opts.args,
16148
16662
  cwd: opts.cwd,
@@ -16421,6 +16935,11 @@ var claudeCodeAgent = {
16421
16935
  aliases: ["claude"],
16422
16936
  binaryName: "claude",
16423
16937
  apiShapes: ["anthropic-messages"],
16938
+ otelCapture: {
16939
+ env: {
16940
+ CLAUDE_CODE_ENABLE_TELEMETRY: "1"
16941
+ }
16942
+ },
16424
16943
  configPath: "~/.claude/settings.json",
16425
16944
  branding: {
16426
16945
  colors: {
@@ -16453,6 +16972,16 @@ var codexAgent = {
16453
16972
  summary: "Configure Codex to use Poe as the model provider.",
16454
16973
  binaryName: "codex",
16455
16974
  apiShapes: ["openai-responses"],
16975
+ otelCapture: {
16976
+ args: (endpoint, content) => [
16977
+ "-c",
16978
+ `otel.trace_exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/traces`)},protocol="json"}}`,
16979
+ "-c",
16980
+ `otel.exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/logs`)},protocol="json"}}`,
16981
+ "-c",
16982
+ `otel.log_user_prompt=${content}`
16983
+ ]
16984
+ },
16456
16985
  configPath: "~/.codex/config.toml",
16457
16986
  branding: {
16458
16987
  colors: {
@@ -16488,6 +17017,11 @@ var openCodeAgent = {
16488
17017
  summary: "Configure OpenCode CLI to use the Poe API.",
16489
17018
  binaryName: "opencode",
16490
17019
  apiShapes: ["openai-chat-completions"],
17020
+ otelCapture: {
17021
+ env: {
17022
+ OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
17023
+ }
17024
+ },
16491
17025
  configPath: "~/.config/opencode/config.json",
16492
17026
  branding: {
16493
17027
  colors: {
@@ -16523,6 +17057,7 @@ var gooseAgent = {
16523
17057
  summary: "Block's open-source AI agent with ACP support.",
16524
17058
  binaryName: "goose",
16525
17059
  apiShapes: ["openai-chat-completions"],
17060
+ otelCapture: {},
16526
17061
  configPath: "~/.config/goose/config.yaml",
16527
17062
  branding: {
16528
17063
  colors: {
@@ -16556,6 +17091,12 @@ function freezeAgent(agent) {
16556
17091
  if (agent.apiShapes !== void 0) {
16557
17092
  Object.freeze(agent.apiShapes);
16558
17093
  }
17094
+ if (agent.otelCapture?.env !== void 0) {
17095
+ Object.freeze(agent.otelCapture.env);
17096
+ }
17097
+ if (agent.otelCapture !== void 0) {
17098
+ Object.freeze(agent.otelCapture);
17099
+ }
16559
17100
  Object.freeze(agent.branding.colors);
16560
17101
  Object.freeze(agent.branding);
16561
17102
  return Object.freeze(agent);
@@ -16616,11 +17157,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
16616
17157
  if (!resolvedId) {
16617
17158
  return { status: "unknown", input };
16618
17159
  }
16619
- const config = registry[resolvedId];
16620
- if (!config) {
17160
+ const config2 = registry[resolvedId];
17161
+ if (!config2) {
16621
17162
  return { status: "unsupported", input, id: resolvedId };
16622
17163
  }
16623
- return { status: "supported", input, id: resolvedId, config: { ...config } };
17164
+ return { status: "supported", input, id: resolvedId, config: { ...config2 } };
16624
17165
  }
16625
17166
  function getAgentConfig(agentId) {
16626
17167
  const support = resolveAgentSupport(agentId);
@@ -16719,6 +17260,7 @@ var templateMutation = {
16719
17260
  };
16720
17261
 
16721
17262
  // ../config-mutations/src/execution/apply-mutation.ts
17263
+ import { randomUUID as randomUUID7 } from "node:crypto";
16722
17264
  import path17 from "node:path";
16723
17265
 
16724
17266
  // ../config-mutations/src/formats/json.ts
@@ -16794,7 +17336,7 @@ function merge(base, patch) {
16794
17336
  if (value === void 0) {
16795
17337
  continue;
16796
17338
  }
16797
- const existing = result[key2];
17339
+ const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
16798
17340
  if (isConfigObject(existing) && isConfigObject(value)) {
16799
17341
  setConfigEntry(result, key2, merge(existing, value));
16800
17342
  continue;
@@ -16922,7 +17464,7 @@ function merge2(base, patch) {
16922
17464
  if (value === void 0) {
16923
17465
  continue;
16924
17466
  }
16925
- const existing = result[key2];
17467
+ const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
16926
17468
  if (isConfigObject2(existing) && isConfigObject2(value)) {
16927
17469
  setConfigEntry(result, key2, merge2(existing, value));
16928
17470
  continue;
@@ -17002,7 +17544,7 @@ function merge3(base, patch) {
17002
17544
  if (value === void 0) {
17003
17545
  continue;
17004
17546
  }
17005
- const existing = result[key2];
17547
+ const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
17006
17548
  if (isConfigObject3(existing) && isConfigObject3(value)) {
17007
17549
  setConfigEntry(result, key2, merge3(existing, value));
17008
17550
  continue;
@@ -17139,7 +17681,7 @@ function resolvePath(rawPath, homeDir, pathMapper) {
17139
17681
 
17140
17682
  // ../config-mutations/src/fs-utils.ts
17141
17683
  function isNotFound(error3) {
17142
- return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "ENOENT";
17684
+ return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT";
17143
17685
  }
17144
17686
  async function readFileIfExists(fs4, target) {
17145
17687
  try {
@@ -17188,6 +17730,7 @@ async function backupInvalidDocument(context, targetPath, content) {
17188
17730
  return;
17189
17731
  } catch (error3) {
17190
17732
  if (!isAlreadyExists(error3)) {
17733
+ await context.fs.unlink(backupPath).catch(() => void 0);
17191
17734
  throw error3;
17192
17735
  }
17193
17736
  attempt += 1;
@@ -17195,7 +17738,7 @@ async function backupInvalidDocument(context, targetPath, content) {
17195
17738
  }
17196
17739
  }
17197
17740
  function isAlreadyExists(error3) {
17198
- return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
17741
+ return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
17199
17742
  }
17200
17743
  async function assertRegularWriteTarget(context, targetPath) {
17201
17744
  const boundary = path17.dirname(path17.resolve(context.homeDir));
@@ -17219,28 +17762,34 @@ async function assertRegularWriteTarget(context, targetPath) {
17219
17762
  }
17220
17763
  async function writeAtomically2(context, targetPath, content) {
17221
17764
  await assertRegularWriteTarget(context, targetPath);
17222
- let attempt = 0;
17223
- while (true) {
17224
- const tempPath = `${targetPath}.mutation-tmp-${attempt}`;
17765
+ for (let attempt = 0; attempt < 10; attempt += 1) {
17766
+ const tempPath = `${targetPath}.mutation-tmp-${process.pid}-${randomUUID7()}`;
17767
+ let tempCreated = false;
17225
17768
  try {
17769
+ await assertRegularWriteTarget(context, tempPath);
17226
17770
  await context.fs.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
17771
+ tempCreated = true;
17227
17772
  await context.fs.rename(tempPath, targetPath);
17773
+ tempCreated = false;
17228
17774
  return;
17229
17775
  } catch (error3) {
17230
- if (isAlreadyExists(error3)) {
17231
- attempt += 1;
17232
- continue;
17233
- }
17234
- try {
17235
- await context.fs.unlink(tempPath);
17236
- } catch (cleanupError) {
17237
- if (!isNotFound(cleanupError)) {
17238
- void cleanupError;
17776
+ const alreadyExists = isAlreadyExists(error3);
17777
+ if (tempCreated || !alreadyExists) {
17778
+ try {
17779
+ await context.fs.unlink(tempPath);
17780
+ } catch (cleanupError) {
17781
+ if (!isNotFound(cleanupError)) {
17782
+ void cleanupError;
17783
+ }
17239
17784
  }
17240
17785
  }
17786
+ if (alreadyExists) {
17787
+ continue;
17788
+ }
17241
17789
  throw error3;
17242
17790
  }
17243
17791
  }
17792
+ throw new Error(`Unable to create temporary mutation file for ${targetPath}.`);
17244
17793
  }
17245
17794
  function describeMutation(kind, targetPath) {
17246
17795
  const displayPath = targetPath ?? "target";
@@ -17532,6 +18081,7 @@ async function applyBackup(mutation, context, options) {
17532
18081
  break;
17533
18082
  } catch (error3) {
17534
18083
  if (!isAlreadyExists(error3)) {
18084
+ await context.fs.unlink(backupPath).catch(() => void 0);
17535
18085
  throw error3;
17536
18086
  }
17537
18087
  attempt += 1;
@@ -17939,7 +18489,7 @@ async function pathExists2(fs4, targetPath) {
17939
18489
  await fs4.stat(targetPath);
17940
18490
  return true;
17941
18491
  } catch (error3) {
17942
- if (error3 && typeof error3 === "object" && "code" in error3 && error3.code === "ENOENT") {
18492
+ if (typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT") {
17943
18493
  return false;
17944
18494
  }
17945
18495
  throw error3;
@@ -17952,14 +18502,14 @@ async function installSkill(agentId, skill, options) {
17952
18502
  throw new UnsupportedAgentError(agentId);
17953
18503
  }
17954
18504
  const scope = options.scope ?? "local";
17955
- const config = support.config;
18505
+ const config2 = support.config;
17956
18506
  if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
17957
18507
  throw new Error(`Invalid skill name: ${skill.name}`);
17958
18508
  }
17959
- const skillDir = scope === "global" ? config.globalSkillDir : toHomeRelative(config.localSkillDir);
18509
+ const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
17960
18510
  const skillFolderPath = `${skillDir}/${skill.name}`;
17961
18511
  const skillFilePath = `${skillFolderPath}/SKILL.md`;
17962
- const displayPath = `${scope === "global" ? config.globalSkillDir : config.localSkillDir}/${skill.name}/SKILL.md`;
18512
+ const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
17963
18513
  const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
17964
18514
  if (await pathExists2(options.fs, absoluteSkillPath)) {
17965
18515
  throw new Error(`Skill already exists: ${displayPath}`);
@@ -17998,12 +18548,13 @@ import path19 from "node:path";
17998
18548
 
17999
18549
  // ../agent-skill-config/src/git-exclude.ts
18000
18550
  import { execFileSync } from "node:child_process";
18551
+ import { randomUUID as randomUUID8 } from "node:crypto";
18001
18552
  import * as fs2 from "node:fs";
18002
18553
  import path20 from "node:path";
18003
18554
 
18004
18555
  // ../agent-skill-config/src/bridge-active-skills.ts
18005
18556
  import * as fs3 from "node:fs";
18006
- import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
18557
+ import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
18007
18558
  import path21 from "node:path";
18008
18559
 
18009
18560
  // src/commands/installer.ts
@@ -18016,7 +18567,7 @@ var DEFAULT_INSTALL_SCOPE = "local";
18016
18567
  var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
18017
18568
  var installableAgents = supportedAgents;
18018
18569
  function isNotFoundError2(error3) {
18019
- return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "ENOENT";
18570
+ return hasOwnErrorCode(error3, "ENOENT");
18020
18571
  }
18021
18572
  function resolveInstallerServices(installer) {
18022
18573
  return {
@@ -18080,17 +18631,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
18080
18631
  return targetPath;
18081
18632
  }
18082
18633
  function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
18083
- const config = getAgentConfig(agent);
18084
- if (!config) {
18634
+ const config2 = getAgentConfig(agent);
18635
+ if (!config2) {
18085
18636
  throwUnsupportedAgent(agent);
18086
18637
  }
18087
18638
  return {
18088
18639
  displayPath: path22.join(
18089
- scope === "global" ? config.globalSkillDir : config.localSkillDir,
18640
+ scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
18090
18641
  TERMINAL_PILOT_SKILL_NAME
18091
18642
  ),
18092
18643
  fullPath: path22.join(
18093
- scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) : path22.resolve(cwd, config.localSkillDir),
18644
+ scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
18094
18645
  TERMINAL_PILOT_SKILL_NAME
18095
18646
  )
18096
18647
  };
@@ -18247,7 +18798,7 @@ var resize = defineCommand({
18247
18798
  });
18248
18799
 
18249
18800
  // ../terminal-png/src/index.ts
18250
- import { randomUUID as randomUUID6 } from "node:crypto";
18801
+ import { randomUUID as randomUUID10 } from "node:crypto";
18251
18802
  import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
18252
18803
 
18253
18804
  // ../terminal-png/src/ansi-parser.ts
@@ -19187,21 +19738,28 @@ async function renderTerminalPng(ansiText, options = {}) {
19187
19738
  });
19188
19739
  const png = renderPng(svg);
19189
19740
  if (options.output) {
19190
- const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
19741
+ const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
19742
+ let temporaryCreated = false;
19191
19743
  try {
19192
19744
  await writeFile6(temporaryPath, png, { flag: "wx" });
19745
+ temporaryCreated = true;
19193
19746
  await rename4(temporaryPath, options.output);
19194
19747
  } catch (error3) {
19195
- try {
19196
- await rm(temporaryPath, { force: true });
19197
- } catch (cleanupError) {
19198
- void cleanupError;
19748
+ if (temporaryCreated || !isAlreadyExistsError3(error3)) {
19749
+ try {
19750
+ await rm(temporaryPath, { force: true });
19751
+ } catch (cleanupError) {
19752
+ void cleanupError;
19753
+ }
19199
19754
  }
19200
19755
  throw error3;
19201
19756
  }
19202
19757
  }
19203
19758
  return png;
19204
19759
  }
19760
+ function isAlreadyExistsError3(error3) {
19761
+ return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
19762
+ }
19205
19763
 
19206
19764
  // src/commands/screenshot.ts
19207
19765
  var params11 = S.Object({
@@ -19264,7 +19822,7 @@ var type = defineCommand({
19264
19822
  });
19265
19823
 
19266
19824
  // src/commands/uninstall.ts
19267
- import { randomUUID as randomUUID7 } from "node:crypto";
19825
+ import { randomUUID as randomUUID11 } from "node:crypto";
19268
19826
  var params14 = S.Object({
19269
19827
  agent: S.Enum(installableAgents, {
19270
19828
  description: "Agent to uninstall terminal-pilot from",
@@ -19300,7 +19858,7 @@ var uninstall = defineCommand({
19300
19858
  if (!await folderExists(services.fs, skill.fullPath)) {
19301
19859
  continue;
19302
19860
  }
19303
- const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
19861
+ const stagingPath = `${skill.fullPath}.removing-${randomUUID11()}`;
19304
19862
  await services.fs.rename(skill.fullPath, stagingPath);
19305
19863
  staged.push({ ...skill, stagingPath });
19306
19864
  }
@@ -19326,7 +19884,7 @@ async function folderExists(fs4, folderPath) {
19326
19884
  await fs4.stat(folderPath);
19327
19885
  return true;
19328
19886
  } catch (error3) {
19329
- if (typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "ENOENT") {
19887
+ if (hasOwnErrorCode(error3, "ENOENT")) {
19330
19888
  return false;
19331
19889
  }
19332
19890
  throw error3;
@@ -19407,6 +19965,7 @@ function createTerminalPilotGroup() {
19407
19965
  var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
19408
19966
 
19409
19967
  // src/cli.ts
19968
+ configureTheme({ brand: "green", label: "Terminal Pilot" });
19410
19969
  function normalizeArgv(argv) {
19411
19970
  if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
19412
19971
  return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
@@ -19430,8 +19989,8 @@ async function isDirectExecution(argv) {
19430
19989
  try {
19431
19990
  const modulePath = fileURLToPath5(import.meta.url);
19432
19991
  const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
19433
- realpath2(path23.resolve(entryPoint)),
19434
- realpath2(modulePath)
19992
+ realpath3(path23.resolve(entryPoint)),
19993
+ realpath3(modulePath)
19435
19994
  ]);
19436
19995
  return resolvedEntryPoint === resolvedModulePath;
19437
19996
  } catch {