terminal-pilot 0.0.20 → 0.0.21

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.
@@ -78,7 +78,7 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
78
78
  }
79
79
 
80
80
  // src/cli.ts
81
- import { realpath as realpath2 } from "node:fs/promises";
81
+ import { realpath as realpath3 } from "node:fs/promises";
82
82
  import path23 from "node:path";
83
83
  import { fileURLToPath as fileURLToPath5 } from "node:url";
84
84
 
@@ -92,7 +92,7 @@ import {
92
92
  Option
93
93
  } from "commander";
94
94
 
95
- // ../design-system/src/internal/color-support.ts
95
+ // ../toolcraft-design/src/internal/color-support.ts
96
96
  function supportsColor(env = process.env, stream = process.stdout) {
97
97
  if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
98
98
  return true;
@@ -106,7 +106,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
106
106
  return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
107
107
  }
108
108
 
109
- // ../design-system/src/components/color.ts
109
+ // ../toolcraft-design/src/components/color.ts
110
110
  var reset = "\x1B[0m";
111
111
  var ansiStyles = {
112
112
  reset: { open: reset },
@@ -208,41 +208,135 @@ function createColor(styles = []) {
208
208
  }
209
209
  var color = createColor();
210
210
 
211
- // ../design-system/src/tokens/colors.ts
212
- var dark = {
213
- header: (text5) => color.magentaBright.bold(text5),
214
- divider: (text5) => color.dim(text5),
215
- prompt: (text5) => color.cyan(text5),
216
- number: (text5) => color.cyanBright(text5),
217
- intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
218
- resolvedSymbol: color.magenta("\u25C7"),
219
- errorSymbol: color.red("\u25A0"),
220
- accent: (text5) => color.cyan(text5),
221
- muted: (text5) => color.dim(text5),
222
- success: (text5) => color.green(text5),
223
- warning: (text5) => color.yellow(text5),
224
- error: (text5) => color.red(text5),
225
- info: (text5) => color.magenta(text5),
226
- badge: (text5) => color.bgYellow.black(` ${text5} `)
211
+ // ../toolcraft-design/src/tokens/brand.ts
212
+ var brands = {
213
+ purple: { name: "purple", primary: "#a200ff" },
214
+ blue: { name: "blue", primary: "#2f6fed" },
215
+ green: { name: "green", primary: "#1f9d57" }
227
216
  };
228
- var light = {
229
- header: (text5) => color.hex("#a200ff").bold(text5),
230
- divider: (text5) => color.hex("#666666")(text5),
231
- prompt: (text5) => color.hex("#006699").bold(text5),
232
- number: (text5) => color.hex("#0077cc").bold(text5),
233
- intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
234
- resolvedSymbol: color.hex("#a200ff")("\u25C7"),
235
- errorSymbol: color.hex("#cc0000")("\u25A0"),
236
- accent: (text5) => color.hex("#006699").bold(text5),
237
- muted: (text5) => color.hex("#666666")(text5),
238
- success: (text5) => color.hex("#008800")(text5),
239
- warning: (text5) => color.hex("#cc6600")(text5),
240
- error: (text5) => color.hex("#cc0000")(text5),
241
- info: (text5) => color.hex("#a200ff")(text5),
242
- badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
217
+
218
+ // ../toolcraft-design/src/internal/theme-state.ts
219
+ var defaults = {
220
+ brand: "purple",
221
+ label: "Poe"
243
222
  };
223
+ var config = { ...defaults };
224
+ var revision = 0;
225
+ var brandConfigured = false;
226
+ function configureTheme(patch) {
227
+ if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
228
+ throw new Error(`Unknown brand: ${patch.brand}`);
229
+ }
230
+ config = {
231
+ brand: patch.brand ?? config.brand,
232
+ label: patch.label ?? config.label
233
+ };
234
+ if (patch.brand !== void 0) {
235
+ brandConfigured = true;
236
+ }
237
+ revision += 1;
238
+ }
239
+ function getThemeConfig() {
240
+ return { ...config };
241
+ }
242
+ function getThemeRevision() {
243
+ return revision;
244
+ }
245
+ function isThemeBrandConfigured() {
246
+ return brandConfigured;
247
+ }
244
248
 
245
- // ../design-system/src/tokens/typography.ts
249
+ // ../toolcraft-design/src/tokens/colors.ts
250
+ var brand = brands.purple.primary;
251
+ function withStyles(palette, styles) {
252
+ return Object.defineProperty(palette, "styles", {
253
+ value: styles,
254
+ enumerable: false
255
+ });
256
+ }
257
+ function brandColor(activeBrand, purple) {
258
+ return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
259
+ }
260
+ function brandBackground(activeBrand, purple) {
261
+ return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
262
+ }
263
+ function createPalette(activeBrand, mode) {
264
+ const isPurple = activeBrand.name === "purple";
265
+ if (mode === "light") {
266
+ const active2 = color.hex(activeBrand.primary);
267
+ const prompt2 = isPurple ? color.hex("#006699") : active2;
268
+ const number2 = isPurple ? color.hex("#0077cc") : active2;
269
+ return withStyles(
270
+ {
271
+ header: (text5) => active2.bold(text5),
272
+ divider: (text5) => color.hex("#666666")(text5),
273
+ prompt: (text5) => prompt2.bold(text5),
274
+ number: (text5) => number2.bold(text5),
275
+ intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
276
+ get resolvedSymbol() {
277
+ return active2("\u25C7");
278
+ },
279
+ get errorSymbol() {
280
+ return color.hex("#cc0000")("\u25A0");
281
+ },
282
+ accent: (text5) => prompt2.bold(text5),
283
+ muted: (text5) => color.hex("#666666")(text5),
284
+ success: (text5) => color.hex("#008800")(text5),
285
+ warning: (text5) => color.hex("#cc6600")(text5),
286
+ error: (text5) => color.hex("#cc0000")(text5),
287
+ info: (text5) => active2(text5),
288
+ badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
289
+ },
290
+ {
291
+ accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
292
+ muted: { fg: "#666666" },
293
+ success: { fg: "#008800" },
294
+ warning: { fg: "#cc6600" },
295
+ error: { fg: "#cc0000" },
296
+ info: { fg: activeBrand.primary }
297
+ }
298
+ );
299
+ }
300
+ const active = brandColor(activeBrand, color.magenta);
301
+ const activeBright = brandColor(activeBrand, color.magentaBright);
302
+ const activeBackground = brandBackground(activeBrand, color.bgMagenta);
303
+ const prompt = isPurple ? color.cyan : active;
304
+ const number = isPurple ? color.cyanBright : active;
305
+ return withStyles(
306
+ {
307
+ header: (text5) => activeBright.bold(text5),
308
+ divider: (text5) => color.dim(text5),
309
+ prompt: (text5) => prompt(text5),
310
+ number: (text5) => number(text5),
311
+ intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
312
+ get resolvedSymbol() {
313
+ return active("\u25C7");
314
+ },
315
+ get errorSymbol() {
316
+ return color.red("\u25A0");
317
+ },
318
+ accent: (text5) => prompt(text5),
319
+ muted: (text5) => color.dim(text5),
320
+ success: (text5) => color.green(text5),
321
+ warning: (text5) => color.yellow(text5),
322
+ error: (text5) => color.red(text5),
323
+ info: (text5) => active(text5),
324
+ badge: (text5) => color.bgYellow.black(` ${text5} `)
325
+ },
326
+ {
327
+ accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
328
+ muted: { dim: true },
329
+ success: { fg: "green" },
330
+ warning: { fg: "yellow" },
331
+ error: { fg: "red" },
332
+ info: { fg: isPurple ? "magenta" : activeBrand.primary }
333
+ }
334
+ );
335
+ }
336
+ var dark = createPalette(brands.purple, "dark");
337
+ var light = createPalette(brands.purple, "light");
338
+
339
+ // ../toolcraft-design/src/tokens/typography.ts
246
340
  var typography = {
247
341
  bold: (text5) => color.bold(text5),
248
342
  dim: (text5) => color.dim(text5),
@@ -251,14 +345,14 @@ var typography = {
251
345
  strikethrough: (text5) => color.strikethrough(text5)
252
346
  };
253
347
 
254
- // ../design-system/src/tokens/widths.ts
348
+ // ../toolcraft-design/src/tokens/widths.ts
255
349
  var widths = {
256
350
  header: 60,
257
351
  helpColumn: 24,
258
352
  maxLine: 80
259
353
  };
260
354
 
261
- // ../design-system/src/internal/output-format.ts
355
+ // ../toolcraft-design/src/internal/output-format.ts
262
356
  import { AsyncLocalStorage } from "node:async_hooks";
263
357
  var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
264
358
  var formatStorage = new AsyncLocalStorage();
@@ -279,7 +373,7 @@ function resetOutputFormatCache() {
279
373
  cached = void 0;
280
374
  }
281
375
 
282
- // ../design-system/src/internal/theme-detect.ts
376
+ // ../toolcraft-design/src/internal/theme-detect.ts
283
377
  function detectThemeFromEnv(env) {
284
378
  const apple = env.APPLE_INTERFACE_STYLE;
285
379
  if (typeof apple === "string") {
@@ -316,17 +410,30 @@ function resolveThemeName(env = process.env) {
316
410
  }
317
411
  return "dark";
318
412
  }
319
- var cachedTheme;
413
+ var themeCache = /* @__PURE__ */ new Map();
414
+ var cachedRevision = -1;
320
415
  function getTheme(env) {
416
+ const themeName = resolveThemeName(env);
417
+ const config2 = getThemeConfig();
418
+ const requestedBrand = env?.POE_BRAND?.toLowerCase();
419
+ const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
420
+ const revision2 = getThemeRevision();
421
+ if (revision2 !== cachedRevision) {
422
+ themeCache.clear();
423
+ cachedRevision = revision2;
424
+ }
425
+ const cacheKey = `${activeBrandName}:${themeName}`;
426
+ const cachedTheme = themeCache.get(cacheKey);
321
427
  if (cachedTheme) {
322
428
  return cachedTheme;
323
429
  }
324
- const themeName = resolveThemeName(env);
325
- cachedTheme = themeName === "light" ? light : dark;
326
- return cachedTheme;
430
+ const activeBrand = brands[activeBrandName];
431
+ const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
432
+ themeCache.set(cacheKey, theme);
433
+ return theme;
327
434
  }
328
435
 
329
- // ../design-system/src/components/text.ts
436
+ // ../toolcraft-design/src/components/text.ts
330
437
  function renderMarkdownInline(content) {
331
438
  return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
332
439
  }
@@ -442,7 +549,7 @@ var text = {
442
549
  }
443
550
  };
444
551
 
445
- // ../design-system/src/components/symbols.ts
552
+ // ../toolcraft-design/src/components/symbols.ts
446
553
  var symbols = {
447
554
  get info() {
448
555
  const format = resolveOutputFormat();
@@ -496,12 +603,12 @@ var symbols = {
496
603
  }
497
604
  };
498
605
 
499
- // ../design-system/src/internal/strip-ansi.ts
606
+ // ../toolcraft-design/src/internal/strip-ansi.ts
500
607
  function stripAnsi2(value) {
501
608
  return value.replace(/\u001b\[[0-9;]*m/g, "");
502
609
  }
503
610
 
504
- // ../design-system/src/prompts/primitives/log.ts
611
+ // ../toolcraft-design/src/prompts/primitives/log.ts
505
612
  function renderMarkdownInline2(value) {
506
613
  return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
507
614
  }
@@ -628,7 +735,7 @@ var log = {
628
735
  error
629
736
  };
630
737
 
631
- // ../design-system/src/components/logger.ts
738
+ // ../toolcraft-design/src/components/logger.ts
632
739
  function createLogger(emitter) {
633
740
  const emit = (level, message2) => {
634
741
  if (emitter) {
@@ -689,7 +796,7 @@ function createLogger(emitter) {
689
796
  }
690
797
  var logger = createLogger();
691
798
 
692
- // ../design-system/src/components/help-formatter.ts
799
+ // ../toolcraft-design/src/components/help-formatter.ts
693
800
  var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
694
801
  function normalizeInline(value) {
695
802
  return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
@@ -865,7 +972,7 @@ function formatOptionList(options) {
865
972
  });
866
973
  }
867
974
 
868
- // ../design-system/src/components/help-formatter-plain.ts
975
+ // ../toolcraft-design/src/components/help-formatter-plain.ts
869
976
  var help_formatter_plain_exports = {};
870
977
  __export(help_formatter_plain_exports, {
871
978
  formatColumns: () => formatColumns2,
@@ -1002,7 +1109,7 @@ function formatOptionList2(options) {
1002
1109
  });
1003
1110
  }
1004
1111
 
1005
- // ../design-system/src/components/table.ts
1112
+ // ../toolcraft-design/src/components/table.ts
1006
1113
  var reset2 = "\x1B[0m";
1007
1114
  var ellipsis = "\u2026";
1008
1115
  var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -1286,7 +1393,7 @@ function renderTable(options) {
1286
1393
  }
1287
1394
  }
1288
1395
 
1289
- // ../design-system/src/components/detail-card.ts
1396
+ // ../toolcraft-design/src/components/detail-card.ts
1290
1397
  function wrap(value, width) {
1291
1398
  const lines = [];
1292
1399
  for (const paragraph of value.split("\n")) {
@@ -1349,7 +1456,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
1349
1456
  return blocks.join("\n\n");
1350
1457
  }
1351
1458
 
1352
- // ../design-system/src/components/template.ts
1459
+ // ../toolcraft-design/src/components/template.ts
1353
1460
  var MAX_PARTIAL_DEPTH = 100;
1354
1461
  var HTML_ESCAPE = {
1355
1462
  "&": "&",
@@ -1761,22 +1868,22 @@ function hasProperty(value, key2) {
1761
1868
  return Object.prototype.hasOwnProperty.call(value, key2);
1762
1869
  }
1763
1870
 
1764
- // ../design-system/src/components/browser.ts
1871
+ // ../toolcraft-design/src/components/browser.ts
1765
1872
  import { spawn } from "node:child_process";
1766
1873
  import process2 from "node:process";
1767
1874
 
1768
- // ../design-system/src/acp/writer.ts
1875
+ // ../toolcraft-design/src/acp/writer.ts
1769
1876
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
1770
1877
  var storage = new AsyncLocalStorage2();
1771
1878
 
1772
- // ../design-system/src/dashboard/terminal-width.ts
1879
+ // ../toolcraft-design/src/dashboard/terminal-width.ts
1773
1880
  var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1774
1881
 
1775
- // ../design-system/src/dashboard/terminal.ts
1882
+ // ../toolcraft-design/src/dashboard/terminal.ts
1776
1883
  import readline from "node:readline";
1777
1884
  import { PassThrough } from "node:stream";
1778
1885
 
1779
- // ../design-system/src/explorer/state.ts
1886
+ // ../toolcraft-design/src/explorer/state.ts
1780
1887
  var REGION_HEADER = 1 << 0;
1781
1888
  var REGION_LIST = 1 << 1;
1782
1889
  var REGION_DETAIL = 1 << 2;
@@ -1785,10 +1892,10 @@ var REGION_MODAL = 1 << 4;
1785
1892
  var REGION_TOAST = 1 << 5;
1786
1893
  var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
1787
1894
 
1788
- // ../design-system/src/prompts/index.ts
1895
+ // ../toolcraft-design/src/prompts/index.ts
1789
1896
  import * as clack from "@clack/prompts";
1790
1897
 
1791
- // ../design-system/src/prompts/primitives/cancel.ts
1898
+ // ../toolcraft-design/src/prompts/primitives/cancel.ts
1792
1899
  import { isCancel } from "@clack/prompts";
1793
1900
  function cancel(msg = "") {
1794
1901
  if (resolveOutputFormat() !== "terminal") {
@@ -1799,7 +1906,7 @@ function cancel(msg = "") {
1799
1906
  `);
1800
1907
  }
1801
1908
 
1802
- // ../design-system/src/prompts/primitives/note.ts
1909
+ // ../toolcraft-design/src/prompts/primitives/note.ts
1803
1910
  function getVisibleWidth(value) {
1804
1911
  return stripAnsi2(value).length;
1805
1912
  }
@@ -1848,10 +1955,10 @@ function note(message2, title) {
1848
1955
  `);
1849
1956
  }
1850
1957
 
1851
- // ../design-system/src/static/spinner.ts
1958
+ // ../toolcraft-design/src/static/spinner.ts
1852
1959
  var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
1853
1960
 
1854
- // ../design-system/src/prompts/index.ts
1961
+ // ../toolcraft-design/src/prompts/index.ts
1855
1962
  async function select2(opts) {
1856
1963
  return clack.select(opts);
1857
1964
  }
@@ -1894,19 +2001,19 @@ var ApprovalDeclinedError = class extends UserError {
1894
2001
  };
1895
2002
 
1896
2003
  // ../toolcraft/src/human-in-loop/config.ts
1897
- function validateHumanInLoopOnDefine(config) {
1898
- const label = Array.isArray(config.children) ? "group" : "command";
1899
- if (config.confirm === true && config.humanInLoop !== void 0 && config.humanInLoop !== null) {
1900
- throw new Error(`${label} '${config.name}': use either confirm or humanInLoop, not both`);
2004
+ function validateHumanInLoopOnDefine(config2) {
2005
+ const label = Array.isArray(config2.children) ? "group" : "command";
2006
+ if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
2007
+ throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
1901
2008
  }
1902
- if (config.humanInLoop === void 0 || config.humanInLoop === null) {
2009
+ if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
1903
2010
  return;
1904
2011
  }
1905
- if (config.humanInLoop.mode !== "sync" && config.humanInLoop.mode !== "async") {
1906
- throw new Error(`${label} '${config.name}': humanInLoop.mode must be "sync" or "async"`);
2012
+ if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
2013
+ throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
1907
2014
  }
1908
- if (typeof config.humanInLoop.message !== "function") {
1909
- throw new Error(`${label} '${config.name}': humanInLoop.message must be a function`);
2015
+ if (typeof config2.humanInLoop.message !== "function") {
2016
+ throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
1910
2017
  }
1911
2018
  }
1912
2019
  function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
@@ -1982,12 +2089,12 @@ function assertValidBranches(branches, discriminator) {
1982
2089
  }
1983
2090
  }
1984
2091
  }
1985
- function OneOf(config) {
1986
- assertValidBranches(config.branches, config.discriminator);
2092
+ function OneOf(config2) {
2093
+ assertValidBranches(config2.branches, config2.discriminator);
1987
2094
  return {
1988
2095
  kind: "oneOf",
1989
- discriminator: config.discriminator,
1990
- branches: config.branches
2096
+ discriminator: config2.discriminator,
2097
+ branches: config2.branches
1991
2098
  };
1992
2099
  }
1993
2100
 
@@ -2237,22 +2344,22 @@ function cloneStringArray(values) {
2237
2344
  function cloneStringRecord(values) {
2238
2345
  return values === void 0 ? void 0 : { ...values };
2239
2346
  }
2240
- function cloneMcpServerConfig(config) {
2241
- if (config === void 0) {
2347
+ function cloneMcpServerConfig(config2) {
2348
+ if (config2 === void 0) {
2242
2349
  return void 0;
2243
2350
  }
2244
- if (config.transport === "stdio") {
2351
+ if (config2.transport === "stdio") {
2245
2352
  return {
2246
2353
  transport: "stdio",
2247
- command: config.command,
2248
- args: cloneStringArray(config.args),
2249
- env: cloneStringRecord(config.env)
2354
+ command: config2.command,
2355
+ args: cloneStringArray(config2.args),
2356
+ env: cloneStringRecord(config2.env)
2250
2357
  };
2251
2358
  }
2252
2359
  return {
2253
2360
  transport: "http",
2254
- url: config.url,
2255
- headers: cloneStringRecord(config.headers)
2361
+ url: config2.url,
2362
+ headers: cloneStringRecord(config2.headers)
2256
2363
  };
2257
2364
  }
2258
2365
  function cloneRenameMap(rename5) {
@@ -2493,57 +2600,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
2493
2600
  function resolveGroupScope(ownScope, inheritedScope) {
2494
2601
  return cloneScope(ownScope ?? inheritedScope);
2495
2602
  }
2496
- function createBaseCommand(config) {
2603
+ function createBaseCommand(config2) {
2497
2604
  const command = {
2498
2605
  kind: "command",
2499
- name: config.name,
2500
- description: config.description,
2501
- aliases: [...config.aliases ?? []],
2502
- positional: [...config.positional ?? []],
2503
- params: config.params,
2504
- secrets: cloneSecrets(config.secrets),
2505
- scope: resolveCommandScope(config.scope, void 0),
2506
- confirm: config.confirm ?? false,
2507
- humanInLoop: config.humanInLoop,
2508
- requires: cloneRequires(config.requires),
2509
- handler: config.handler,
2510
- render: config.render
2606
+ name: config2.name,
2607
+ description: config2.description,
2608
+ aliases: [...config2.aliases ?? []],
2609
+ positional: [...config2.positional ?? []],
2610
+ params: config2.params,
2611
+ secrets: cloneSecrets(config2.secrets),
2612
+ scope: resolveCommandScope(config2.scope, void 0),
2613
+ confirm: config2.confirm ?? false,
2614
+ humanInLoop: config2.humanInLoop,
2615
+ requires: cloneRequires(config2.requires),
2616
+ handler: config2.handler,
2617
+ render: config2.render
2511
2618
  };
2512
2619
  Object.defineProperty(command, commandConfigSymbol, {
2513
2620
  value: {
2514
- scope: cloneScope(config.scope),
2515
- humanInLoop: config.humanInLoop,
2516
- secrets: cloneSecrets(config.secrets),
2517
- requires: cloneRequires(config.requires),
2621
+ scope: cloneScope(config2.scope),
2622
+ humanInLoop: config2.humanInLoop,
2623
+ secrets: cloneSecrets(config2.secrets),
2624
+ requires: cloneRequires(config2.requires),
2518
2625
  sourcePath: inferCommandSourcePath()
2519
2626
  }
2520
2627
  });
2521
2628
  return command;
2522
2629
  }
2523
- function createBaseGroup(config) {
2630
+ function createBaseGroup(config2) {
2524
2631
  const group = {
2525
2632
  kind: "group",
2526
- name: config.name,
2527
- description: config.description,
2528
- aliases: [...config.aliases ?? []],
2529
- scope: resolveGroupScope(config.scope, void 0),
2530
- humanInLoop: config.humanInLoop,
2531
- secrets: cloneSecrets(config.secrets),
2532
- requires: cloneRequires(config.requires),
2633
+ name: config2.name,
2634
+ description: config2.description,
2635
+ aliases: [...config2.aliases ?? []],
2636
+ scope: resolveGroupScope(config2.scope, void 0),
2637
+ humanInLoop: config2.humanInLoop,
2638
+ secrets: cloneSecrets(config2.secrets),
2639
+ requires: cloneRequires(config2.requires),
2533
2640
  children: [],
2534
2641
  default: void 0
2535
2642
  };
2536
2643
  Object.defineProperty(group, groupConfigSymbol, {
2537
2644
  value: {
2538
- mcp: cloneMcpServerConfig(config.mcp),
2539
- scope: cloneScope(config.scope),
2540
- humanInLoop: config.humanInLoop,
2541
- secrets: cloneSecrets(config.secrets),
2542
- tools: cloneStringArray(config.tools),
2543
- rename: cloneRenameMap(config.rename),
2544
- requires: cloneRequires(config.requires),
2545
- children: [...config.children],
2546
- default: config.default
2645
+ mcp: cloneMcpServerConfig(config2.mcp),
2646
+ scope: cloneScope(config2.scope),
2647
+ humanInLoop: config2.humanInLoop,
2648
+ secrets: cloneSecrets(config2.secrets),
2649
+ tools: cloneStringArray(config2.tools),
2650
+ rename: cloneRenameMap(config2.rename),
2651
+ requires: cloneRequires(config2.requires),
2652
+ children: [...config2.children],
2653
+ default: config2.default
2547
2654
  }
2548
2655
  });
2549
2656
  return group;
@@ -2646,10 +2753,10 @@ function materializeNode(node, inherited) {
2646
2753
  }
2647
2754
  return materializeGroup(node, inherited);
2648
2755
  }
2649
- function defineCommand(config) {
2650
- validateHumanInLoopOnDefine(config);
2756
+ function defineCommand(config2) {
2757
+ validateHumanInLoopOnDefine(config2);
2651
2758
  return materializeCommand(
2652
- createBaseCommand(config),
2759
+ createBaseCommand(config2),
2653
2760
  {
2654
2761
  scope: void 0,
2655
2762
  humanInLoop: void 0,
@@ -2658,10 +2765,10 @@ function defineCommand(config) {
2658
2765
  }
2659
2766
  );
2660
2767
  }
2661
- function defineGroup(config) {
2662
- validateRenameMap(config.rename);
2663
- validateHumanInLoopOnDefine(config);
2664
- return materializeGroup(createBaseGroup(config), {
2768
+ function defineGroup(config2) {
2769
+ validateRenameMap(config2.rename);
2770
+ validateHumanInLoopOnDefine(config2);
2771
+ return materializeGroup(createBaseGroup(config2), {
2665
2772
  scope: void 0,
2666
2773
  humanInLoop: void 0,
2667
2774
  secrets: {},
@@ -2830,7 +2937,7 @@ import path3 from "node:path";
2830
2937
  // ../process-runner/src/docker/docker-execution-env.ts
2831
2938
  import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
2832
2939
  import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
2833
- import { readdir, readFile, writeFile } from "node:fs/promises";
2940
+ import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
2834
2941
  import { tmpdir as tmpdir2 } from "node:os";
2835
2942
  import path5 from "node:path";
2836
2943
 
@@ -4518,7 +4625,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
4518
4625
  }
4519
4626
  return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
4520
4627
  }
4521
- function createdFrontmatter(defaults, input, initialState, mode) {
4628
+ function createdFrontmatter(defaults2, input, initialState, mode) {
4522
4629
  const frontmatter = mode !== "passthrough" ? {
4523
4630
  $schema: TASK_SCHEMA_ID,
4524
4631
  kind: TASK_KIND,
@@ -4530,7 +4637,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
4530
4637
  state: initialState
4531
4638
  };
4532
4639
  const reservedKeys = reservedFrontmatterKeys(mode);
4533
- for (const [key2, value] of Object.entries(defaults.metadata)) {
4640
+ for (const [key2, value] of Object.entries(defaults2.metadata)) {
4534
4641
  if (!reservedKeys.has(key2)) {
4535
4642
  setOwnValue(frontmatter, key2, value);
4536
4643
  }
@@ -5276,13 +5383,13 @@ function matchesFilter(task, filter) {
5276
5383
  }
5277
5384
  return true;
5278
5385
  }
5279
- function createTaskRecord(defaults, input, initialState) {
5386
+ function createTaskRecord(defaults2, input, initialState) {
5280
5387
  const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
5281
5388
  name: input.name,
5282
5389
  state: initialState,
5283
5390
  description: input.description ?? ""
5284
5391
  });
5285
- for (const [key2, value] of Object.entries(defaults.metadata)) {
5392
+ for (const [key2, value] of Object.entries(defaults2.metadata)) {
5286
5393
  if (!RESERVED_TASK_KEYS.has(key2)) {
5287
5394
  taskRecord[key2] = value;
5288
5395
  }
@@ -6656,7 +6763,7 @@ function isMissingStateError(error3) {
6656
6763
  }
6657
6764
 
6658
6765
  // ../toolcraft/src/error-report.ts
6659
- import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
6766
+ import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
6660
6767
  import { randomUUID as randomUUID3 } from "node:crypto";
6661
6768
  import os from "node:os";
6662
6769
  import path13 from "node:path";
@@ -7175,19 +7282,24 @@ function createAuthStoreClientStore(options) {
7175
7282
  }
7176
7283
  };
7177
7284
  }
7178
- function createNamedSecretStore(key2, options, defaults) {
7285
+ function createNamedSecretStore(key2, options, defaults2) {
7179
7286
  const hash = crypto.createHash("sha256").update(key2).digest("hex");
7180
- const parsedFilePath = options.fileStore?.filePath === void 0 ? null : path11.parse(options.fileStore.filePath);
7287
+ const configuredFilePath = options.fileStore?.filePath;
7288
+ const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
7181
7289
  const fileStore = {
7182
7290
  ...options.fileStore,
7183
- salt: options.fileStore?.salt ?? defaults.salt,
7184
- defaultDirectory: parsedFilePath?.dir || options.fileStore?.defaultDirectory || defaults.directory,
7291
+ filePath: parsedFilePath === null ? void 0 : path11.join(
7292
+ parsedFilePath.dir,
7293
+ `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
7294
+ ),
7295
+ salt: options.fileStore?.salt ?? defaults2.salt,
7296
+ defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
7185
7297
  defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
7186
7298
  };
7187
7299
  const keychainStore = {
7188
7300
  ...options.keychainStore,
7189
- service: options.keychainStore?.service ?? defaults.service,
7190
- account: `${options.keychainStore?.account ?? defaults.accountPrefix}:${hash}`
7301
+ service: options.keychainStore?.service ?? defaults2.service,
7302
+ account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
7191
7303
  };
7192
7304
  return createSecretStore({ ...options, fileStore, keychainStore }).store;
7193
7305
  }
@@ -8787,6 +8899,9 @@ var McpClient = class {
8787
8899
  const abortPromise = new Promise((_, reject) => {
8788
8900
  const rejectWithAbortReason = () => {
8789
8901
  sendCancellationNotification();
8902
+ if (requestId !== void 0) {
8903
+ messageLayer.cancelRequest(requestId, signal.reason);
8904
+ }
8790
8905
  reject(signal.reason);
8791
8906
  };
8792
8907
  abortListener = rejectWithAbortReason;
@@ -8961,11 +9076,13 @@ var StdioTransport = class _StdioTransport {
8961
9076
  const child = this.child;
8962
9077
  this.readable = child.stdout;
8963
9078
  this.writable = child.stdin;
9079
+ const stderrDecoder = new TextDecoder();
8964
9080
  child.stderr.on("data", (chunk) => {
8965
- this.stderrOutput += chunkToString(chunk);
8966
- if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
8967
- this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
8968
- }
9081
+ const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
9082
+ this.appendStderrOutput(decoded);
9083
+ });
9084
+ child.stderr.once("end", () => {
9085
+ this.appendStderrOutput(stderrDecoder.decode());
8969
9086
  });
8970
9087
  this.closed = new Promise((resolve) => {
8971
9088
  let settled = false;
@@ -9005,6 +9122,15 @@ var StdioTransport = class _StdioTransport {
9005
9122
  getStderrOutput() {
9006
9123
  return this.stderrOutput;
9007
9124
  }
9125
+ appendStderrOutput(chunk) {
9126
+ if (chunk.length === 0) {
9127
+ return;
9128
+ }
9129
+ this.stderrOutput += chunk;
9130
+ if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
9131
+ this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
9132
+ }
9133
+ }
9008
9134
  dispose(reason = new Error("Stdio transport disposed")) {
9009
9135
  void reason;
9010
9136
  if (this.disposed) {
@@ -9412,15 +9538,6 @@ function serializeJsonRpcMessage(message2) {
9412
9538
  return `${JSON.stringify(message2)}
9413
9539
  `;
9414
9540
  }
9415
- function chunkToString(chunk) {
9416
- if (typeof chunk === "string") {
9417
- return chunk;
9418
- }
9419
- if (chunk instanceof Uint8Array) {
9420
- return Buffer.from(chunk).toString("utf8");
9421
- }
9422
- return String(chunk);
9423
- }
9424
9541
  function normalizeLine(line) {
9425
9542
  return line.endsWith("\r") ? line.slice(0, -1) : line;
9426
9543
  }
@@ -9610,6 +9727,16 @@ var JsonRpcMessageLayer = class {
9610
9727
  }
9611
9728
  });
9612
9729
  }
9730
+ cancelRequest(requestId, reason) {
9731
+ const pending = this.pendingRequests.get(requestId);
9732
+ if (pending === void 0) {
9733
+ return false;
9734
+ }
9735
+ this.pendingRequests.delete(requestId);
9736
+ clearTimeout(pending.timeout);
9737
+ pending.reject(reason);
9738
+ return true;
9739
+ }
9613
9740
  dispose(reason = new Error("JSON-RPC message layer disposed")) {
9614
9741
  if (this.disposedError !== void 0) {
9615
9742
  return;
@@ -10678,10 +10805,10 @@ function validateRenameMap2(name, tools, rename5) {
10678
10805
  }
10679
10806
  }
10680
10807
  }
10681
- function createConnection(name, config) {
10808
+ function createConnection(name, config2) {
10682
10809
  const connection = {
10683
10810
  name,
10684
- config,
10811
+ config: config2,
10685
10812
  async dispose() {
10686
10813
  shutdownDisposers.delete(connection.dispose);
10687
10814
  connection.connecting = void 0;
@@ -10748,13 +10875,13 @@ async function writeCache(cachePath, cache) {
10748
10875
  await assertCachePathHasNoSymlinks(cachePath);
10749
10876
  await rename2(tempPath, cachePath);
10750
10877
  }
10751
- async function fetchCache(name, config) {
10878
+ async function fetchCache(name, config2) {
10752
10879
  const logger2 = createLogger((message2) => {
10753
10880
  process.stderr.write(`${message2}
10754
10881
  `);
10755
10882
  });
10756
10883
  logger2.info(`MCP ${name}: connecting`);
10757
- const client = await dialUpstream(name, config);
10884
+ const client = await dialUpstream(name, config2);
10758
10885
  try {
10759
10886
  logger2.info(`MCP ${name}: listing tools`);
10760
10887
  const tools = [];
@@ -10773,7 +10900,7 @@ async function fetchCache(name, config) {
10773
10900
  $schema: MCP_PROXY_SCHEMA_URL,
10774
10901
  version: 1,
10775
10902
  upstream,
10776
- configFingerprint: fingerprintMcpServerConfig(config),
10903
+ configFingerprint: fingerprintMcpServerConfig(config2),
10777
10904
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
10778
10905
  tools
10779
10906
  };
@@ -10843,8 +10970,8 @@ function isRefreshRequested(name, refresh) {
10843
10970
  }
10844
10971
  async function resolveSingleProxy(group, options) {
10845
10972
  const internal = getInternalGroupConfig2(group);
10846
- const config = internal.mcp;
10847
- if (config === void 0) {
10973
+ const config2 = internal.mcp;
10974
+ if (config2 === void 0) {
10848
10975
  return;
10849
10976
  }
10850
10977
  const name = group.name;
@@ -10854,21 +10981,21 @@ async function resolveSingleProxy(group, options) {
10854
10981
  let cache;
10855
10982
  let shouldWriteCache = false;
10856
10983
  if (isRefreshRequested(name, refresh)) {
10857
- cache = await fetchCache(name, config);
10984
+ cache = await fetchCache(name, config2);
10858
10985
  shouldWriteCache = true;
10859
10986
  } else {
10860
10987
  const storedCache = await readCache(cachePath);
10861
- if (storedCache && cacheMatchesConfig(storedCache, config)) {
10988
+ if (storedCache && cacheMatchesConfig(storedCache, config2)) {
10862
10989
  cache = storedCache;
10863
10990
  } else {
10864
- cache = await fetchCache(name, config);
10991
+ cache = await fetchCache(name, config2);
10865
10992
  shouldWriteCache = true;
10866
10993
  }
10867
10994
  }
10868
10995
  const tools = filterAllowlistedTools(cache.tools, internal.tools);
10869
10996
  validateRenameMap2(name, tools, internal.rename);
10870
10997
  const previousConnection = getProxyConnection(group);
10871
- const nextConnection = createConnection(name, config);
10998
+ const nextConnection = createConnection(name, config2);
10872
10999
  try {
10873
11000
  replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
10874
11001
  if (shouldWriteCache) {
@@ -10893,11 +11020,11 @@ async function resolveSingleProxy(group, options) {
10893
11020
  );
10894
11021
  }
10895
11022
  }
10896
- function cacheMatchesConfig(cache, config) {
10897
- return cache.configFingerprint === fingerprintMcpServerConfig(config);
11023
+ function cacheMatchesConfig(cache, config2) {
11024
+ return cache.configFingerprint === fingerprintMcpServerConfig(config2);
10898
11025
  }
10899
- function fingerprintMcpServerConfig(config) {
10900
- return createHash3("sha256").update(JSON.stringify(config)).digest("hex");
11026
+ function fingerprintMcpServerConfig(config2) {
11027
+ return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
10901
11028
  }
10902
11029
  function collectProxyGroups(root) {
10903
11030
  const groups = [];
@@ -10975,20 +11102,20 @@ function parseRefreshEnv(value) {
10975
11102
  const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
10976
11103
  return names.length === 0 ? void 0 : new Set(names);
10977
11104
  }
10978
- async function dialUpstream(name, config) {
11105
+ async function dialUpstream(name, config2) {
10979
11106
  const client = new McpClient({
10980
11107
  clientInfo: {
10981
11108
  name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
10982
11109
  version: DEFAULT_CLIENT_INFO.version
10983
11110
  }
10984
11111
  });
10985
- const transport = config.transport === "stdio" ? new StdioTransport({
10986
- command: config.command,
10987
- ...config.args === void 0 ? {} : { args: config.args },
10988
- ...config.env === void 0 ? {} : { env: config.env }
11112
+ const transport = config2.transport === "stdio" ? new StdioTransport({
11113
+ command: config2.command,
11114
+ ...config2.args === void 0 ? {} : { args: config2.args },
11115
+ ...config2.env === void 0 ? {} : { env: config2.env }
10989
11116
  }) : new HttpTransport({
10990
- url: config.url,
10991
- ...config.headers === void 0 ? {} : { headers: config.headers }
11117
+ url: config2.url,
11118
+ ...config2.headers === void 0 ? {} : { headers: config2.headers }
10992
11119
  });
10993
11120
  await client.connect(transport);
10994
11121
  return client;
@@ -10998,10 +11125,82 @@ async function resolveMcpProxies(root, options = {}) {
10998
11125
  await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
10999
11126
  }
11000
11127
 
11128
+ // ../toolcraft/src/redaction.ts
11129
+ var REDACTED_VALUE = "<redacted>";
11130
+ var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
11131
+ var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
11132
+ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
11133
+ function isPlainObject2(value) {
11134
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11135
+ }
11136
+ function normalizeName(name) {
11137
+ return name.toLowerCase().replace(/[^a-z0-9]/g, "");
11138
+ }
11139
+ function isSensitiveName(name) {
11140
+ const normalized = normalizeName(name);
11141
+ return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
11142
+ }
11143
+ function redactSecretLikeFieldsValue(value, name, seen) {
11144
+ if (name.length > 0 && isSensitiveName(name)) {
11145
+ return REDACTED_VALUE;
11146
+ }
11147
+ if (Array.isArray(value)) {
11148
+ if (seen.has(value)) {
11149
+ return "[Circular]";
11150
+ }
11151
+ seen.add(value);
11152
+ return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
11153
+ }
11154
+ if (isPlainObject2(value)) {
11155
+ if (seen.has(value)) {
11156
+ return "[Circular]";
11157
+ }
11158
+ seen.add(value);
11159
+ return Object.fromEntries(
11160
+ Object.entries(value).map(([key2, entry]) => [
11161
+ key2,
11162
+ redactSecretLikeFieldsValue(entry, key2, seen)
11163
+ ])
11164
+ );
11165
+ }
11166
+ return value;
11167
+ }
11168
+ function redactSecretLikeFields(value, name = "") {
11169
+ return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
11170
+ }
11171
+ function parseJsonObjectOrArray(value) {
11172
+ const trimmed = value.trim();
11173
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
11174
+ return void 0;
11175
+ }
11176
+ try {
11177
+ const parsed = JSON.parse(trimmed);
11178
+ return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
11179
+ } catch {
11180
+ return void 0;
11181
+ }
11182
+ }
11183
+ function redactHttpBody(body) {
11184
+ if (typeof body === "string") {
11185
+ const parsed = parseJsonObjectOrArray(body);
11186
+ return parsed === void 0 ? body : redactSecretLikeFields(parsed);
11187
+ }
11188
+ return redactSecretLikeFields(body);
11189
+ }
11190
+ function redactHttpHeaderValue(name, value) {
11191
+ const normalized = normalizeName(name);
11192
+ if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
11193
+ return "Bearer ****";
11194
+ }
11195
+ if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
11196
+ return REDACTED_VALUE;
11197
+ }
11198
+ return value;
11199
+ }
11200
+
11001
11201
  // ../toolcraft/src/error-report.ts
11002
11202
  var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
11003
- var DEFAULT_SENSITIVE_NAMES = ["password", "token", "apikey", "secret"];
11004
- function isPlainObject2(value) {
11203
+ function isPlainObject3(value) {
11005
11204
  return typeof value === "object" && value !== null && !Array.isArray(value);
11006
11205
  }
11007
11206
  function unwrapOptional(schema) {
@@ -11011,7 +11210,7 @@ function unwrapOptional(schema) {
11011
11210
  return schema;
11012
11211
  }
11013
11212
  function hasHttpContext(error3) {
11014
- return error3 instanceof Error && error3.name === "HttpError" && isPlainObject2(error3.request) && isPlainObject2(error3.response);
11213
+ return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
11015
11214
  }
11016
11215
  function isSkippedError(error3) {
11017
11216
  if (error3 instanceof ApprovalDeclinedError) {
@@ -11048,8 +11247,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
11048
11247
  throw new Error("Error report directory resolves outside project root.");
11049
11248
  }
11050
11249
  const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
11051
- realpath(projectRoot),
11052
- realpath(reportDir)
11250
+ realpath2(projectRoot),
11251
+ realpath2(reportDir)
11053
11252
  ]);
11054
11253
  if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
11055
11254
  throw new Error("Error report directory resolves outside project root.");
@@ -11104,9 +11303,24 @@ function redactValue(value) {
11104
11303
  }
11105
11304
  return `<set, ${value.length} chars>`;
11106
11305
  }
11107
- function isSensitiveName(name) {
11108
- const normalized = name.toLowerCase();
11109
- return DEFAULT_SENSITIVE_NAMES.some((candidate) => normalized.includes(candidate));
11306
+ function collectStringLeaves(value, output) {
11307
+ if (typeof value === "string") {
11308
+ if (value.length > 0) {
11309
+ output.add(value);
11310
+ }
11311
+ return;
11312
+ }
11313
+ if (Array.isArray(value)) {
11314
+ for (const entry of value) {
11315
+ collectStringLeaves(entry, output);
11316
+ }
11317
+ return;
11318
+ }
11319
+ if (isPlainObject3(value)) {
11320
+ for (const entry of Object.values(value)) {
11321
+ collectStringLeaves(entry, output);
11322
+ }
11323
+ }
11110
11324
  }
11111
11325
  function schemaSecretValue(schema) {
11112
11326
  const unwrapped = unwrapOptional(schema);
@@ -11127,7 +11341,7 @@ function redactParamsValue(value, schema, name) {
11127
11341
  return "<redacted>";
11128
11342
  }
11129
11343
  const unwrapped = unwrapOptional(schema);
11130
- if (unwrapped.kind === "object" && isPlainObject2(value)) {
11344
+ if (unwrapped.kind === "object" && isPlainObject3(value)) {
11131
11345
  return Object.fromEntries(
11132
11346
  Object.entries(value).map(([key2, childValue]) => {
11133
11347
  const childSchema = unwrapped.shape[key2];
@@ -11149,6 +11363,52 @@ function redactParams(params17, command) {
11149
11363
  }
11150
11364
  return redactParamsValue(params17, command.params, "");
11151
11365
  }
11366
+ function collectSensitiveParamValues(value, schema, name, output) {
11367
+ if (shouldRedactParam(name, schema)) {
11368
+ collectStringLeaves(value, output);
11369
+ return;
11370
+ }
11371
+ const unwrapped = unwrapOptional(schema);
11372
+ if (unwrapped.kind === "object" && isPlainObject3(value)) {
11373
+ for (const [key2, childValue] of Object.entries(value)) {
11374
+ const childSchema = unwrapped.shape[key2];
11375
+ if (childSchema !== void 0) {
11376
+ collectSensitiveParamValues(childValue, childSchema, key2, output);
11377
+ }
11378
+ }
11379
+ return;
11380
+ }
11381
+ if (unwrapped.kind === "array" && Array.isArray(value)) {
11382
+ for (const entry of value) {
11383
+ collectSensitiveParamValues(entry, unwrapped.item, name, output);
11384
+ }
11385
+ }
11386
+ }
11387
+ function createReportStringRedactor(context, env) {
11388
+ const values = /* @__PURE__ */ new Set();
11389
+ for (const value of Object.values(context.secrets ?? {})) {
11390
+ if (value !== void 0 && value.length > 0) {
11391
+ values.add(value);
11392
+ }
11393
+ }
11394
+ for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
11395
+ const value = context.secrets?.[name] ?? env[secret.env];
11396
+ if (value !== void 0 && value.length > 0) {
11397
+ values.add(value);
11398
+ }
11399
+ }
11400
+ if (context.command !== void 0) {
11401
+ collectSensitiveParamValues(context.params, context.command.params, "", values);
11402
+ }
11403
+ const orderedValues = [...values].sort((left, right) => right.length - left.length);
11404
+ return (value) => {
11405
+ let redacted = value;
11406
+ for (const secretValue of orderedValues) {
11407
+ redacted = redacted.split(secretValue).join("<redacted>");
11408
+ }
11409
+ return redacted;
11410
+ };
11411
+ }
11152
11412
  function commandSecretEnvNames(secrets) {
11153
11413
  if (secrets === void 0) {
11154
11414
  return [];
@@ -11202,28 +11462,42 @@ function redactArgv(argv, options) {
11202
11462
  function stableJson(value) {
11203
11463
  return JSON.stringify(value, null, 2) ?? "undefined";
11204
11464
  }
11205
- function redactStructuredErrorField(name, value) {
11206
- if (typeof value === "string" && name.toLowerCase() === "authorization") {
11207
- return "Bearer ****";
11465
+ function redactStructuredErrorField(name, value, redactString) {
11466
+ if (typeof value === "string") {
11467
+ const redactedHeaderValue = redactHttpHeaderValue(name, value);
11468
+ if (redactedHeaderValue !== value) {
11469
+ return redactedHeaderValue;
11470
+ }
11471
+ if (isSensitiveName(name)) {
11472
+ return "<redacted>";
11473
+ }
11474
+ return redactString(value);
11208
11475
  }
11209
11476
  if (Array.isArray(value)) {
11210
- return value.map((entry) => redactStructuredErrorField(name, entry));
11477
+ return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
11211
11478
  }
11212
- if (isPlainObject2(value)) {
11479
+ if (isPlainObject3(value)) {
11213
11480
  return Object.fromEntries(
11214
- Object.entries(value).map(([key2, entry]) => [key2, redactStructuredErrorField(key2, entry)])
11481
+ Object.entries(value).map(([key2, entry]) => [
11482
+ key2,
11483
+ redactStructuredErrorField(key2, entry, redactString)
11484
+ ])
11215
11485
  );
11216
11486
  }
11217
11487
  return value;
11218
11488
  }
11219
- function ownStructuredFields(error3) {
11489
+ function ownStructuredFields(error3, redactString) {
11220
11490
  const fields = {};
11221
11491
  for (const key2 of Object.keys(error3)) {
11222
11492
  if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
11223
11493
  continue;
11224
11494
  }
11225
11495
  Object.defineProperty(fields, key2, {
11226
- value: redactStructuredErrorField(key2, error3[key2]),
11496
+ value: redactStructuredErrorField(
11497
+ key2,
11498
+ error3[key2],
11499
+ redactString
11500
+ ),
11227
11501
  enumerable: true,
11228
11502
  configurable: true,
11229
11503
  writable: true
@@ -11231,43 +11505,44 @@ function ownStructuredFields(error3) {
11231
11505
  }
11232
11506
  return fields;
11233
11507
  }
11234
- function formatStackChain(error3) {
11508
+ function formatStackChain(error3, redactString) {
11235
11509
  const lines = [];
11236
11510
  let current = error3;
11237
11511
  let index = 0;
11238
11512
  while (current !== void 0) {
11239
11513
  if (current instanceof Error) {
11240
- lines.push(
11241
- index === 0 ? current.stack ?? String(current) : `Caused by: ${current.stack ?? String(current)}`
11242
- );
11514
+ const stack = current.stack ?? String(current);
11515
+ lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
11243
11516
  current = current.cause;
11244
11517
  } else {
11245
- lines.push(index === 0 ? String(current) : `Caused by: ${String(current)}`);
11518
+ const message2 = String(current);
11519
+ lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
11246
11520
  current = void 0;
11247
11521
  }
11248
11522
  index += 1;
11249
11523
  }
11250
11524
  return lines.join("\n");
11251
11525
  }
11252
- function formatHeaderValue(name, value) {
11253
- return name.toLowerCase() === "authorization" ? "Bearer ****" : value;
11526
+ function formatHeaderValue(name, value, redactString) {
11527
+ return redactString(redactHttpHeaderValue(name, value));
11254
11528
  }
11255
- function formatHeaders(headers) {
11256
- return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
11529
+ function formatHeaders(headers, redactString) {
11530
+ return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
11257
11531
  }
11258
- function formatBody(body) {
11259
- if (typeof body === "string") {
11260
- return body;
11532
+ function formatBody(body, redactString) {
11533
+ const redactedBody = redactHttpBody(body);
11534
+ if (typeof redactedBody === "string") {
11535
+ return redactString(redactedBody);
11261
11536
  }
11262
- return stableJson(body);
11537
+ return redactString(stableJson(redactedBody));
11263
11538
  }
11264
- function formatHttpTranscript(error3) {
11539
+ function formatHttpTranscript(error3, redactString) {
11265
11540
  const requestLines = [
11266
11541
  `${error3.request.method} ${error3.request.url}`,
11267
- formatHeaders(error3.request.headers)
11542
+ formatHeaders(error3.request.headers, redactString)
11268
11543
  ].filter((line) => line.length > 0);
11269
11544
  if (error3.request.body !== void 0) {
11270
- requestLines.push("", formatBody(error3.request.body));
11545
+ requestLines.push("", formatBody(error3.request.body, redactString));
11271
11546
  }
11272
11547
  return [
11273
11548
  "Request:",
@@ -11275,9 +11550,9 @@ function formatHttpTranscript(error3) {
11275
11550
  "",
11276
11551
  "Response:",
11277
11552
  `${error3.response.status} ${error3.response.statusText}`,
11278
- formatHeaders(error3.response.headers),
11553
+ formatHeaders(error3.response.headers, redactString),
11279
11554
  "",
11280
- formatBody(error3.response.body)
11555
+ formatBody(error3.response.body, redactString)
11281
11556
  ].join("\n");
11282
11557
  }
11283
11558
  function resolveToolcraftVersion(version) {
@@ -11286,9 +11561,10 @@ function resolveToolcraftVersion(version) {
11286
11561
  function buildReport(context) {
11287
11562
  const env = context.env ?? process.env;
11288
11563
  const error3 = context.error;
11564
+ const redactString = createReportStringRedactor(context, env);
11289
11565
  const errorName = error3 instanceof Error ? error3.name : typeof error3;
11290
- const errorMessage = error3 instanceof Error ? error3.message : String(error3);
11291
- const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
11566
+ const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
11567
+ const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
11292
11568
  const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
11293
11569
  const value = context.secrets?.[name] ?? env[secret.env];
11294
11570
  return `${secret.env}=${redactValue(value)}`;
@@ -11302,7 +11578,9 @@ function buildReport(context) {
11302
11578
  `platform: ${process.platform} ${process.arch}`,
11303
11579
  "",
11304
11580
  "Argv",
11305
- stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets })),
11581
+ redactString(
11582
+ stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
11583
+ ),
11306
11584
  "",
11307
11585
  "Resolved Secrets",
11308
11586
  ...secretLines.length === 0 ? ["<none>"] : secretLines,
@@ -11311,19 +11589,19 @@ function buildReport(context) {
11311
11589
  context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
11312
11590
  "",
11313
11591
  "Parsed Params",
11314
- stableJson(redactParams(context.params, context.command)),
11592
+ redactString(stableJson(redactParams(context.params, context.command))),
11315
11593
  "",
11316
11594
  "Error",
11317
11595
  `name: ${errorName}`,
11318
11596
  `message: ${errorMessage}`,
11319
11597
  "structured fields:",
11320
- stableJson(structuredFields),
11598
+ redactString(stableJson(structuredFields)),
11321
11599
  "",
11322
11600
  "Stack",
11323
- formatStackChain(error3)
11601
+ formatStackChain(error3, redactString)
11324
11602
  ];
11325
11603
  if (hasHttpContext(error3)) {
11326
- lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
11604
+ lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
11327
11605
  }
11328
11606
  return `${lines.join("\n")}
11329
11607
  `;
@@ -11783,6 +12061,7 @@ ${rendered.join("\n")}`);
11783
12061
  }
11784
12062
 
11785
12063
  // ../toolcraft/src/cli.ts
12064
+ configureTheme({ brand: "blue", label: "Toolcraft" });
11786
12065
  var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
11787
12066
  "params",
11788
12067
  "secrets",
@@ -13216,7 +13495,7 @@ function createEnv2(values = process.env) {
13216
13495
  }
13217
13496
  };
13218
13497
  }
13219
- function isPlainObject3(value) {
13498
+ function isPlainObject4(value) {
13220
13499
  return typeof value === "object" && value !== null && !Array.isArray(value);
13221
13500
  }
13222
13501
  function hasFieldValue(value) {
@@ -13325,7 +13604,7 @@ async function loadPresetValues(fields, presetPath) {
13325
13604
  { cause: error3 }
13326
13605
  );
13327
13606
  }
13328
- if (!isPlainObject3(parsedPreset)) {
13607
+ if (!isPlainObject4(parsedPreset)) {
13329
13608
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
13330
13609
  }
13331
13610
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
@@ -13344,7 +13623,7 @@ async function loadPresetValues(fields, presetPath) {
13344
13623
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
13345
13624
  );
13346
13625
  }
13347
- if (!isPlainObject3(value)) {
13626
+ if (!isPlainObject4(value)) {
13348
13627
  throw new UserError(
13349
13628
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
13350
13629
  );
@@ -13387,8 +13666,8 @@ function matchesFixtureValue(expected, actual) {
13387
13666
  }
13388
13667
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
13389
13668
  }
13390
- if (isPlainObject3(expected)) {
13391
- if (!isPlainObject3(actual)) {
13669
+ if (isPlainObject4(expected)) {
13670
+ if (!isPlainObject4(actual)) {
13392
13671
  return false;
13393
13672
  }
13394
13673
  return Object.entries(expected).every(
@@ -13451,9 +13730,9 @@ function createFixtureFetch(entries) {
13451
13730
  };
13452
13731
  }
13453
13732
  function createFixtureFs(definition) {
13454
- const fsDefinition = isPlainObject3(definition) ? definition : {};
13455
- const readFileEntries = isPlainObject3(fsDefinition.readFile) ? fsDefinition.readFile : {};
13456
- const existsEntries = isPlainObject3(fsDefinition.exists) ? fsDefinition.exists : {};
13733
+ const fsDefinition = isPlainObject4(definition) ? definition : {};
13734
+ const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
13735
+ const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
13457
13736
  return {
13458
13737
  readFile: async (filePath) => {
13459
13738
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -13476,10 +13755,10 @@ function createFixtureFs(definition) {
13476
13755
  function resolveFixtureMethodResult(methodName, definition, args) {
13477
13756
  if (Array.isArray(definition)) {
13478
13757
  for (const entry of definition) {
13479
- if (!isPlainObject3(entry)) {
13758
+ if (!isPlainObject4(entry)) {
13480
13759
  continue;
13481
13760
  }
13482
- const explicitMatcher = isPlainObject3(entry.request) ? entry.request : void 0;
13761
+ const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
13483
13762
  const matcher = explicitMatcher ?? Object.fromEntries(
13484
13763
  Object.entries(entry).filter(
13485
13764
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -13491,7 +13770,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13491
13770
  matched = matchesFixtureValue(matcher.args, args);
13492
13771
  } else if (Object.keys(matcher).length === 0) {
13493
13772
  matched = true;
13494
- } else if (isPlainObject3(firstArg)) {
13773
+ } else if (isPlainObject4(firstArg)) {
13495
13774
  matched = matchesFixtureValue(matcher, firstArg);
13496
13775
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
13497
13776
  const [[, expectedValue]] = Object.entries(matcher);
@@ -13512,7 +13791,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13512
13791
  return Promise.resolve(null);
13513
13792
  }
13514
13793
  }
13515
- if (isPlainObject3(definition)) {
13794
+ if (isPlainObject4(definition)) {
13516
13795
  const firstArg = args[0];
13517
13796
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
13518
13797
  return Promise.resolve(definition[firstArg]);
@@ -13524,7 +13803,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13524
13803
  return Promise.resolve(null);
13525
13804
  }
13526
13805
  function createFixtureService(definition) {
13527
- const methods = isPlainObject3(definition) ? definition : {};
13806
+ const methods = isPlainObject4(definition) ? definition : {};
13528
13807
  return new Proxy(
13529
13808
  {},
13530
13809
  {
@@ -13622,7 +13901,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
13622
13901
  };
13623
13902
  }
13624
13903
  const scenario = await loadFixtureScenario(command, selector);
13625
- const scenarioServices = isPlainObject3(scenario.services) ? scenario.services : {};
13904
+ const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
13626
13905
  const customServiceNames = /* @__PURE__ */ new Set([
13627
13906
  ...Object.keys(services),
13628
13907
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -13904,7 +14183,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13904
14183
  if (itemSchema.kind !== "object") {
13905
14184
  return value;
13906
14185
  }
13907
- if (!isPlainObject3(value)) {
14186
+ if (!isPlainObject4(value)) {
13908
14187
  errors2.push({
13909
14188
  path: displayPath,
13910
14189
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -13939,7 +14218,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13939
14218
  );
13940
14219
  }
13941
14220
  case "object": {
13942
- if (!isPlainObject3(value)) {
14221
+ if (!isPlainObject4(value)) {
13943
14222
  errors2.push({
13944
14223
  path: displayPath,
13945
14224
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -13970,7 +14249,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13970
14249
  return result;
13971
14250
  }
13972
14251
  case "record": {
13973
- if (!isPlainObject3(value)) {
14252
+ if (!isPlainObject4(value)) {
13974
14253
  errors2.push({
13975
14254
  path: displayPath,
13976
14255
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -14396,10 +14675,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
14396
14675
  }
14397
14676
  }
14398
14677
  function isStringRecord(value) {
14399
- return isPlainObject3(value) && Object.values(value).every((entry) => typeof entry === "string");
14678
+ return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
14400
14679
  }
14401
14680
  function isHttpErrorLike(error3) {
14402
- if (!isPlainObject3(error3)) {
14681
+ if (!isPlainObject4(error3)) {
14403
14682
  return false;
14404
14683
  }
14405
14684
  if (error3.name !== "HttpError" || typeof error3.message !== "string") {
@@ -14407,7 +14686,7 @@ function isHttpErrorLike(error3) {
14407
14686
  }
14408
14687
  const request = error3.request;
14409
14688
  const response = error3.response;
14410
- 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;
14689
+ 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;
14411
14690
  }
14412
14691
  function hasTypedOptionalField(value, field, type2) {
14413
14692
  return !(field in value) || typeof value[field] === type2;
@@ -14416,7 +14695,7 @@ function isNonEmptyString(value) {
14416
14695
  return typeof value === "string" && value.trim().length > 0;
14417
14696
  }
14418
14697
  function isProblemDetailsLike(body) {
14419
- if (!isPlainObject3(body)) {
14698
+ if (!isPlainObject4(body)) {
14420
14699
  return false;
14421
14700
  }
14422
14701
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -14437,11 +14716,11 @@ function isProblemDetailsLike(body) {
14437
14716
  return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
14438
14717
  }
14439
14718
  function isGraphQLErrorEnvelopeLike(body) {
14440
- if (!isPlainObject3(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
14719
+ if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
14441
14720
  return false;
14442
14721
  }
14443
14722
  return body.errors.every((error3) => {
14444
- if (!isPlainObject3(error3) || typeof error3.message !== "string") {
14723
+ if (!isPlainObject4(error3) || typeof error3.message !== "string") {
14445
14724
  return false;
14446
14725
  }
14447
14726
  if ("path" in error3) {
@@ -14451,7 +14730,7 @@ function isGraphQLErrorEnvelopeLike(body) {
14451
14730
  }
14452
14731
  }
14453
14732
  if ("extensions" in error3) {
14454
- if (!isPlainObject3(error3.extensions)) {
14733
+ if (!isPlainObject4(error3.extensions)) {
14455
14734
  return false;
14456
14735
  }
14457
14736
  if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
@@ -14499,23 +14778,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
14499
14778
  }).join("\n\n");
14500
14779
  }
14501
14780
  function formatHttpErrorBody(body) {
14502
- if (typeof body === "string") {
14503
- return body;
14781
+ const redactedBody = redactHttpBody(body);
14782
+ if (typeof redactedBody === "string") {
14783
+ return redactedBody;
14504
14784
  }
14505
- if (isProblemDetailsLike(body)) {
14506
- return formatProblemDetailsBody(body);
14785
+ if (isProblemDetailsLike(redactedBody)) {
14786
+ return formatProblemDetailsBody(redactedBody);
14507
14787
  }
14508
- if (isGraphQLErrorEnvelopeLike(body)) {
14509
- return formatGraphQLErrorEnvelopeBody(body);
14788
+ if (isGraphQLErrorEnvelopeLike(redactedBody)) {
14789
+ return formatGraphQLErrorEnvelopeBody(redactedBody);
14510
14790
  }
14511
- const serialized = JSON.stringify(body, null, 2);
14512
- return serialized === void 0 ? String(body) : serialized;
14791
+ const serialized = JSON.stringify(redactedBody, null, 2);
14792
+ return serialized === void 0 ? String(redactedBody) : serialized;
14513
14793
  }
14514
14794
  function indentHttpErrorBlock(value) {
14515
14795
  return value.split("\n").map((line) => ` ${line}`).join("\n");
14516
14796
  }
14517
14797
  function formatHttpHeaderValue(name, value) {
14518
- return name.toLowerCase() === "authorization" ? "Bearer ****" : value;
14798
+ return redactHttpHeaderValue(name, value);
14519
14799
  }
14520
14800
  function formatHttpErrorHeaders(headers) {
14521
14801
  return Object.entries(headers).map(
@@ -14533,7 +14813,11 @@ function renderHttpError(error3, options) {
14533
14813
  if (detailed) {
14534
14814
  lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
14535
14815
  if (error3.request.body !== void 0) {
14536
- lines.push("Request body:", indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)), "");
14816
+ lines.push(
14817
+ "Request body:",
14818
+ indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
14819
+ ""
14820
+ );
14537
14821
  }
14538
14822
  }
14539
14823
  lines.push(
@@ -16622,11 +16906,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
16622
16906
  if (!resolvedId) {
16623
16907
  return { status: "unknown", input };
16624
16908
  }
16625
- const config = registry[resolvedId];
16626
- if (!config) {
16909
+ const config2 = registry[resolvedId];
16910
+ if (!config2) {
16627
16911
  return { status: "unsupported", input, id: resolvedId };
16628
16912
  }
16629
- return { status: "supported", input, id: resolvedId, config: { ...config } };
16913
+ return { status: "supported", input, id: resolvedId, config: { ...config2 } };
16630
16914
  }
16631
16915
  function getAgentConfig(agentId) {
16632
16916
  const support = resolveAgentSupport(agentId);
@@ -17958,14 +18242,14 @@ async function installSkill(agentId, skill, options) {
17958
18242
  throw new UnsupportedAgentError(agentId);
17959
18243
  }
17960
18244
  const scope = options.scope ?? "local";
17961
- const config = support.config;
18245
+ const config2 = support.config;
17962
18246
  if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
17963
18247
  throw new Error(`Invalid skill name: ${skill.name}`);
17964
18248
  }
17965
- const skillDir = scope === "global" ? config.globalSkillDir : toHomeRelative(config.localSkillDir);
18249
+ const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
17966
18250
  const skillFolderPath = `${skillDir}/${skill.name}`;
17967
18251
  const skillFilePath = `${skillFolderPath}/SKILL.md`;
17968
- const displayPath = `${scope === "global" ? config.globalSkillDir : config.localSkillDir}/${skill.name}/SKILL.md`;
18252
+ const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
17969
18253
  const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
17970
18254
  if (await pathExists2(options.fs, absoluteSkillPath)) {
17971
18255
  throw new Error(`Skill already exists: ${displayPath}`);
@@ -18086,17 +18370,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
18086
18370
  return targetPath;
18087
18371
  }
18088
18372
  function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
18089
- const config = getAgentConfig(agent);
18090
- if (!config) {
18373
+ const config2 = getAgentConfig(agent);
18374
+ if (!config2) {
18091
18375
  throwUnsupportedAgent(agent);
18092
18376
  }
18093
18377
  return {
18094
18378
  displayPath: path22.join(
18095
- scope === "global" ? config.globalSkillDir : config.localSkillDir,
18379
+ scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
18096
18380
  TERMINAL_PILOT_SKILL_NAME
18097
18381
  ),
18098
18382
  fullPath: path22.join(
18099
- scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) : path22.resolve(cwd, config.localSkillDir),
18383
+ scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
18100
18384
  TERMINAL_PILOT_SKILL_NAME
18101
18385
  )
18102
18386
  };
@@ -19413,6 +19697,7 @@ function createTerminalPilotGroup() {
19413
19697
  var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
19414
19698
 
19415
19699
  // src/cli.ts
19700
+ configureTheme({ brand: "green", label: "Terminal Pilot" });
19416
19701
  function normalizeArgv(argv) {
19417
19702
  if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
19418
19703
  return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
@@ -19436,8 +19721,8 @@ async function isDirectExecution(argv) {
19436
19721
  try {
19437
19722
  const modulePath = fileURLToPath5(import.meta.url);
19438
19723
  const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
19439
- realpath2(path23.resolve(entryPoint)),
19440
- realpath2(modulePath)
19724
+ realpath3(path23.resolve(entryPoint)),
19725
+ realpath3(modulePath)
19441
19726
  ]);
19442
19727
  return resolvedEntryPoint === resolvedModulePath;
19443
19728
  } catch {