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.
@@ -85,7 +85,7 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
85
85
  }
86
86
 
87
87
  // src/cli.ts
88
- import { realpath as realpath2 } from "node:fs/promises";
88
+ import { realpath as realpath3 } from "node:fs/promises";
89
89
  import path23 from "node:path";
90
90
  import { fileURLToPath as fileURLToPath5 } from "node:url";
91
91
 
@@ -99,7 +99,7 @@ import {
99
99
  Option
100
100
  } from "commander";
101
101
 
102
- // ../design-system/src/internal/color-support.ts
102
+ // ../toolcraft-design/src/internal/color-support.ts
103
103
  function supportsColor(env = process.env, stream = process.stdout) {
104
104
  if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
105
105
  return true;
@@ -113,7 +113,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
113
113
  return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
114
114
  }
115
115
 
116
- // ../design-system/src/components/color.ts
116
+ // ../toolcraft-design/src/components/color.ts
117
117
  var reset = "\x1B[0m";
118
118
  var ansiStyles = {
119
119
  reset: { open: reset },
@@ -215,41 +215,135 @@ function createColor(styles = []) {
215
215
  }
216
216
  var color = createColor();
217
217
 
218
- // ../design-system/src/tokens/colors.ts
219
- var dark = {
220
- header: (text5) => color.magentaBright.bold(text5),
221
- divider: (text5) => color.dim(text5),
222
- prompt: (text5) => color.cyan(text5),
223
- number: (text5) => color.cyanBright(text5),
224
- intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
225
- resolvedSymbol: color.magenta("\u25C7"),
226
- errorSymbol: color.red("\u25A0"),
227
- accent: (text5) => color.cyan(text5),
228
- muted: (text5) => color.dim(text5),
229
- success: (text5) => color.green(text5),
230
- warning: (text5) => color.yellow(text5),
231
- error: (text5) => color.red(text5),
232
- info: (text5) => color.magenta(text5),
233
- badge: (text5) => color.bgYellow.black(` ${text5} `)
218
+ // ../toolcraft-design/src/tokens/brand.ts
219
+ var brands = {
220
+ purple: { name: "purple", primary: "#a200ff" },
221
+ blue: { name: "blue", primary: "#2f6fed" },
222
+ green: { name: "green", primary: "#1f9d57" }
234
223
  };
235
- var light = {
236
- header: (text5) => color.hex("#a200ff").bold(text5),
237
- divider: (text5) => color.hex("#666666")(text5),
238
- prompt: (text5) => color.hex("#006699").bold(text5),
239
- number: (text5) => color.hex("#0077cc").bold(text5),
240
- intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
241
- resolvedSymbol: color.hex("#a200ff")("\u25C7"),
242
- errorSymbol: color.hex("#cc0000")("\u25A0"),
243
- accent: (text5) => color.hex("#006699").bold(text5),
244
- muted: (text5) => color.hex("#666666")(text5),
245
- success: (text5) => color.hex("#008800")(text5),
246
- warning: (text5) => color.hex("#cc6600")(text5),
247
- error: (text5) => color.hex("#cc0000")(text5),
248
- info: (text5) => color.hex("#a200ff")(text5),
249
- badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
224
+
225
+ // ../toolcraft-design/src/internal/theme-state.ts
226
+ var defaults = {
227
+ brand: "purple",
228
+ label: "Poe"
250
229
  };
230
+ var config = { ...defaults };
231
+ var revision = 0;
232
+ var brandConfigured = false;
233
+ function configureTheme(patch) {
234
+ if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
235
+ throw new Error(`Unknown brand: ${patch.brand}`);
236
+ }
237
+ config = {
238
+ brand: patch.brand ?? config.brand,
239
+ label: patch.label ?? config.label
240
+ };
241
+ if (patch.brand !== void 0) {
242
+ brandConfigured = true;
243
+ }
244
+ revision += 1;
245
+ }
246
+ function getThemeConfig() {
247
+ return { ...config };
248
+ }
249
+ function getThemeRevision() {
250
+ return revision;
251
+ }
252
+ function isThemeBrandConfigured() {
253
+ return brandConfigured;
254
+ }
251
255
 
252
- // ../design-system/src/tokens/typography.ts
256
+ // ../toolcraft-design/src/tokens/colors.ts
257
+ var brand = brands.purple.primary;
258
+ function withStyles(palette, styles) {
259
+ return Object.defineProperty(palette, "styles", {
260
+ value: styles,
261
+ enumerable: false
262
+ });
263
+ }
264
+ function brandColor(activeBrand, purple) {
265
+ return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
266
+ }
267
+ function brandBackground(activeBrand, purple) {
268
+ return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
269
+ }
270
+ function createPalette(activeBrand, mode) {
271
+ const isPurple = activeBrand.name === "purple";
272
+ if (mode === "light") {
273
+ const active2 = color.hex(activeBrand.primary);
274
+ const prompt2 = isPurple ? color.hex("#006699") : active2;
275
+ const number2 = isPurple ? color.hex("#0077cc") : active2;
276
+ return withStyles(
277
+ {
278
+ header: (text5) => active2.bold(text5),
279
+ divider: (text5) => color.hex("#666666")(text5),
280
+ prompt: (text5) => prompt2.bold(text5),
281
+ number: (text5) => number2.bold(text5),
282
+ intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
283
+ get resolvedSymbol() {
284
+ return active2("\u25C7");
285
+ },
286
+ get errorSymbol() {
287
+ return color.hex("#cc0000")("\u25A0");
288
+ },
289
+ accent: (text5) => prompt2.bold(text5),
290
+ muted: (text5) => color.hex("#666666")(text5),
291
+ success: (text5) => color.hex("#008800")(text5),
292
+ warning: (text5) => color.hex("#cc6600")(text5),
293
+ error: (text5) => color.hex("#cc0000")(text5),
294
+ info: (text5) => active2(text5),
295
+ badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
296
+ },
297
+ {
298
+ accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
299
+ muted: { fg: "#666666" },
300
+ success: { fg: "#008800" },
301
+ warning: { fg: "#cc6600" },
302
+ error: { fg: "#cc0000" },
303
+ info: { fg: activeBrand.primary }
304
+ }
305
+ );
306
+ }
307
+ const active = brandColor(activeBrand, color.magenta);
308
+ const activeBright = brandColor(activeBrand, color.magentaBright);
309
+ const activeBackground = brandBackground(activeBrand, color.bgMagenta);
310
+ const prompt = isPurple ? color.cyan : active;
311
+ const number = isPurple ? color.cyanBright : active;
312
+ return withStyles(
313
+ {
314
+ header: (text5) => activeBright.bold(text5),
315
+ divider: (text5) => color.dim(text5),
316
+ prompt: (text5) => prompt(text5),
317
+ number: (text5) => number(text5),
318
+ intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
319
+ get resolvedSymbol() {
320
+ return active("\u25C7");
321
+ },
322
+ get errorSymbol() {
323
+ return color.red("\u25A0");
324
+ },
325
+ accent: (text5) => prompt(text5),
326
+ muted: (text5) => color.dim(text5),
327
+ success: (text5) => color.green(text5),
328
+ warning: (text5) => color.yellow(text5),
329
+ error: (text5) => color.red(text5),
330
+ info: (text5) => active(text5),
331
+ badge: (text5) => color.bgYellow.black(` ${text5} `)
332
+ },
333
+ {
334
+ accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
335
+ muted: { dim: true },
336
+ success: { fg: "green" },
337
+ warning: { fg: "yellow" },
338
+ error: { fg: "red" },
339
+ info: { fg: isPurple ? "magenta" : activeBrand.primary }
340
+ }
341
+ );
342
+ }
343
+ var dark = createPalette(brands.purple, "dark");
344
+ var light = createPalette(brands.purple, "light");
345
+
346
+ // ../toolcraft-design/src/tokens/typography.ts
253
347
  var typography = {
254
348
  bold: (text5) => color.bold(text5),
255
349
  dim: (text5) => color.dim(text5),
@@ -258,14 +352,14 @@ var typography = {
258
352
  strikethrough: (text5) => color.strikethrough(text5)
259
353
  };
260
354
 
261
- // ../design-system/src/tokens/widths.ts
355
+ // ../toolcraft-design/src/tokens/widths.ts
262
356
  var widths = {
263
357
  header: 60,
264
358
  helpColumn: 24,
265
359
  maxLine: 80
266
360
  };
267
361
 
268
- // ../design-system/src/internal/output-format.ts
362
+ // ../toolcraft-design/src/internal/output-format.ts
269
363
  import { AsyncLocalStorage } from "node:async_hooks";
270
364
  var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
271
365
  var formatStorage = new AsyncLocalStorage();
@@ -286,7 +380,7 @@ function resetOutputFormatCache() {
286
380
  cached = void 0;
287
381
  }
288
382
 
289
- // ../design-system/src/internal/theme-detect.ts
383
+ // ../toolcraft-design/src/internal/theme-detect.ts
290
384
  function detectThemeFromEnv(env) {
291
385
  const apple = env.APPLE_INTERFACE_STYLE;
292
386
  if (typeof apple === "string") {
@@ -323,17 +417,30 @@ function resolveThemeName(env = process.env) {
323
417
  }
324
418
  return "dark";
325
419
  }
326
- var cachedTheme;
420
+ var themeCache = /* @__PURE__ */ new Map();
421
+ var cachedRevision = -1;
327
422
  function getTheme(env) {
423
+ const themeName = resolveThemeName(env);
424
+ const config2 = getThemeConfig();
425
+ const requestedBrand = env?.POE_BRAND?.toLowerCase();
426
+ const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
427
+ const revision2 = getThemeRevision();
428
+ if (revision2 !== cachedRevision) {
429
+ themeCache.clear();
430
+ cachedRevision = revision2;
431
+ }
432
+ const cacheKey = `${activeBrandName}:${themeName}`;
433
+ const cachedTheme = themeCache.get(cacheKey);
328
434
  if (cachedTheme) {
329
435
  return cachedTheme;
330
436
  }
331
- const themeName = resolveThemeName(env);
332
- cachedTheme = themeName === "light" ? light : dark;
333
- return cachedTheme;
437
+ const activeBrand = brands[activeBrandName];
438
+ const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
439
+ themeCache.set(cacheKey, theme);
440
+ return theme;
334
441
  }
335
442
 
336
- // ../design-system/src/components/text.ts
443
+ // ../toolcraft-design/src/components/text.ts
337
444
  function renderMarkdownInline(content) {
338
445
  return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
339
446
  }
@@ -449,7 +556,7 @@ var text = {
449
556
  }
450
557
  };
451
558
 
452
- // ../design-system/src/components/symbols.ts
559
+ // ../toolcraft-design/src/components/symbols.ts
453
560
  var symbols = {
454
561
  get info() {
455
562
  const format = resolveOutputFormat();
@@ -503,12 +610,12 @@ var symbols = {
503
610
  }
504
611
  };
505
612
 
506
- // ../design-system/src/internal/strip-ansi.ts
613
+ // ../toolcraft-design/src/internal/strip-ansi.ts
507
614
  function stripAnsi2(value) {
508
615
  return value.replace(/\u001b\[[0-9;]*m/g, "");
509
616
  }
510
617
 
511
- // ../design-system/src/prompts/primitives/log.ts
618
+ // ../toolcraft-design/src/prompts/primitives/log.ts
512
619
  function renderMarkdownInline2(value) {
513
620
  return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
514
621
  }
@@ -635,7 +742,7 @@ var log = {
635
742
  error
636
743
  };
637
744
 
638
- // ../design-system/src/components/logger.ts
745
+ // ../toolcraft-design/src/components/logger.ts
639
746
  function createLogger(emitter) {
640
747
  const emit = (level, message2) => {
641
748
  if (emitter) {
@@ -696,7 +803,7 @@ function createLogger(emitter) {
696
803
  }
697
804
  var logger = createLogger();
698
805
 
699
- // ../design-system/src/components/help-formatter.ts
806
+ // ../toolcraft-design/src/components/help-formatter.ts
700
807
  var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
701
808
  function normalizeInline(value) {
702
809
  return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
@@ -872,7 +979,7 @@ function formatOptionList(options) {
872
979
  });
873
980
  }
874
981
 
875
- // ../design-system/src/components/help-formatter-plain.ts
982
+ // ../toolcraft-design/src/components/help-formatter-plain.ts
876
983
  var help_formatter_plain_exports = {};
877
984
  __export(help_formatter_plain_exports, {
878
985
  formatColumns: () => formatColumns2,
@@ -1009,7 +1116,7 @@ function formatOptionList2(options) {
1009
1116
  });
1010
1117
  }
1011
1118
 
1012
- // ../design-system/src/components/table.ts
1119
+ // ../toolcraft-design/src/components/table.ts
1013
1120
  var reset2 = "\x1B[0m";
1014
1121
  var ellipsis = "\u2026";
1015
1122
  var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -1293,7 +1400,7 @@ function renderTable(options) {
1293
1400
  }
1294
1401
  }
1295
1402
 
1296
- // ../design-system/src/components/detail-card.ts
1403
+ // ../toolcraft-design/src/components/detail-card.ts
1297
1404
  function wrap(value, width) {
1298
1405
  const lines = [];
1299
1406
  for (const paragraph of value.split("\n")) {
@@ -1356,7 +1463,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
1356
1463
  return blocks.join("\n\n");
1357
1464
  }
1358
1465
 
1359
- // ../design-system/src/components/template.ts
1466
+ // ../toolcraft-design/src/components/template.ts
1360
1467
  var MAX_PARTIAL_DEPTH = 100;
1361
1468
  var HTML_ESCAPE = {
1362
1469
  "&": "&",
@@ -1768,22 +1875,22 @@ function hasProperty(value, key2) {
1768
1875
  return Object.prototype.hasOwnProperty.call(value, key2);
1769
1876
  }
1770
1877
 
1771
- // ../design-system/src/components/browser.ts
1878
+ // ../toolcraft-design/src/components/browser.ts
1772
1879
  import { spawn } from "node:child_process";
1773
1880
  import process2 from "node:process";
1774
1881
 
1775
- // ../design-system/src/acp/writer.ts
1882
+ // ../toolcraft-design/src/acp/writer.ts
1776
1883
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
1777
1884
  var storage = new AsyncLocalStorage2();
1778
1885
 
1779
- // ../design-system/src/dashboard/terminal-width.ts
1886
+ // ../toolcraft-design/src/dashboard/terminal-width.ts
1780
1887
  var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1781
1888
 
1782
- // ../design-system/src/dashboard/terminal.ts
1889
+ // ../toolcraft-design/src/dashboard/terminal.ts
1783
1890
  import readline from "node:readline";
1784
1891
  import { PassThrough } from "node:stream";
1785
1892
 
1786
- // ../design-system/src/explorer/state.ts
1893
+ // ../toolcraft-design/src/explorer/state.ts
1787
1894
  var REGION_HEADER = 1 << 0;
1788
1895
  var REGION_LIST = 1 << 1;
1789
1896
  var REGION_DETAIL = 1 << 2;
@@ -1792,10 +1899,10 @@ var REGION_MODAL = 1 << 4;
1792
1899
  var REGION_TOAST = 1 << 5;
1793
1900
  var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
1794
1901
 
1795
- // ../design-system/src/prompts/index.ts
1902
+ // ../toolcraft-design/src/prompts/index.ts
1796
1903
  import * as clack from "@clack/prompts";
1797
1904
 
1798
- // ../design-system/src/prompts/primitives/cancel.ts
1905
+ // ../toolcraft-design/src/prompts/primitives/cancel.ts
1799
1906
  import { isCancel } from "@clack/prompts";
1800
1907
  function cancel(msg = "") {
1801
1908
  if (resolveOutputFormat() !== "terminal") {
@@ -1806,7 +1913,7 @@ function cancel(msg = "") {
1806
1913
  `);
1807
1914
  }
1808
1915
 
1809
- // ../design-system/src/prompts/primitives/note.ts
1916
+ // ../toolcraft-design/src/prompts/primitives/note.ts
1810
1917
  function getVisibleWidth(value) {
1811
1918
  return stripAnsi2(value).length;
1812
1919
  }
@@ -1855,10 +1962,10 @@ function note(message2, title) {
1855
1962
  `);
1856
1963
  }
1857
1964
 
1858
- // ../design-system/src/static/spinner.ts
1965
+ // ../toolcraft-design/src/static/spinner.ts
1859
1966
  var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
1860
1967
 
1861
- // ../design-system/src/prompts/index.ts
1968
+ // ../toolcraft-design/src/prompts/index.ts
1862
1969
  async function select2(opts) {
1863
1970
  return clack.select(opts);
1864
1971
  }
@@ -1901,19 +2008,19 @@ var ApprovalDeclinedError = class extends UserError {
1901
2008
  };
1902
2009
 
1903
2010
  // ../toolcraft/src/human-in-loop/config.ts
1904
- function validateHumanInLoopOnDefine(config) {
1905
- const label = Array.isArray(config.children) ? "group" : "command";
1906
- if (config.confirm === true && config.humanInLoop !== void 0 && config.humanInLoop !== null) {
1907
- throw new Error(`${label} '${config.name}': use either confirm or humanInLoop, not both`);
2011
+ function validateHumanInLoopOnDefine(config2) {
2012
+ const label = Array.isArray(config2.children) ? "group" : "command";
2013
+ if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
2014
+ throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
1908
2015
  }
1909
- if (config.humanInLoop === void 0 || config.humanInLoop === null) {
2016
+ if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
1910
2017
  return;
1911
2018
  }
1912
- if (config.humanInLoop.mode !== "sync" && config.humanInLoop.mode !== "async") {
1913
- throw new Error(`${label} '${config.name}': humanInLoop.mode must be "sync" or "async"`);
2019
+ if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
2020
+ throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
1914
2021
  }
1915
- if (typeof config.humanInLoop.message !== "function") {
1916
- throw new Error(`${label} '${config.name}': humanInLoop.message must be a function`);
2022
+ if (typeof config2.humanInLoop.message !== "function") {
2023
+ throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
1917
2024
  }
1918
2025
  }
1919
2026
  function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
@@ -1989,12 +2096,12 @@ function assertValidBranches(branches, discriminator) {
1989
2096
  }
1990
2097
  }
1991
2098
  }
1992
- function OneOf(config) {
1993
- assertValidBranches(config.branches, config.discriminator);
2099
+ function OneOf(config2) {
2100
+ assertValidBranches(config2.branches, config2.discriminator);
1994
2101
  return {
1995
2102
  kind: "oneOf",
1996
- discriminator: config.discriminator,
1997
- branches: config.branches
2103
+ discriminator: config2.discriminator,
2104
+ branches: config2.branches
1998
2105
  };
1999
2106
  }
2000
2107
 
@@ -2244,22 +2351,22 @@ function cloneStringArray(values) {
2244
2351
  function cloneStringRecord(values) {
2245
2352
  return values === void 0 ? void 0 : { ...values };
2246
2353
  }
2247
- function cloneMcpServerConfig(config) {
2248
- if (config === void 0) {
2354
+ function cloneMcpServerConfig(config2) {
2355
+ if (config2 === void 0) {
2249
2356
  return void 0;
2250
2357
  }
2251
- if (config.transport === "stdio") {
2358
+ if (config2.transport === "stdio") {
2252
2359
  return {
2253
2360
  transport: "stdio",
2254
- command: config.command,
2255
- args: cloneStringArray(config.args),
2256
- env: cloneStringRecord(config.env)
2361
+ command: config2.command,
2362
+ args: cloneStringArray(config2.args),
2363
+ env: cloneStringRecord(config2.env)
2257
2364
  };
2258
2365
  }
2259
2366
  return {
2260
2367
  transport: "http",
2261
- url: config.url,
2262
- headers: cloneStringRecord(config.headers)
2368
+ url: config2.url,
2369
+ headers: cloneStringRecord(config2.headers)
2263
2370
  };
2264
2371
  }
2265
2372
  function cloneRenameMap(rename5) {
@@ -2500,57 +2607,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
2500
2607
  function resolveGroupScope(ownScope, inheritedScope) {
2501
2608
  return cloneScope(ownScope ?? inheritedScope);
2502
2609
  }
2503
- function createBaseCommand(config) {
2610
+ function createBaseCommand(config2) {
2504
2611
  const command = {
2505
2612
  kind: "command",
2506
- name: config.name,
2507
- description: config.description,
2508
- aliases: [...config.aliases ?? []],
2509
- positional: [...config.positional ?? []],
2510
- params: config.params,
2511
- secrets: cloneSecrets(config.secrets),
2512
- scope: resolveCommandScope(config.scope, void 0),
2513
- confirm: config.confirm ?? false,
2514
- humanInLoop: config.humanInLoop,
2515
- requires: cloneRequires(config.requires),
2516
- handler: config.handler,
2517
- render: config.render
2613
+ name: config2.name,
2614
+ description: config2.description,
2615
+ aliases: [...config2.aliases ?? []],
2616
+ positional: [...config2.positional ?? []],
2617
+ params: config2.params,
2618
+ secrets: cloneSecrets(config2.secrets),
2619
+ scope: resolveCommandScope(config2.scope, void 0),
2620
+ confirm: config2.confirm ?? false,
2621
+ humanInLoop: config2.humanInLoop,
2622
+ requires: cloneRequires(config2.requires),
2623
+ handler: config2.handler,
2624
+ render: config2.render
2518
2625
  };
2519
2626
  Object.defineProperty(command, commandConfigSymbol, {
2520
2627
  value: {
2521
- scope: cloneScope(config.scope),
2522
- humanInLoop: config.humanInLoop,
2523
- secrets: cloneSecrets(config.secrets),
2524
- requires: cloneRequires(config.requires),
2628
+ scope: cloneScope(config2.scope),
2629
+ humanInLoop: config2.humanInLoop,
2630
+ secrets: cloneSecrets(config2.secrets),
2631
+ requires: cloneRequires(config2.requires),
2525
2632
  sourcePath: inferCommandSourcePath()
2526
2633
  }
2527
2634
  });
2528
2635
  return command;
2529
2636
  }
2530
- function createBaseGroup(config) {
2637
+ function createBaseGroup(config2) {
2531
2638
  const group = {
2532
2639
  kind: "group",
2533
- name: config.name,
2534
- description: config.description,
2535
- aliases: [...config.aliases ?? []],
2536
- scope: resolveGroupScope(config.scope, void 0),
2537
- humanInLoop: config.humanInLoop,
2538
- secrets: cloneSecrets(config.secrets),
2539
- requires: cloneRequires(config.requires),
2640
+ name: config2.name,
2641
+ description: config2.description,
2642
+ aliases: [...config2.aliases ?? []],
2643
+ scope: resolveGroupScope(config2.scope, void 0),
2644
+ humanInLoop: config2.humanInLoop,
2645
+ secrets: cloneSecrets(config2.secrets),
2646
+ requires: cloneRequires(config2.requires),
2540
2647
  children: [],
2541
2648
  default: void 0
2542
2649
  };
2543
2650
  Object.defineProperty(group, groupConfigSymbol, {
2544
2651
  value: {
2545
- mcp: cloneMcpServerConfig(config.mcp),
2546
- scope: cloneScope(config.scope),
2547
- humanInLoop: config.humanInLoop,
2548
- secrets: cloneSecrets(config.secrets),
2549
- tools: cloneStringArray(config.tools),
2550
- rename: cloneRenameMap(config.rename),
2551
- requires: cloneRequires(config.requires),
2552
- children: [...config.children],
2553
- default: config.default
2652
+ mcp: cloneMcpServerConfig(config2.mcp),
2653
+ scope: cloneScope(config2.scope),
2654
+ humanInLoop: config2.humanInLoop,
2655
+ secrets: cloneSecrets(config2.secrets),
2656
+ tools: cloneStringArray(config2.tools),
2657
+ rename: cloneRenameMap(config2.rename),
2658
+ requires: cloneRequires(config2.requires),
2659
+ children: [...config2.children],
2660
+ default: config2.default
2554
2661
  }
2555
2662
  });
2556
2663
  return group;
@@ -2653,10 +2760,10 @@ function materializeNode(node, inherited) {
2653
2760
  }
2654
2761
  return materializeGroup(node, inherited);
2655
2762
  }
2656
- function defineCommand(config) {
2657
- validateHumanInLoopOnDefine(config);
2763
+ function defineCommand(config2) {
2764
+ validateHumanInLoopOnDefine(config2);
2658
2765
  return materializeCommand(
2659
- createBaseCommand(config),
2766
+ createBaseCommand(config2),
2660
2767
  {
2661
2768
  scope: void 0,
2662
2769
  humanInLoop: void 0,
@@ -2665,10 +2772,10 @@ function defineCommand(config) {
2665
2772
  }
2666
2773
  );
2667
2774
  }
2668
- function defineGroup(config) {
2669
- validateRenameMap(config.rename);
2670
- validateHumanInLoopOnDefine(config);
2671
- return materializeGroup(createBaseGroup(config), {
2775
+ function defineGroup(config2) {
2776
+ validateRenameMap(config2.rename);
2777
+ validateHumanInLoopOnDefine(config2);
2778
+ return materializeGroup(createBaseGroup(config2), {
2672
2779
  scope: void 0,
2673
2780
  humanInLoop: void 0,
2674
2781
  secrets: {},
@@ -2837,7 +2944,7 @@ import path3 from "node:path";
2837
2944
  // ../process-runner/src/docker/docker-execution-env.ts
2838
2945
  import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
2839
2946
  import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
2840
- import { readdir, readFile, writeFile } from "node:fs/promises";
2947
+ import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
2841
2948
  import { tmpdir as tmpdir2 } from "node:os";
2842
2949
  import path5 from "node:path";
2843
2950
 
@@ -4525,7 +4632,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
4525
4632
  }
4526
4633
  return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
4527
4634
  }
4528
- function createdFrontmatter(defaults, input, initialState, mode) {
4635
+ function createdFrontmatter(defaults2, input, initialState, mode) {
4529
4636
  const frontmatter = mode !== "passthrough" ? {
4530
4637
  $schema: TASK_SCHEMA_ID,
4531
4638
  kind: TASK_KIND,
@@ -4537,7 +4644,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
4537
4644
  state: initialState
4538
4645
  };
4539
4646
  const reservedKeys = reservedFrontmatterKeys(mode);
4540
- for (const [key2, value] of Object.entries(defaults.metadata)) {
4647
+ for (const [key2, value] of Object.entries(defaults2.metadata)) {
4541
4648
  if (!reservedKeys.has(key2)) {
4542
4649
  setOwnValue(frontmatter, key2, value);
4543
4650
  }
@@ -5283,13 +5390,13 @@ function matchesFilter(task, filter) {
5283
5390
  }
5284
5391
  return true;
5285
5392
  }
5286
- function createTaskRecord(defaults, input, initialState) {
5393
+ function createTaskRecord(defaults2, input, initialState) {
5287
5394
  const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
5288
5395
  name: input.name,
5289
5396
  state: initialState,
5290
5397
  description: input.description ?? ""
5291
5398
  });
5292
- for (const [key2, value] of Object.entries(defaults.metadata)) {
5399
+ for (const [key2, value] of Object.entries(defaults2.metadata)) {
5293
5400
  if (!RESERVED_TASK_KEYS.has(key2)) {
5294
5401
  taskRecord[key2] = value;
5295
5402
  }
@@ -6663,7 +6770,7 @@ function isMissingStateError(error3) {
6663
6770
  }
6664
6771
 
6665
6772
  // ../toolcraft/src/error-report.ts
6666
- import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
6773
+ import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
6667
6774
  import { randomUUID as randomUUID3 } from "node:crypto";
6668
6775
  import os from "node:os";
6669
6776
  import path13 from "node:path";
@@ -7182,19 +7289,24 @@ function createAuthStoreClientStore(options) {
7182
7289
  }
7183
7290
  };
7184
7291
  }
7185
- function createNamedSecretStore(key2, options, defaults) {
7292
+ function createNamedSecretStore(key2, options, defaults2) {
7186
7293
  const hash = crypto.createHash("sha256").update(key2).digest("hex");
7187
- const parsedFilePath = options.fileStore?.filePath === void 0 ? null : path11.parse(options.fileStore.filePath);
7294
+ const configuredFilePath = options.fileStore?.filePath;
7295
+ const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
7188
7296
  const fileStore = {
7189
7297
  ...options.fileStore,
7190
- salt: options.fileStore?.salt ?? defaults.salt,
7191
- defaultDirectory: parsedFilePath?.dir || options.fileStore?.defaultDirectory || defaults.directory,
7298
+ filePath: parsedFilePath === null ? void 0 : path11.join(
7299
+ parsedFilePath.dir,
7300
+ `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
7301
+ ),
7302
+ salt: options.fileStore?.salt ?? defaults2.salt,
7303
+ defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
7192
7304
  defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
7193
7305
  };
7194
7306
  const keychainStore = {
7195
7307
  ...options.keychainStore,
7196
- service: options.keychainStore?.service ?? defaults.service,
7197
- account: `${options.keychainStore?.account ?? defaults.accountPrefix}:${hash}`
7308
+ service: options.keychainStore?.service ?? defaults2.service,
7309
+ account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
7198
7310
  };
7199
7311
  return createSecretStore({ ...options, fileStore, keychainStore }).store;
7200
7312
  }
@@ -8794,6 +8906,9 @@ var McpClient = class {
8794
8906
  const abortPromise = new Promise((_, reject) => {
8795
8907
  const rejectWithAbortReason = () => {
8796
8908
  sendCancellationNotification();
8909
+ if (requestId !== void 0) {
8910
+ messageLayer.cancelRequest(requestId, signal.reason);
8911
+ }
8797
8912
  reject(signal.reason);
8798
8913
  };
8799
8914
  abortListener = rejectWithAbortReason;
@@ -8968,11 +9083,13 @@ var StdioTransport = class _StdioTransport {
8968
9083
  const child = this.child;
8969
9084
  this.readable = child.stdout;
8970
9085
  this.writable = child.stdin;
9086
+ const stderrDecoder = new TextDecoder();
8971
9087
  child.stderr.on("data", (chunk) => {
8972
- this.stderrOutput += chunkToString(chunk);
8973
- if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
8974
- this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
8975
- }
9088
+ const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
9089
+ this.appendStderrOutput(decoded);
9090
+ });
9091
+ child.stderr.once("end", () => {
9092
+ this.appendStderrOutput(stderrDecoder.decode());
8976
9093
  });
8977
9094
  this.closed = new Promise((resolve) => {
8978
9095
  let settled = false;
@@ -9012,6 +9129,15 @@ var StdioTransport = class _StdioTransport {
9012
9129
  getStderrOutput() {
9013
9130
  return this.stderrOutput;
9014
9131
  }
9132
+ appendStderrOutput(chunk) {
9133
+ if (chunk.length === 0) {
9134
+ return;
9135
+ }
9136
+ this.stderrOutput += chunk;
9137
+ if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
9138
+ this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
9139
+ }
9140
+ }
9015
9141
  dispose(reason = new Error("Stdio transport disposed")) {
9016
9142
  void reason;
9017
9143
  if (this.disposed) {
@@ -9419,15 +9545,6 @@ function serializeJsonRpcMessage(message2) {
9419
9545
  return `${JSON.stringify(message2)}
9420
9546
  `;
9421
9547
  }
9422
- function chunkToString(chunk) {
9423
- if (typeof chunk === "string") {
9424
- return chunk;
9425
- }
9426
- if (chunk instanceof Uint8Array) {
9427
- return Buffer.from(chunk).toString("utf8");
9428
- }
9429
- return String(chunk);
9430
- }
9431
9548
  function normalizeLine(line) {
9432
9549
  return line.endsWith("\r") ? line.slice(0, -1) : line;
9433
9550
  }
@@ -9617,6 +9734,16 @@ var JsonRpcMessageLayer = class {
9617
9734
  }
9618
9735
  });
9619
9736
  }
9737
+ cancelRequest(requestId, reason) {
9738
+ const pending = this.pendingRequests.get(requestId);
9739
+ if (pending === void 0) {
9740
+ return false;
9741
+ }
9742
+ this.pendingRequests.delete(requestId);
9743
+ clearTimeout(pending.timeout);
9744
+ pending.reject(reason);
9745
+ return true;
9746
+ }
9620
9747
  dispose(reason = new Error("JSON-RPC message layer disposed")) {
9621
9748
  if (this.disposedError !== void 0) {
9622
9749
  return;
@@ -10685,10 +10812,10 @@ function validateRenameMap2(name, tools, rename5) {
10685
10812
  }
10686
10813
  }
10687
10814
  }
10688
- function createConnection(name, config) {
10815
+ function createConnection(name, config2) {
10689
10816
  const connection = {
10690
10817
  name,
10691
- config,
10818
+ config: config2,
10692
10819
  async dispose() {
10693
10820
  shutdownDisposers.delete(connection.dispose);
10694
10821
  connection.connecting = void 0;
@@ -10755,13 +10882,13 @@ async function writeCache(cachePath, cache) {
10755
10882
  await assertCachePathHasNoSymlinks(cachePath);
10756
10883
  await rename2(tempPath, cachePath);
10757
10884
  }
10758
- async function fetchCache(name, config) {
10885
+ async function fetchCache(name, config2) {
10759
10886
  const logger2 = createLogger((message2) => {
10760
10887
  process.stderr.write(`${message2}
10761
10888
  `);
10762
10889
  });
10763
10890
  logger2.info(`MCP ${name}: connecting`);
10764
- const client = await dialUpstream(name, config);
10891
+ const client = await dialUpstream(name, config2);
10765
10892
  try {
10766
10893
  logger2.info(`MCP ${name}: listing tools`);
10767
10894
  const tools = [];
@@ -10780,7 +10907,7 @@ async function fetchCache(name, config) {
10780
10907
  $schema: MCP_PROXY_SCHEMA_URL,
10781
10908
  version: 1,
10782
10909
  upstream,
10783
- configFingerprint: fingerprintMcpServerConfig(config),
10910
+ configFingerprint: fingerprintMcpServerConfig(config2),
10784
10911
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
10785
10912
  tools
10786
10913
  };
@@ -10850,8 +10977,8 @@ function isRefreshRequested(name, refresh) {
10850
10977
  }
10851
10978
  async function resolveSingleProxy(group, options) {
10852
10979
  const internal = getInternalGroupConfig2(group);
10853
- const config = internal.mcp;
10854
- if (config === void 0) {
10980
+ const config2 = internal.mcp;
10981
+ if (config2 === void 0) {
10855
10982
  return;
10856
10983
  }
10857
10984
  const name = group.name;
@@ -10861,21 +10988,21 @@ async function resolveSingleProxy(group, options) {
10861
10988
  let cache;
10862
10989
  let shouldWriteCache = false;
10863
10990
  if (isRefreshRequested(name, refresh)) {
10864
- cache = await fetchCache(name, config);
10991
+ cache = await fetchCache(name, config2);
10865
10992
  shouldWriteCache = true;
10866
10993
  } else {
10867
10994
  const storedCache = await readCache(cachePath);
10868
- if (storedCache && cacheMatchesConfig(storedCache, config)) {
10995
+ if (storedCache && cacheMatchesConfig(storedCache, config2)) {
10869
10996
  cache = storedCache;
10870
10997
  } else {
10871
- cache = await fetchCache(name, config);
10998
+ cache = await fetchCache(name, config2);
10872
10999
  shouldWriteCache = true;
10873
11000
  }
10874
11001
  }
10875
11002
  const tools = filterAllowlistedTools(cache.tools, internal.tools);
10876
11003
  validateRenameMap2(name, tools, internal.rename);
10877
11004
  const previousConnection = getProxyConnection(group);
10878
- const nextConnection = createConnection(name, config);
11005
+ const nextConnection = createConnection(name, config2);
10879
11006
  try {
10880
11007
  replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
10881
11008
  if (shouldWriteCache) {
@@ -10900,11 +11027,11 @@ async function resolveSingleProxy(group, options) {
10900
11027
  );
10901
11028
  }
10902
11029
  }
10903
- function cacheMatchesConfig(cache, config) {
10904
- return cache.configFingerprint === fingerprintMcpServerConfig(config);
11030
+ function cacheMatchesConfig(cache, config2) {
11031
+ return cache.configFingerprint === fingerprintMcpServerConfig(config2);
10905
11032
  }
10906
- function fingerprintMcpServerConfig(config) {
10907
- return createHash3("sha256").update(JSON.stringify(config)).digest("hex");
11033
+ function fingerprintMcpServerConfig(config2) {
11034
+ return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
10908
11035
  }
10909
11036
  function collectProxyGroups(root) {
10910
11037
  const groups = [];
@@ -10982,20 +11109,20 @@ function parseRefreshEnv(value) {
10982
11109
  const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
10983
11110
  return names.length === 0 ? void 0 : new Set(names);
10984
11111
  }
10985
- async function dialUpstream(name, config) {
11112
+ async function dialUpstream(name, config2) {
10986
11113
  const client = new McpClient({
10987
11114
  clientInfo: {
10988
11115
  name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
10989
11116
  version: DEFAULT_CLIENT_INFO.version
10990
11117
  }
10991
11118
  });
10992
- const transport = config.transport === "stdio" ? new StdioTransport({
10993
- command: config.command,
10994
- ...config.args === void 0 ? {} : { args: config.args },
10995
- ...config.env === void 0 ? {} : { env: config.env }
11119
+ const transport = config2.transport === "stdio" ? new StdioTransport({
11120
+ command: config2.command,
11121
+ ...config2.args === void 0 ? {} : { args: config2.args },
11122
+ ...config2.env === void 0 ? {} : { env: config2.env }
10996
11123
  }) : new HttpTransport({
10997
- url: config.url,
10998
- ...config.headers === void 0 ? {} : { headers: config.headers }
11124
+ url: config2.url,
11125
+ ...config2.headers === void 0 ? {} : { headers: config2.headers }
10999
11126
  });
11000
11127
  await client.connect(transport);
11001
11128
  return client;
@@ -11005,10 +11132,82 @@ async function resolveMcpProxies(root, options = {}) {
11005
11132
  await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
11006
11133
  }
11007
11134
 
11135
+ // ../toolcraft/src/redaction.ts
11136
+ var REDACTED_VALUE = "<redacted>";
11137
+ var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
11138
+ var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
11139
+ var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
11140
+ function isPlainObject2(value) {
11141
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11142
+ }
11143
+ function normalizeName(name) {
11144
+ return name.toLowerCase().replace(/[^a-z0-9]/g, "");
11145
+ }
11146
+ function isSensitiveName(name) {
11147
+ const normalized = normalizeName(name);
11148
+ return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
11149
+ }
11150
+ function redactSecretLikeFieldsValue(value, name, seen) {
11151
+ if (name.length > 0 && isSensitiveName(name)) {
11152
+ return REDACTED_VALUE;
11153
+ }
11154
+ if (Array.isArray(value)) {
11155
+ if (seen.has(value)) {
11156
+ return "[Circular]";
11157
+ }
11158
+ seen.add(value);
11159
+ return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
11160
+ }
11161
+ if (isPlainObject2(value)) {
11162
+ if (seen.has(value)) {
11163
+ return "[Circular]";
11164
+ }
11165
+ seen.add(value);
11166
+ return Object.fromEntries(
11167
+ Object.entries(value).map(([key2, entry]) => [
11168
+ key2,
11169
+ redactSecretLikeFieldsValue(entry, key2, seen)
11170
+ ])
11171
+ );
11172
+ }
11173
+ return value;
11174
+ }
11175
+ function redactSecretLikeFields(value, name = "") {
11176
+ return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
11177
+ }
11178
+ function parseJsonObjectOrArray(value) {
11179
+ const trimmed = value.trim();
11180
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
11181
+ return void 0;
11182
+ }
11183
+ try {
11184
+ const parsed = JSON.parse(trimmed);
11185
+ return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
11186
+ } catch {
11187
+ return void 0;
11188
+ }
11189
+ }
11190
+ function redactHttpBody(body) {
11191
+ if (typeof body === "string") {
11192
+ const parsed = parseJsonObjectOrArray(body);
11193
+ return parsed === void 0 ? body : redactSecretLikeFields(parsed);
11194
+ }
11195
+ return redactSecretLikeFields(body);
11196
+ }
11197
+ function redactHttpHeaderValue(name, value) {
11198
+ const normalized = normalizeName(name);
11199
+ if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
11200
+ return "Bearer ****";
11201
+ }
11202
+ if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
11203
+ return REDACTED_VALUE;
11204
+ }
11205
+ return value;
11206
+ }
11207
+
11008
11208
  // ../toolcraft/src/error-report.ts
11009
11209
  var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
11010
- var DEFAULT_SENSITIVE_NAMES = ["password", "token", "apikey", "secret"];
11011
- function isPlainObject2(value) {
11210
+ function isPlainObject3(value) {
11012
11211
  return typeof value === "object" && value !== null && !Array.isArray(value);
11013
11212
  }
11014
11213
  function unwrapOptional(schema) {
@@ -11018,7 +11217,7 @@ function unwrapOptional(schema) {
11018
11217
  return schema;
11019
11218
  }
11020
11219
  function hasHttpContext(error3) {
11021
- return error3 instanceof Error && error3.name === "HttpError" && isPlainObject2(error3.request) && isPlainObject2(error3.response);
11220
+ return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
11022
11221
  }
11023
11222
  function isSkippedError(error3) {
11024
11223
  if (error3 instanceof ApprovalDeclinedError) {
@@ -11055,8 +11254,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
11055
11254
  throw new Error("Error report directory resolves outside project root.");
11056
11255
  }
11057
11256
  const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
11058
- realpath(projectRoot),
11059
- realpath(reportDir)
11257
+ realpath2(projectRoot),
11258
+ realpath2(reportDir)
11060
11259
  ]);
11061
11260
  if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
11062
11261
  throw new Error("Error report directory resolves outside project root.");
@@ -11111,9 +11310,24 @@ function redactValue(value) {
11111
11310
  }
11112
11311
  return `<set, ${value.length} chars>`;
11113
11312
  }
11114
- function isSensitiveName(name) {
11115
- const normalized = name.toLowerCase();
11116
- return DEFAULT_SENSITIVE_NAMES.some((candidate) => normalized.includes(candidate));
11313
+ function collectStringLeaves(value, output) {
11314
+ if (typeof value === "string") {
11315
+ if (value.length > 0) {
11316
+ output.add(value);
11317
+ }
11318
+ return;
11319
+ }
11320
+ if (Array.isArray(value)) {
11321
+ for (const entry of value) {
11322
+ collectStringLeaves(entry, output);
11323
+ }
11324
+ return;
11325
+ }
11326
+ if (isPlainObject3(value)) {
11327
+ for (const entry of Object.values(value)) {
11328
+ collectStringLeaves(entry, output);
11329
+ }
11330
+ }
11117
11331
  }
11118
11332
  function schemaSecretValue(schema) {
11119
11333
  const unwrapped = unwrapOptional(schema);
@@ -11134,7 +11348,7 @@ function redactParamsValue(value, schema, name) {
11134
11348
  return "<redacted>";
11135
11349
  }
11136
11350
  const unwrapped = unwrapOptional(schema);
11137
- if (unwrapped.kind === "object" && isPlainObject2(value)) {
11351
+ if (unwrapped.kind === "object" && isPlainObject3(value)) {
11138
11352
  return Object.fromEntries(
11139
11353
  Object.entries(value).map(([key2, childValue]) => {
11140
11354
  const childSchema = unwrapped.shape[key2];
@@ -11156,6 +11370,52 @@ function redactParams(params17, command) {
11156
11370
  }
11157
11371
  return redactParamsValue(params17, command.params, "");
11158
11372
  }
11373
+ function collectSensitiveParamValues(value, schema, name, output) {
11374
+ if (shouldRedactParam(name, schema)) {
11375
+ collectStringLeaves(value, output);
11376
+ return;
11377
+ }
11378
+ const unwrapped = unwrapOptional(schema);
11379
+ if (unwrapped.kind === "object" && isPlainObject3(value)) {
11380
+ for (const [key2, childValue] of Object.entries(value)) {
11381
+ const childSchema = unwrapped.shape[key2];
11382
+ if (childSchema !== void 0) {
11383
+ collectSensitiveParamValues(childValue, childSchema, key2, output);
11384
+ }
11385
+ }
11386
+ return;
11387
+ }
11388
+ if (unwrapped.kind === "array" && Array.isArray(value)) {
11389
+ for (const entry of value) {
11390
+ collectSensitiveParamValues(entry, unwrapped.item, name, output);
11391
+ }
11392
+ }
11393
+ }
11394
+ function createReportStringRedactor(context, env) {
11395
+ const values = /* @__PURE__ */ new Set();
11396
+ for (const value of Object.values(context.secrets ?? {})) {
11397
+ if (value !== void 0 && value.length > 0) {
11398
+ values.add(value);
11399
+ }
11400
+ }
11401
+ for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
11402
+ const value = context.secrets?.[name] ?? env[secret.env];
11403
+ if (value !== void 0 && value.length > 0) {
11404
+ values.add(value);
11405
+ }
11406
+ }
11407
+ if (context.command !== void 0) {
11408
+ collectSensitiveParamValues(context.params, context.command.params, "", values);
11409
+ }
11410
+ const orderedValues = [...values].sort((left, right) => right.length - left.length);
11411
+ return (value) => {
11412
+ let redacted = value;
11413
+ for (const secretValue of orderedValues) {
11414
+ redacted = redacted.split(secretValue).join("<redacted>");
11415
+ }
11416
+ return redacted;
11417
+ };
11418
+ }
11159
11419
  function commandSecretEnvNames(secrets) {
11160
11420
  if (secrets === void 0) {
11161
11421
  return [];
@@ -11209,28 +11469,42 @@ function redactArgv(argv, options) {
11209
11469
  function stableJson(value) {
11210
11470
  return JSON.stringify(value, null, 2) ?? "undefined";
11211
11471
  }
11212
- function redactStructuredErrorField(name, value) {
11213
- if (typeof value === "string" && name.toLowerCase() === "authorization") {
11214
- return "Bearer ****";
11472
+ function redactStructuredErrorField(name, value, redactString) {
11473
+ if (typeof value === "string") {
11474
+ const redactedHeaderValue = redactHttpHeaderValue(name, value);
11475
+ if (redactedHeaderValue !== value) {
11476
+ return redactedHeaderValue;
11477
+ }
11478
+ if (isSensitiveName(name)) {
11479
+ return "<redacted>";
11480
+ }
11481
+ return redactString(value);
11215
11482
  }
11216
11483
  if (Array.isArray(value)) {
11217
- return value.map((entry) => redactStructuredErrorField(name, entry));
11484
+ return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
11218
11485
  }
11219
- if (isPlainObject2(value)) {
11486
+ if (isPlainObject3(value)) {
11220
11487
  return Object.fromEntries(
11221
- Object.entries(value).map(([key2, entry]) => [key2, redactStructuredErrorField(key2, entry)])
11488
+ Object.entries(value).map(([key2, entry]) => [
11489
+ key2,
11490
+ redactStructuredErrorField(key2, entry, redactString)
11491
+ ])
11222
11492
  );
11223
11493
  }
11224
11494
  return value;
11225
11495
  }
11226
- function ownStructuredFields(error3) {
11496
+ function ownStructuredFields(error3, redactString) {
11227
11497
  const fields = {};
11228
11498
  for (const key2 of Object.keys(error3)) {
11229
11499
  if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
11230
11500
  continue;
11231
11501
  }
11232
11502
  Object.defineProperty(fields, key2, {
11233
- value: redactStructuredErrorField(key2, error3[key2]),
11503
+ value: redactStructuredErrorField(
11504
+ key2,
11505
+ error3[key2],
11506
+ redactString
11507
+ ),
11234
11508
  enumerable: true,
11235
11509
  configurable: true,
11236
11510
  writable: true
@@ -11238,43 +11512,44 @@ function ownStructuredFields(error3) {
11238
11512
  }
11239
11513
  return fields;
11240
11514
  }
11241
- function formatStackChain(error3) {
11515
+ function formatStackChain(error3, redactString) {
11242
11516
  const lines = [];
11243
11517
  let current = error3;
11244
11518
  let index = 0;
11245
11519
  while (current !== void 0) {
11246
11520
  if (current instanceof Error) {
11247
- lines.push(
11248
- index === 0 ? current.stack ?? String(current) : `Caused by: ${current.stack ?? String(current)}`
11249
- );
11521
+ const stack = current.stack ?? String(current);
11522
+ lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
11250
11523
  current = current.cause;
11251
11524
  } else {
11252
- lines.push(index === 0 ? String(current) : `Caused by: ${String(current)}`);
11525
+ const message2 = String(current);
11526
+ lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
11253
11527
  current = void 0;
11254
11528
  }
11255
11529
  index += 1;
11256
11530
  }
11257
11531
  return lines.join("\n");
11258
11532
  }
11259
- function formatHeaderValue(name, value) {
11260
- return name.toLowerCase() === "authorization" ? "Bearer ****" : value;
11533
+ function formatHeaderValue(name, value, redactString) {
11534
+ return redactString(redactHttpHeaderValue(name, value));
11261
11535
  }
11262
- function formatHeaders(headers) {
11263
- return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
11536
+ function formatHeaders(headers, redactString) {
11537
+ return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
11264
11538
  }
11265
- function formatBody(body) {
11266
- if (typeof body === "string") {
11267
- return body;
11539
+ function formatBody(body, redactString) {
11540
+ const redactedBody = redactHttpBody(body);
11541
+ if (typeof redactedBody === "string") {
11542
+ return redactString(redactedBody);
11268
11543
  }
11269
- return stableJson(body);
11544
+ return redactString(stableJson(redactedBody));
11270
11545
  }
11271
- function formatHttpTranscript(error3) {
11546
+ function formatHttpTranscript(error3, redactString) {
11272
11547
  const requestLines = [
11273
11548
  `${error3.request.method} ${error3.request.url}`,
11274
- formatHeaders(error3.request.headers)
11549
+ formatHeaders(error3.request.headers, redactString)
11275
11550
  ].filter((line) => line.length > 0);
11276
11551
  if (error3.request.body !== void 0) {
11277
- requestLines.push("", formatBody(error3.request.body));
11552
+ requestLines.push("", formatBody(error3.request.body, redactString));
11278
11553
  }
11279
11554
  return [
11280
11555
  "Request:",
@@ -11282,9 +11557,9 @@ function formatHttpTranscript(error3) {
11282
11557
  "",
11283
11558
  "Response:",
11284
11559
  `${error3.response.status} ${error3.response.statusText}`,
11285
- formatHeaders(error3.response.headers),
11560
+ formatHeaders(error3.response.headers, redactString),
11286
11561
  "",
11287
- formatBody(error3.response.body)
11562
+ formatBody(error3.response.body, redactString)
11288
11563
  ].join("\n");
11289
11564
  }
11290
11565
  function resolveToolcraftVersion(version) {
@@ -11293,9 +11568,10 @@ function resolveToolcraftVersion(version) {
11293
11568
  function buildReport(context) {
11294
11569
  const env = context.env ?? process.env;
11295
11570
  const error3 = context.error;
11571
+ const redactString = createReportStringRedactor(context, env);
11296
11572
  const errorName = error3 instanceof Error ? error3.name : typeof error3;
11297
- const errorMessage = error3 instanceof Error ? error3.message : String(error3);
11298
- const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
11573
+ const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
11574
+ const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
11299
11575
  const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
11300
11576
  const value = context.secrets?.[name] ?? env[secret.env];
11301
11577
  return `${secret.env}=${redactValue(value)}`;
@@ -11309,7 +11585,9 @@ function buildReport(context) {
11309
11585
  `platform: ${process.platform} ${process.arch}`,
11310
11586
  "",
11311
11587
  "Argv",
11312
- stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets })),
11588
+ redactString(
11589
+ stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
11590
+ ),
11313
11591
  "",
11314
11592
  "Resolved Secrets",
11315
11593
  ...secretLines.length === 0 ? ["<none>"] : secretLines,
@@ -11318,19 +11596,19 @@ function buildReport(context) {
11318
11596
  context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
11319
11597
  "",
11320
11598
  "Parsed Params",
11321
- stableJson(redactParams(context.params, context.command)),
11599
+ redactString(stableJson(redactParams(context.params, context.command))),
11322
11600
  "",
11323
11601
  "Error",
11324
11602
  `name: ${errorName}`,
11325
11603
  `message: ${errorMessage}`,
11326
11604
  "structured fields:",
11327
- stableJson(structuredFields),
11605
+ redactString(stableJson(structuredFields)),
11328
11606
  "",
11329
11607
  "Stack",
11330
- formatStackChain(error3)
11608
+ formatStackChain(error3, redactString)
11331
11609
  ];
11332
11610
  if (hasHttpContext(error3)) {
11333
- lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
11611
+ lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
11334
11612
  }
11335
11613
  return `${lines.join("\n")}
11336
11614
  `;
@@ -11790,6 +12068,7 @@ ${rendered.join("\n")}`);
11790
12068
  }
11791
12069
 
11792
12070
  // ../toolcraft/src/cli.ts
12071
+ configureTheme({ brand: "blue", label: "Toolcraft" });
11793
12072
  var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
11794
12073
  "params",
11795
12074
  "secrets",
@@ -13223,7 +13502,7 @@ function createEnv2(values = process.env) {
13223
13502
  }
13224
13503
  };
13225
13504
  }
13226
- function isPlainObject3(value) {
13505
+ function isPlainObject4(value) {
13227
13506
  return typeof value === "object" && value !== null && !Array.isArray(value);
13228
13507
  }
13229
13508
  function hasFieldValue(value) {
@@ -13332,7 +13611,7 @@ async function loadPresetValues(fields, presetPath) {
13332
13611
  { cause: error3 }
13333
13612
  );
13334
13613
  }
13335
- if (!isPlainObject3(parsedPreset)) {
13614
+ if (!isPlainObject4(parsedPreset)) {
13336
13615
  throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
13337
13616
  }
13338
13617
  const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
@@ -13351,7 +13630,7 @@ async function loadPresetValues(fields, presetPath) {
13351
13630
  `Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
13352
13631
  );
13353
13632
  }
13354
- if (!isPlainObject3(value)) {
13633
+ if (!isPlainObject4(value)) {
13355
13634
  throw new UserError(
13356
13635
  `Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
13357
13636
  );
@@ -13394,8 +13673,8 @@ function matchesFixtureValue(expected, actual) {
13394
13673
  }
13395
13674
  return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
13396
13675
  }
13397
- if (isPlainObject3(expected)) {
13398
- if (!isPlainObject3(actual)) {
13676
+ if (isPlainObject4(expected)) {
13677
+ if (!isPlainObject4(actual)) {
13399
13678
  return false;
13400
13679
  }
13401
13680
  return Object.entries(expected).every(
@@ -13458,9 +13737,9 @@ function createFixtureFetch(entries) {
13458
13737
  };
13459
13738
  }
13460
13739
  function createFixtureFs(definition) {
13461
- const fsDefinition = isPlainObject3(definition) ? definition : {};
13462
- const readFileEntries = isPlainObject3(fsDefinition.readFile) ? fsDefinition.readFile : {};
13463
- const existsEntries = isPlainObject3(fsDefinition.exists) ? fsDefinition.exists : {};
13740
+ const fsDefinition = isPlainObject4(definition) ? definition : {};
13741
+ const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
13742
+ const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
13464
13743
  return {
13465
13744
  readFile: async (filePath) => {
13466
13745
  if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
@@ -13483,10 +13762,10 @@ function createFixtureFs(definition) {
13483
13762
  function resolveFixtureMethodResult(methodName, definition, args) {
13484
13763
  if (Array.isArray(definition)) {
13485
13764
  for (const entry of definition) {
13486
- if (!isPlainObject3(entry)) {
13765
+ if (!isPlainObject4(entry)) {
13487
13766
  continue;
13488
13767
  }
13489
- const explicitMatcher = isPlainObject3(entry.request) ? entry.request : void 0;
13768
+ const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
13490
13769
  const matcher = explicitMatcher ?? Object.fromEntries(
13491
13770
  Object.entries(entry).filter(
13492
13771
  ([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
@@ -13498,7 +13777,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13498
13777
  matched = matchesFixtureValue(matcher.args, args);
13499
13778
  } else if (Object.keys(matcher).length === 0) {
13500
13779
  matched = true;
13501
- } else if (isPlainObject3(firstArg)) {
13780
+ } else if (isPlainObject4(firstArg)) {
13502
13781
  matched = matchesFixtureValue(matcher, firstArg);
13503
13782
  } else if (args.length === 1 && Object.keys(matcher).length === 1) {
13504
13783
  const [[, expectedValue]] = Object.entries(matcher);
@@ -13519,7 +13798,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13519
13798
  return Promise.resolve(null);
13520
13799
  }
13521
13800
  }
13522
- if (isPlainObject3(definition)) {
13801
+ if (isPlainObject4(definition)) {
13523
13802
  const firstArg = args[0];
13524
13803
  if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
13525
13804
  return Promise.resolve(definition[firstArg]);
@@ -13531,7 +13810,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
13531
13810
  return Promise.resolve(null);
13532
13811
  }
13533
13812
  function createFixtureService(definition) {
13534
- const methods = isPlainObject3(definition) ? definition : {};
13813
+ const methods = isPlainObject4(definition) ? definition : {};
13535
13814
  return new Proxy(
13536
13815
  {},
13537
13816
  {
@@ -13629,7 +13908,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
13629
13908
  };
13630
13909
  }
13631
13910
  const scenario = await loadFixtureScenario(command, selector);
13632
- const scenarioServices = isPlainObject3(scenario.services) ? scenario.services : {};
13911
+ const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
13633
13912
  const customServiceNames = /* @__PURE__ */ new Set([
13634
13913
  ...Object.keys(services),
13635
13914
  ...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
@@ -13911,7 +14190,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13911
14190
  if (itemSchema.kind !== "object") {
13912
14191
  return value;
13913
14192
  }
13914
- if (!isPlainObject3(value)) {
14193
+ if (!isPlainObject4(value)) {
13915
14194
  errors2.push({
13916
14195
  path: displayPath,
13917
14196
  message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
@@ -13946,7 +14225,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13946
14225
  );
13947
14226
  }
13948
14227
  case "object": {
13949
- if (!isPlainObject3(value)) {
14228
+ if (!isPlainObject4(value)) {
13950
14229
  errors2.push({
13951
14230
  path: displayPath,
13952
14231
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -13977,7 +14256,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
13977
14256
  return result;
13978
14257
  }
13979
14258
  case "record": {
13980
- if (!isPlainObject3(value)) {
14259
+ if (!isPlainObject4(value)) {
13981
14260
  errors2.push({
13982
14261
  path: displayPath,
13983
14262
  message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
@@ -14403,10 +14682,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
14403
14682
  }
14404
14683
  }
14405
14684
  function isStringRecord(value) {
14406
- return isPlainObject3(value) && Object.values(value).every((entry) => typeof entry === "string");
14685
+ return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
14407
14686
  }
14408
14687
  function isHttpErrorLike(error3) {
14409
- if (!isPlainObject3(error3)) {
14688
+ if (!isPlainObject4(error3)) {
14410
14689
  return false;
14411
14690
  }
14412
14691
  if (error3.name !== "HttpError" || typeof error3.message !== "string") {
@@ -14414,7 +14693,7 @@ function isHttpErrorLike(error3) {
14414
14693
  }
14415
14694
  const request = error3.request;
14416
14695
  const response = error3.response;
14417
- 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;
14696
+ 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;
14418
14697
  }
14419
14698
  function hasTypedOptionalField(value, field, type2) {
14420
14699
  return !(field in value) || typeof value[field] === type2;
@@ -14423,7 +14702,7 @@ function isNonEmptyString(value) {
14423
14702
  return typeof value === "string" && value.trim().length > 0;
14424
14703
  }
14425
14704
  function isProblemDetailsLike(body) {
14426
- if (!isPlainObject3(body)) {
14705
+ if (!isPlainObject4(body)) {
14427
14706
  return false;
14428
14707
  }
14429
14708
  if (!hasTypedOptionalField(body, "type", "string")) {
@@ -14444,11 +14723,11 @@ function isProblemDetailsLike(body) {
14444
14723
  return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
14445
14724
  }
14446
14725
  function isGraphQLErrorEnvelopeLike(body) {
14447
- if (!isPlainObject3(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
14726
+ if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
14448
14727
  return false;
14449
14728
  }
14450
14729
  return body.errors.every((error3) => {
14451
- if (!isPlainObject3(error3) || typeof error3.message !== "string") {
14730
+ if (!isPlainObject4(error3) || typeof error3.message !== "string") {
14452
14731
  return false;
14453
14732
  }
14454
14733
  if ("path" in error3) {
@@ -14458,7 +14737,7 @@ function isGraphQLErrorEnvelopeLike(body) {
14458
14737
  }
14459
14738
  }
14460
14739
  if ("extensions" in error3) {
14461
- if (!isPlainObject3(error3.extensions)) {
14740
+ if (!isPlainObject4(error3.extensions)) {
14462
14741
  return false;
14463
14742
  }
14464
14743
  if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
@@ -14506,23 +14785,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
14506
14785
  }).join("\n\n");
14507
14786
  }
14508
14787
  function formatHttpErrorBody(body) {
14509
- if (typeof body === "string") {
14510
- return body;
14788
+ const redactedBody = redactHttpBody(body);
14789
+ if (typeof redactedBody === "string") {
14790
+ return redactedBody;
14511
14791
  }
14512
- if (isProblemDetailsLike(body)) {
14513
- return formatProblemDetailsBody(body);
14792
+ if (isProblemDetailsLike(redactedBody)) {
14793
+ return formatProblemDetailsBody(redactedBody);
14514
14794
  }
14515
- if (isGraphQLErrorEnvelopeLike(body)) {
14516
- return formatGraphQLErrorEnvelopeBody(body);
14795
+ if (isGraphQLErrorEnvelopeLike(redactedBody)) {
14796
+ return formatGraphQLErrorEnvelopeBody(redactedBody);
14517
14797
  }
14518
- const serialized = JSON.stringify(body, null, 2);
14519
- return serialized === void 0 ? String(body) : serialized;
14798
+ const serialized = JSON.stringify(redactedBody, null, 2);
14799
+ return serialized === void 0 ? String(redactedBody) : serialized;
14520
14800
  }
14521
14801
  function indentHttpErrorBlock(value) {
14522
14802
  return value.split("\n").map((line) => ` ${line}`).join("\n");
14523
14803
  }
14524
14804
  function formatHttpHeaderValue(name, value) {
14525
- return name.toLowerCase() === "authorization" ? "Bearer ****" : value;
14805
+ return redactHttpHeaderValue(name, value);
14526
14806
  }
14527
14807
  function formatHttpErrorHeaders(headers) {
14528
14808
  return Object.entries(headers).map(
@@ -14540,7 +14820,11 @@ function renderHttpError(error3, options) {
14540
14820
  if (detailed) {
14541
14821
  lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
14542
14822
  if (error3.request.body !== void 0) {
14543
- lines.push("Request body:", indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)), "");
14823
+ lines.push(
14824
+ "Request body:",
14825
+ indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
14826
+ ""
14827
+ );
14544
14828
  }
14545
14829
  }
14546
14830
  lines.push(
@@ -16629,11 +16913,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
16629
16913
  if (!resolvedId) {
16630
16914
  return { status: "unknown", input };
16631
16915
  }
16632
- const config = registry[resolvedId];
16633
- if (!config) {
16916
+ const config2 = registry[resolvedId];
16917
+ if (!config2) {
16634
16918
  return { status: "unsupported", input, id: resolvedId };
16635
16919
  }
16636
- return { status: "supported", input, id: resolvedId, config: { ...config } };
16920
+ return { status: "supported", input, id: resolvedId, config: { ...config2 } };
16637
16921
  }
16638
16922
  function getAgentConfig(agentId) {
16639
16923
  const support = resolveAgentSupport(agentId);
@@ -17965,14 +18249,14 @@ async function installSkill(agentId, skill, options) {
17965
18249
  throw new UnsupportedAgentError(agentId);
17966
18250
  }
17967
18251
  const scope = options.scope ?? "local";
17968
- const config = support.config;
18252
+ const config2 = support.config;
17969
18253
  if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
17970
18254
  throw new Error(`Invalid skill name: ${skill.name}`);
17971
18255
  }
17972
- const skillDir = scope === "global" ? config.globalSkillDir : toHomeRelative(config.localSkillDir);
18256
+ const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
17973
18257
  const skillFolderPath = `${skillDir}/${skill.name}`;
17974
18258
  const skillFilePath = `${skillFolderPath}/SKILL.md`;
17975
- const displayPath = `${scope === "global" ? config.globalSkillDir : config.localSkillDir}/${skill.name}/SKILL.md`;
18259
+ const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
17976
18260
  const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
17977
18261
  if (await pathExists2(options.fs, absoluteSkillPath)) {
17978
18262
  throw new Error(`Skill already exists: ${displayPath}`);
@@ -18093,17 +18377,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
18093
18377
  return targetPath;
18094
18378
  }
18095
18379
  function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
18096
- const config = getAgentConfig(agent);
18097
- if (!config) {
18380
+ const config2 = getAgentConfig(agent);
18381
+ if (!config2) {
18098
18382
  throwUnsupportedAgent(agent);
18099
18383
  }
18100
18384
  return {
18101
18385
  displayPath: path22.join(
18102
- scope === "global" ? config.globalSkillDir : config.localSkillDir,
18386
+ scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
18103
18387
  TERMINAL_PILOT_SKILL_NAME
18104
18388
  ),
18105
18389
  fullPath: path22.join(
18106
- scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) : path22.resolve(cwd, config.localSkillDir),
18390
+ scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
18107
18391
  TERMINAL_PILOT_SKILL_NAME
18108
18392
  )
18109
18393
  };
@@ -19420,6 +19704,7 @@ function createTerminalPilotGroup() {
19420
19704
  var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
19421
19705
 
19422
19706
  // src/cli.ts
19707
+ configureTheme({ brand: "green", label: "Terminal Pilot" });
19423
19708
  function normalizeArgv(argv) {
19424
19709
  if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
19425
19710
  return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
@@ -19443,8 +19728,8 @@ async function isDirectExecution(argv) {
19443
19728
  try {
19444
19729
  const modulePath = fileURLToPath5(import.meta.url);
19445
19730
  const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
19446
- realpath2(path23.resolve(entryPoint)),
19447
- realpath2(modulePath)
19731
+ realpath3(path23.resolve(entryPoint)),
19732
+ realpath3(modulePath)
19448
19733
  ]);
19449
19734
  return resolvedEntryPoint === resolvedModulePath;
19450
19735
  } catch {