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.
- package/dist/cli.js +544 -259
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js.map +1 -1
- package/dist/commands/create-session.js.map +1 -1
- package/dist/commands/fill.js.map +1 -1
- package/dist/commands/get-session.js.map +1 -1
- package/dist/commands/index.js +220 -126
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +187 -93
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +154 -60
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js.map +1 -1
- package/dist/commands/press-key.js.map +1 -1
- package/dist/commands/read-history.js.map +1 -1
- package/dist/commands/read-screen.js.map +1 -1
- package/dist/commands/resize.js.map +1 -1
- package/dist/commands/runtime.js.map +1 -1
- package/dist/commands/screenshot.js.map +1 -1
- package/dist/commands/send-signal.js.map +1 -1
- package/dist/commands/type.js.map +1 -1
- package/dist/commands/uninstall.js +187 -93
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js.map +1 -1
- package/dist/commands/wait-for.js.map +1 -1
- package/dist/testing/cli-repl.js +544 -259
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +544 -259
- package/dist/testing/qa-cli.js.map +4 -4
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
|
-
import { realpath as
|
|
9
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
10
10
|
import path23 from "node:path";
|
|
11
11
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
Option
|
|
21
21
|
} from "commander";
|
|
22
22
|
|
|
23
|
-
// ../design
|
|
23
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
24
24
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
25
25
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
26
26
|
return true;
|
|
@@ -34,7 +34,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
34
34
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// ../design
|
|
37
|
+
// ../toolcraft-design/src/components/color.ts
|
|
38
38
|
var reset = "\x1B[0m";
|
|
39
39
|
var ansiStyles = {
|
|
40
40
|
reset: { open: reset },
|
|
@@ -136,41 +136,135 @@ function createColor(styles = []) {
|
|
|
136
136
|
}
|
|
137
137
|
var color = createColor();
|
|
138
138
|
|
|
139
|
-
// ../design
|
|
140
|
-
var
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
number: (text5) => color.cyanBright(text5),
|
|
145
|
-
intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
|
|
146
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
147
|
-
errorSymbol: color.red("\u25A0"),
|
|
148
|
-
accent: (text5) => color.cyan(text5),
|
|
149
|
-
muted: (text5) => color.dim(text5),
|
|
150
|
-
success: (text5) => color.green(text5),
|
|
151
|
-
warning: (text5) => color.yellow(text5),
|
|
152
|
-
error: (text5) => color.red(text5),
|
|
153
|
-
info: (text5) => color.magenta(text5),
|
|
154
|
-
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
139
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
140
|
+
var brands = {
|
|
141
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
142
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
143
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
155
144
|
};
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
|
|
162
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
163
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
164
|
-
accent: (text5) => color.hex("#006699").bold(text5),
|
|
165
|
-
muted: (text5) => color.hex("#666666")(text5),
|
|
166
|
-
success: (text5) => color.hex("#008800")(text5),
|
|
167
|
-
warning: (text5) => color.hex("#cc6600")(text5),
|
|
168
|
-
error: (text5) => color.hex("#cc0000")(text5),
|
|
169
|
-
info: (text5) => color.hex("#a200ff")(text5),
|
|
170
|
-
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
145
|
+
|
|
146
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
147
|
+
var defaults = {
|
|
148
|
+
brand: "purple",
|
|
149
|
+
label: "Poe"
|
|
171
150
|
};
|
|
151
|
+
var config = { ...defaults };
|
|
152
|
+
var revision = 0;
|
|
153
|
+
var brandConfigured = false;
|
|
154
|
+
function configureTheme(patch) {
|
|
155
|
+
if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
|
|
156
|
+
throw new Error(`Unknown brand: ${patch.brand}`);
|
|
157
|
+
}
|
|
158
|
+
config = {
|
|
159
|
+
brand: patch.brand ?? config.brand,
|
|
160
|
+
label: patch.label ?? config.label
|
|
161
|
+
};
|
|
162
|
+
if (patch.brand !== void 0) {
|
|
163
|
+
brandConfigured = true;
|
|
164
|
+
}
|
|
165
|
+
revision += 1;
|
|
166
|
+
}
|
|
167
|
+
function getThemeConfig() {
|
|
168
|
+
return { ...config };
|
|
169
|
+
}
|
|
170
|
+
function getThemeRevision() {
|
|
171
|
+
return revision;
|
|
172
|
+
}
|
|
173
|
+
function isThemeBrandConfigured() {
|
|
174
|
+
return brandConfigured;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
178
|
+
var brand = brands.purple.primary;
|
|
179
|
+
function withStyles(palette, styles) {
|
|
180
|
+
return Object.defineProperty(palette, "styles", {
|
|
181
|
+
value: styles,
|
|
182
|
+
enumerable: false
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function brandColor(activeBrand, purple) {
|
|
186
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
187
|
+
}
|
|
188
|
+
function brandBackground(activeBrand, purple) {
|
|
189
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
190
|
+
}
|
|
191
|
+
function createPalette(activeBrand, mode) {
|
|
192
|
+
const isPurple = activeBrand.name === "purple";
|
|
193
|
+
if (mode === "light") {
|
|
194
|
+
const active2 = color.hex(activeBrand.primary);
|
|
195
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
196
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
197
|
+
return withStyles(
|
|
198
|
+
{
|
|
199
|
+
header: (text5) => active2.bold(text5),
|
|
200
|
+
divider: (text5) => color.hex("#666666")(text5),
|
|
201
|
+
prompt: (text5) => prompt2.bold(text5),
|
|
202
|
+
number: (text5) => number2.bold(text5),
|
|
203
|
+
intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
|
|
204
|
+
get resolvedSymbol() {
|
|
205
|
+
return active2("\u25C7");
|
|
206
|
+
},
|
|
207
|
+
get errorSymbol() {
|
|
208
|
+
return color.hex("#cc0000")("\u25A0");
|
|
209
|
+
},
|
|
210
|
+
accent: (text5) => prompt2.bold(text5),
|
|
211
|
+
muted: (text5) => color.hex("#666666")(text5),
|
|
212
|
+
success: (text5) => color.hex("#008800")(text5),
|
|
213
|
+
warning: (text5) => color.hex("#cc6600")(text5),
|
|
214
|
+
error: (text5) => color.hex("#cc0000")(text5),
|
|
215
|
+
info: (text5) => active2(text5),
|
|
216
|
+
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
220
|
+
muted: { fg: "#666666" },
|
|
221
|
+
success: { fg: "#008800" },
|
|
222
|
+
warning: { fg: "#cc6600" },
|
|
223
|
+
error: { fg: "#cc0000" },
|
|
224
|
+
info: { fg: activeBrand.primary }
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
229
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
230
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
231
|
+
const prompt = isPurple ? color.cyan : active;
|
|
232
|
+
const number = isPurple ? color.cyanBright : active;
|
|
233
|
+
return withStyles(
|
|
234
|
+
{
|
|
235
|
+
header: (text5) => activeBright.bold(text5),
|
|
236
|
+
divider: (text5) => color.dim(text5),
|
|
237
|
+
prompt: (text5) => prompt(text5),
|
|
238
|
+
number: (text5) => number(text5),
|
|
239
|
+
intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
|
|
240
|
+
get resolvedSymbol() {
|
|
241
|
+
return active("\u25C7");
|
|
242
|
+
},
|
|
243
|
+
get errorSymbol() {
|
|
244
|
+
return color.red("\u25A0");
|
|
245
|
+
},
|
|
246
|
+
accent: (text5) => prompt(text5),
|
|
247
|
+
muted: (text5) => color.dim(text5),
|
|
248
|
+
success: (text5) => color.green(text5),
|
|
249
|
+
warning: (text5) => color.yellow(text5),
|
|
250
|
+
error: (text5) => color.red(text5),
|
|
251
|
+
info: (text5) => active(text5),
|
|
252
|
+
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
256
|
+
muted: { dim: true },
|
|
257
|
+
success: { fg: "green" },
|
|
258
|
+
warning: { fg: "yellow" },
|
|
259
|
+
error: { fg: "red" },
|
|
260
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
var dark = createPalette(brands.purple, "dark");
|
|
265
|
+
var light = createPalette(brands.purple, "light");
|
|
172
266
|
|
|
173
|
-
// ../design
|
|
267
|
+
// ../toolcraft-design/src/tokens/typography.ts
|
|
174
268
|
var typography = {
|
|
175
269
|
bold: (text5) => color.bold(text5),
|
|
176
270
|
dim: (text5) => color.dim(text5),
|
|
@@ -179,14 +273,14 @@ var typography = {
|
|
|
179
273
|
strikethrough: (text5) => color.strikethrough(text5)
|
|
180
274
|
};
|
|
181
275
|
|
|
182
|
-
// ../design
|
|
276
|
+
// ../toolcraft-design/src/tokens/widths.ts
|
|
183
277
|
var widths = {
|
|
184
278
|
header: 60,
|
|
185
279
|
helpColumn: 24,
|
|
186
280
|
maxLine: 80
|
|
187
281
|
};
|
|
188
282
|
|
|
189
|
-
// ../design
|
|
283
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
190
284
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
191
285
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
192
286
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -207,7 +301,7 @@ function resetOutputFormatCache() {
|
|
|
207
301
|
cached = void 0;
|
|
208
302
|
}
|
|
209
303
|
|
|
210
|
-
// ../design
|
|
304
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
211
305
|
function detectThemeFromEnv(env) {
|
|
212
306
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
213
307
|
if (typeof apple === "string") {
|
|
@@ -244,17 +338,30 @@ function resolveThemeName(env = process.env) {
|
|
|
244
338
|
}
|
|
245
339
|
return "dark";
|
|
246
340
|
}
|
|
247
|
-
var
|
|
341
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
342
|
+
var cachedRevision = -1;
|
|
248
343
|
function getTheme(env) {
|
|
344
|
+
const themeName = resolveThemeName(env);
|
|
345
|
+
const config2 = getThemeConfig();
|
|
346
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
347
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
348
|
+
const revision2 = getThemeRevision();
|
|
349
|
+
if (revision2 !== cachedRevision) {
|
|
350
|
+
themeCache.clear();
|
|
351
|
+
cachedRevision = revision2;
|
|
352
|
+
}
|
|
353
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
354
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
249
355
|
if (cachedTheme) {
|
|
250
356
|
return cachedTheme;
|
|
251
357
|
}
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
358
|
+
const activeBrand = brands[activeBrandName];
|
|
359
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
360
|
+
themeCache.set(cacheKey, theme);
|
|
361
|
+
return theme;
|
|
255
362
|
}
|
|
256
363
|
|
|
257
|
-
// ../design
|
|
364
|
+
// ../toolcraft-design/src/components/text.ts
|
|
258
365
|
function renderMarkdownInline(content) {
|
|
259
366
|
return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
260
367
|
}
|
|
@@ -370,7 +477,7 @@ var text = {
|
|
|
370
477
|
}
|
|
371
478
|
};
|
|
372
479
|
|
|
373
|
-
// ../design
|
|
480
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
374
481
|
var symbols = {
|
|
375
482
|
get info() {
|
|
376
483
|
const format = resolveOutputFormat();
|
|
@@ -424,12 +531,12 @@ var symbols = {
|
|
|
424
531
|
}
|
|
425
532
|
};
|
|
426
533
|
|
|
427
|
-
// ../design
|
|
534
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
428
535
|
function stripAnsi(value) {
|
|
429
536
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
430
537
|
}
|
|
431
538
|
|
|
432
|
-
// ../design
|
|
539
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
433
540
|
function renderMarkdownInline2(value) {
|
|
434
541
|
return stripAnsi(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
435
542
|
}
|
|
@@ -556,7 +663,7 @@ var log = {
|
|
|
556
663
|
error
|
|
557
664
|
};
|
|
558
665
|
|
|
559
|
-
// ../design
|
|
666
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
560
667
|
function createLogger(emitter) {
|
|
561
668
|
const emit = (level, message2) => {
|
|
562
669
|
if (emitter) {
|
|
@@ -617,7 +724,7 @@ function createLogger(emitter) {
|
|
|
617
724
|
}
|
|
618
725
|
var logger = createLogger();
|
|
619
726
|
|
|
620
|
-
// ../design
|
|
727
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
621
728
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
622
729
|
function normalizeInline(value) {
|
|
623
730
|
return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
@@ -793,7 +900,7 @@ function formatOptionList(options) {
|
|
|
793
900
|
});
|
|
794
901
|
}
|
|
795
902
|
|
|
796
|
-
// ../design
|
|
903
|
+
// ../toolcraft-design/src/components/help-formatter-plain.ts
|
|
797
904
|
var help_formatter_plain_exports = {};
|
|
798
905
|
__export(help_formatter_plain_exports, {
|
|
799
906
|
formatColumns: () => formatColumns2,
|
|
@@ -930,7 +1037,7 @@ function formatOptionList2(options) {
|
|
|
930
1037
|
});
|
|
931
1038
|
}
|
|
932
1039
|
|
|
933
|
-
// ../design
|
|
1040
|
+
// ../toolcraft-design/src/components/table.ts
|
|
934
1041
|
var reset2 = "\x1B[0m";
|
|
935
1042
|
var ellipsis = "\u2026";
|
|
936
1043
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -1214,7 +1321,7 @@ function renderTable(options) {
|
|
|
1214
1321
|
}
|
|
1215
1322
|
}
|
|
1216
1323
|
|
|
1217
|
-
// ../design
|
|
1324
|
+
// ../toolcraft-design/src/components/detail-card.ts
|
|
1218
1325
|
function wrap(value, width) {
|
|
1219
1326
|
const lines = [];
|
|
1220
1327
|
for (const paragraph of value.split("\n")) {
|
|
@@ -1277,7 +1384,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1277
1384
|
return blocks.join("\n\n");
|
|
1278
1385
|
}
|
|
1279
1386
|
|
|
1280
|
-
// ../design
|
|
1387
|
+
// ../toolcraft-design/src/components/template.ts
|
|
1281
1388
|
var MAX_PARTIAL_DEPTH = 100;
|
|
1282
1389
|
var HTML_ESCAPE = {
|
|
1283
1390
|
"&": "&",
|
|
@@ -1689,22 +1796,22 @@ function hasProperty(value, key2) {
|
|
|
1689
1796
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1690
1797
|
}
|
|
1691
1798
|
|
|
1692
|
-
// ../design
|
|
1799
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1693
1800
|
import { spawn } from "node:child_process";
|
|
1694
1801
|
import process2 from "node:process";
|
|
1695
1802
|
|
|
1696
|
-
// ../design
|
|
1803
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1697
1804
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1698
1805
|
var storage = new AsyncLocalStorage2();
|
|
1699
1806
|
|
|
1700
|
-
// ../design
|
|
1807
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1701
1808
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1702
1809
|
|
|
1703
|
-
// ../design
|
|
1810
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1704
1811
|
import readline from "node:readline";
|
|
1705
1812
|
import { PassThrough } from "node:stream";
|
|
1706
1813
|
|
|
1707
|
-
// ../design
|
|
1814
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1708
1815
|
var REGION_HEADER = 1 << 0;
|
|
1709
1816
|
var REGION_LIST = 1 << 1;
|
|
1710
1817
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1713,10 +1820,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1713
1820
|
var REGION_TOAST = 1 << 5;
|
|
1714
1821
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1715
1822
|
|
|
1716
|
-
// ../design
|
|
1823
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1717
1824
|
import * as clack from "@clack/prompts";
|
|
1718
1825
|
|
|
1719
|
-
// ../design
|
|
1826
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1720
1827
|
import { isCancel } from "@clack/prompts";
|
|
1721
1828
|
function cancel(msg = "") {
|
|
1722
1829
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1727,7 +1834,7 @@ function cancel(msg = "") {
|
|
|
1727
1834
|
`);
|
|
1728
1835
|
}
|
|
1729
1836
|
|
|
1730
|
-
// ../design
|
|
1837
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1731
1838
|
function getVisibleWidth(value) {
|
|
1732
1839
|
return stripAnsi(value).length;
|
|
1733
1840
|
}
|
|
@@ -1776,10 +1883,10 @@ function note(message2, title) {
|
|
|
1776
1883
|
`);
|
|
1777
1884
|
}
|
|
1778
1885
|
|
|
1779
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1780
1887
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1781
1888
|
|
|
1782
|
-
// ../design
|
|
1889
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1783
1890
|
async function select2(opts) {
|
|
1784
1891
|
return clack.select(opts);
|
|
1785
1892
|
}
|
|
@@ -1822,19 +1929,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1822
1929
|
};
|
|
1823
1930
|
|
|
1824
1931
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1825
|
-
function validateHumanInLoopOnDefine(
|
|
1826
|
-
const label = Array.isArray(
|
|
1827
|
-
if (
|
|
1828
|
-
throw new Error(`${label} '${
|
|
1932
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
1933
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
1934
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
1935
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
1829
1936
|
}
|
|
1830
|
-
if (
|
|
1937
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1831
1938
|
return;
|
|
1832
1939
|
}
|
|
1833
|
-
if (
|
|
1834
|
-
throw new Error(`${label} '${
|
|
1940
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
1941
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
1835
1942
|
}
|
|
1836
|
-
if (typeof
|
|
1837
|
-
throw new Error(`${label} '${
|
|
1943
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
1944
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1838
1945
|
}
|
|
1839
1946
|
}
|
|
1840
1947
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1910,12 +2017,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1910
2017
|
}
|
|
1911
2018
|
}
|
|
1912
2019
|
}
|
|
1913
|
-
function OneOf(
|
|
1914
|
-
assertValidBranches(
|
|
2020
|
+
function OneOf(config2) {
|
|
2021
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1915
2022
|
return {
|
|
1916
2023
|
kind: "oneOf",
|
|
1917
|
-
discriminator:
|
|
1918
|
-
branches:
|
|
2024
|
+
discriminator: config2.discriminator,
|
|
2025
|
+
branches: config2.branches
|
|
1919
2026
|
};
|
|
1920
2027
|
}
|
|
1921
2028
|
|
|
@@ -2165,22 +2272,22 @@ function cloneStringArray(values) {
|
|
|
2165
2272
|
function cloneStringRecord(values) {
|
|
2166
2273
|
return values === void 0 ? void 0 : { ...values };
|
|
2167
2274
|
}
|
|
2168
|
-
function cloneMcpServerConfig(
|
|
2169
|
-
if (
|
|
2275
|
+
function cloneMcpServerConfig(config2) {
|
|
2276
|
+
if (config2 === void 0) {
|
|
2170
2277
|
return void 0;
|
|
2171
2278
|
}
|
|
2172
|
-
if (
|
|
2279
|
+
if (config2.transport === "stdio") {
|
|
2173
2280
|
return {
|
|
2174
2281
|
transport: "stdio",
|
|
2175
|
-
command:
|
|
2176
|
-
args: cloneStringArray(
|
|
2177
|
-
env: cloneStringRecord(
|
|
2282
|
+
command: config2.command,
|
|
2283
|
+
args: cloneStringArray(config2.args),
|
|
2284
|
+
env: cloneStringRecord(config2.env)
|
|
2178
2285
|
};
|
|
2179
2286
|
}
|
|
2180
2287
|
return {
|
|
2181
2288
|
transport: "http",
|
|
2182
|
-
url:
|
|
2183
|
-
headers: cloneStringRecord(
|
|
2289
|
+
url: config2.url,
|
|
2290
|
+
headers: cloneStringRecord(config2.headers)
|
|
2184
2291
|
};
|
|
2185
2292
|
}
|
|
2186
2293
|
function cloneRenameMap(rename5) {
|
|
@@ -2421,57 +2528,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2421
2528
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2422
2529
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2423
2530
|
}
|
|
2424
|
-
function createBaseCommand(
|
|
2531
|
+
function createBaseCommand(config2) {
|
|
2425
2532
|
const command = {
|
|
2426
2533
|
kind: "command",
|
|
2427
|
-
name:
|
|
2428
|
-
description:
|
|
2429
|
-
aliases: [...
|
|
2430
|
-
positional: [...
|
|
2431
|
-
params:
|
|
2432
|
-
secrets: cloneSecrets(
|
|
2433
|
-
scope: resolveCommandScope(
|
|
2434
|
-
confirm:
|
|
2435
|
-
humanInLoop:
|
|
2436
|
-
requires: cloneRequires(
|
|
2437
|
-
handler:
|
|
2438
|
-
render:
|
|
2534
|
+
name: config2.name,
|
|
2535
|
+
description: config2.description,
|
|
2536
|
+
aliases: [...config2.aliases ?? []],
|
|
2537
|
+
positional: [...config2.positional ?? []],
|
|
2538
|
+
params: config2.params,
|
|
2539
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2540
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
2541
|
+
confirm: config2.confirm ?? false,
|
|
2542
|
+
humanInLoop: config2.humanInLoop,
|
|
2543
|
+
requires: cloneRequires(config2.requires),
|
|
2544
|
+
handler: config2.handler,
|
|
2545
|
+
render: config2.render
|
|
2439
2546
|
};
|
|
2440
2547
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2441
2548
|
value: {
|
|
2442
|
-
scope: cloneScope(
|
|
2443
|
-
humanInLoop:
|
|
2444
|
-
secrets: cloneSecrets(
|
|
2445
|
-
requires: cloneRequires(
|
|
2549
|
+
scope: cloneScope(config2.scope),
|
|
2550
|
+
humanInLoop: config2.humanInLoop,
|
|
2551
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2552
|
+
requires: cloneRequires(config2.requires),
|
|
2446
2553
|
sourcePath: inferCommandSourcePath()
|
|
2447
2554
|
}
|
|
2448
2555
|
});
|
|
2449
2556
|
return command;
|
|
2450
2557
|
}
|
|
2451
|
-
function createBaseGroup(
|
|
2558
|
+
function createBaseGroup(config2) {
|
|
2452
2559
|
const group = {
|
|
2453
2560
|
kind: "group",
|
|
2454
|
-
name:
|
|
2455
|
-
description:
|
|
2456
|
-
aliases: [...
|
|
2457
|
-
scope: resolveGroupScope(
|
|
2458
|
-
humanInLoop:
|
|
2459
|
-
secrets: cloneSecrets(
|
|
2460
|
-
requires: cloneRequires(
|
|
2561
|
+
name: config2.name,
|
|
2562
|
+
description: config2.description,
|
|
2563
|
+
aliases: [...config2.aliases ?? []],
|
|
2564
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
2565
|
+
humanInLoop: config2.humanInLoop,
|
|
2566
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2567
|
+
requires: cloneRequires(config2.requires),
|
|
2461
2568
|
children: [],
|
|
2462
2569
|
default: void 0
|
|
2463
2570
|
};
|
|
2464
2571
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2465
2572
|
value: {
|
|
2466
|
-
mcp: cloneMcpServerConfig(
|
|
2467
|
-
scope: cloneScope(
|
|
2468
|
-
humanInLoop:
|
|
2469
|
-
secrets: cloneSecrets(
|
|
2470
|
-
tools: cloneStringArray(
|
|
2471
|
-
rename: cloneRenameMap(
|
|
2472
|
-
requires: cloneRequires(
|
|
2473
|
-
children: [...
|
|
2474
|
-
default:
|
|
2573
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
2574
|
+
scope: cloneScope(config2.scope),
|
|
2575
|
+
humanInLoop: config2.humanInLoop,
|
|
2576
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2577
|
+
tools: cloneStringArray(config2.tools),
|
|
2578
|
+
rename: cloneRenameMap(config2.rename),
|
|
2579
|
+
requires: cloneRequires(config2.requires),
|
|
2580
|
+
children: [...config2.children],
|
|
2581
|
+
default: config2.default
|
|
2475
2582
|
}
|
|
2476
2583
|
});
|
|
2477
2584
|
return group;
|
|
@@ -2574,10 +2681,10 @@ function materializeNode(node, inherited) {
|
|
|
2574
2681
|
}
|
|
2575
2682
|
return materializeGroup(node, inherited);
|
|
2576
2683
|
}
|
|
2577
|
-
function defineCommand(
|
|
2578
|
-
validateHumanInLoopOnDefine(
|
|
2684
|
+
function defineCommand(config2) {
|
|
2685
|
+
validateHumanInLoopOnDefine(config2);
|
|
2579
2686
|
return materializeCommand(
|
|
2580
|
-
createBaseCommand(
|
|
2687
|
+
createBaseCommand(config2),
|
|
2581
2688
|
{
|
|
2582
2689
|
scope: void 0,
|
|
2583
2690
|
humanInLoop: void 0,
|
|
@@ -2586,10 +2693,10 @@ function defineCommand(config) {
|
|
|
2586
2693
|
}
|
|
2587
2694
|
);
|
|
2588
2695
|
}
|
|
2589
|
-
function defineGroup(
|
|
2590
|
-
validateRenameMap(
|
|
2591
|
-
validateHumanInLoopOnDefine(
|
|
2592
|
-
return materializeGroup(createBaseGroup(
|
|
2696
|
+
function defineGroup(config2) {
|
|
2697
|
+
validateRenameMap(config2.rename);
|
|
2698
|
+
validateHumanInLoopOnDefine(config2);
|
|
2699
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2593
2700
|
scope: void 0,
|
|
2594
2701
|
humanInLoop: void 0,
|
|
2595
2702
|
secrets: {},
|
|
@@ -2758,7 +2865,7 @@ import path3 from "node:path";
|
|
|
2758
2865
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2759
2866
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2760
2867
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2761
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2868
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2762
2869
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2763
2870
|
import path5 from "node:path";
|
|
2764
2871
|
|
|
@@ -4446,7 +4553,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4446
4553
|
}
|
|
4447
4554
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4448
4555
|
}
|
|
4449
|
-
function createdFrontmatter(
|
|
4556
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4450
4557
|
const frontmatter = mode !== "passthrough" ? {
|
|
4451
4558
|
$schema: TASK_SCHEMA_ID,
|
|
4452
4559
|
kind: TASK_KIND,
|
|
@@ -4458,7 +4565,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4458
4565
|
state: initialState
|
|
4459
4566
|
};
|
|
4460
4567
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4461
|
-
for (const [key2, value] of Object.entries(
|
|
4568
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4462
4569
|
if (!reservedKeys.has(key2)) {
|
|
4463
4570
|
setOwnValue(frontmatter, key2, value);
|
|
4464
4571
|
}
|
|
@@ -5204,13 +5311,13 @@ function matchesFilter(task, filter) {
|
|
|
5204
5311
|
}
|
|
5205
5312
|
return true;
|
|
5206
5313
|
}
|
|
5207
|
-
function createTaskRecord(
|
|
5314
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5208
5315
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5209
5316
|
name: input.name,
|
|
5210
5317
|
state: initialState,
|
|
5211
5318
|
description: input.description ?? ""
|
|
5212
5319
|
});
|
|
5213
|
-
for (const [key2, value] of Object.entries(
|
|
5320
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5214
5321
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5215
5322
|
taskRecord[key2] = value;
|
|
5216
5323
|
}
|
|
@@ -6584,7 +6691,7 @@ function isMissingStateError(error3) {
|
|
|
6584
6691
|
}
|
|
6585
6692
|
|
|
6586
6693
|
// ../toolcraft/src/error-report.ts
|
|
6587
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6694
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6588
6695
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6589
6696
|
import os from "node:os";
|
|
6590
6697
|
import path13 from "node:path";
|
|
@@ -7103,19 +7210,24 @@ function createAuthStoreClientStore(options) {
|
|
|
7103
7210
|
}
|
|
7104
7211
|
};
|
|
7105
7212
|
}
|
|
7106
|
-
function createNamedSecretStore(key2, options,
|
|
7213
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
7107
7214
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
7108
|
-
const
|
|
7215
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7216
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
7109
7217
|
const fileStore = {
|
|
7110
7218
|
...options.fileStore,
|
|
7111
|
-
|
|
7112
|
-
|
|
7219
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7220
|
+
parsedFilePath.dir,
|
|
7221
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7222
|
+
),
|
|
7223
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7224
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
7113
7225
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7114
7226
|
};
|
|
7115
7227
|
const keychainStore = {
|
|
7116
7228
|
...options.keychainStore,
|
|
7117
|
-
service: options.keychainStore?.service ??
|
|
7118
|
-
account: `${options.keychainStore?.account ??
|
|
7229
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7230
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
7119
7231
|
};
|
|
7120
7232
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
7121
7233
|
}
|
|
@@ -8715,6 +8827,9 @@ var McpClient = class {
|
|
|
8715
8827
|
const abortPromise = new Promise((_, reject) => {
|
|
8716
8828
|
const rejectWithAbortReason = () => {
|
|
8717
8829
|
sendCancellationNotification();
|
|
8830
|
+
if (requestId !== void 0) {
|
|
8831
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
8832
|
+
}
|
|
8718
8833
|
reject(signal.reason);
|
|
8719
8834
|
};
|
|
8720
8835
|
abortListener = rejectWithAbortReason;
|
|
@@ -8889,11 +9004,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8889
9004
|
const child = this.child;
|
|
8890
9005
|
this.readable = child.stdout;
|
|
8891
9006
|
this.writable = child.stdin;
|
|
9007
|
+
const stderrDecoder = new TextDecoder();
|
|
8892
9008
|
child.stderr.on("data", (chunk) => {
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
9009
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9010
|
+
this.appendStderrOutput(decoded);
|
|
9011
|
+
});
|
|
9012
|
+
child.stderr.once("end", () => {
|
|
9013
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8897
9014
|
});
|
|
8898
9015
|
this.closed = new Promise((resolve) => {
|
|
8899
9016
|
let settled = false;
|
|
@@ -8933,6 +9050,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
8933
9050
|
getStderrOutput() {
|
|
8934
9051
|
return this.stderrOutput;
|
|
8935
9052
|
}
|
|
9053
|
+
appendStderrOutput(chunk) {
|
|
9054
|
+
if (chunk.length === 0) {
|
|
9055
|
+
return;
|
|
9056
|
+
}
|
|
9057
|
+
this.stderrOutput += chunk;
|
|
9058
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9059
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9060
|
+
}
|
|
9061
|
+
}
|
|
8936
9062
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
8937
9063
|
void reason;
|
|
8938
9064
|
if (this.disposed) {
|
|
@@ -9340,15 +9466,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9340
9466
|
return `${JSON.stringify(message2)}
|
|
9341
9467
|
`;
|
|
9342
9468
|
}
|
|
9343
|
-
function chunkToString(chunk) {
|
|
9344
|
-
if (typeof chunk === "string") {
|
|
9345
|
-
return chunk;
|
|
9346
|
-
}
|
|
9347
|
-
if (chunk instanceof Uint8Array) {
|
|
9348
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9349
|
-
}
|
|
9350
|
-
return String(chunk);
|
|
9351
|
-
}
|
|
9352
9469
|
function normalizeLine(line) {
|
|
9353
9470
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9354
9471
|
}
|
|
@@ -9538,6 +9655,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9538
9655
|
}
|
|
9539
9656
|
});
|
|
9540
9657
|
}
|
|
9658
|
+
cancelRequest(requestId, reason) {
|
|
9659
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9660
|
+
if (pending === void 0) {
|
|
9661
|
+
return false;
|
|
9662
|
+
}
|
|
9663
|
+
this.pendingRequests.delete(requestId);
|
|
9664
|
+
clearTimeout(pending.timeout);
|
|
9665
|
+
pending.reject(reason);
|
|
9666
|
+
return true;
|
|
9667
|
+
}
|
|
9541
9668
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9542
9669
|
if (this.disposedError !== void 0) {
|
|
9543
9670
|
return;
|
|
@@ -10606,10 +10733,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10606
10733
|
}
|
|
10607
10734
|
}
|
|
10608
10735
|
}
|
|
10609
|
-
function createConnection(name,
|
|
10736
|
+
function createConnection(name, config2) {
|
|
10610
10737
|
const connection = {
|
|
10611
10738
|
name,
|
|
10612
|
-
config,
|
|
10739
|
+
config: config2,
|
|
10613
10740
|
async dispose() {
|
|
10614
10741
|
shutdownDisposers.delete(connection.dispose);
|
|
10615
10742
|
connection.connecting = void 0;
|
|
@@ -10676,13 +10803,13 @@ async function writeCache(cachePath, cache) {
|
|
|
10676
10803
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10677
10804
|
await rename2(tempPath, cachePath);
|
|
10678
10805
|
}
|
|
10679
|
-
async function fetchCache(name,
|
|
10806
|
+
async function fetchCache(name, config2) {
|
|
10680
10807
|
const logger2 = createLogger((message2) => {
|
|
10681
10808
|
process.stderr.write(`${message2}
|
|
10682
10809
|
`);
|
|
10683
10810
|
});
|
|
10684
10811
|
logger2.info(`MCP ${name}: connecting`);
|
|
10685
|
-
const client = await dialUpstream(name,
|
|
10812
|
+
const client = await dialUpstream(name, config2);
|
|
10686
10813
|
try {
|
|
10687
10814
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10688
10815
|
const tools = [];
|
|
@@ -10701,7 +10828,7 @@ async function fetchCache(name, config) {
|
|
|
10701
10828
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10702
10829
|
version: 1,
|
|
10703
10830
|
upstream,
|
|
10704
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
10831
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10705
10832
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10706
10833
|
tools
|
|
10707
10834
|
};
|
|
@@ -10771,8 +10898,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10771
10898
|
}
|
|
10772
10899
|
async function resolveSingleProxy(group, options) {
|
|
10773
10900
|
const internal = getInternalGroupConfig2(group);
|
|
10774
|
-
const
|
|
10775
|
-
if (
|
|
10901
|
+
const config2 = internal.mcp;
|
|
10902
|
+
if (config2 === void 0) {
|
|
10776
10903
|
return;
|
|
10777
10904
|
}
|
|
10778
10905
|
const name = group.name;
|
|
@@ -10782,21 +10909,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10782
10909
|
let cache;
|
|
10783
10910
|
let shouldWriteCache = false;
|
|
10784
10911
|
if (isRefreshRequested(name, refresh)) {
|
|
10785
|
-
cache = await fetchCache(name,
|
|
10912
|
+
cache = await fetchCache(name, config2);
|
|
10786
10913
|
shouldWriteCache = true;
|
|
10787
10914
|
} else {
|
|
10788
10915
|
const storedCache = await readCache(cachePath);
|
|
10789
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
10916
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10790
10917
|
cache = storedCache;
|
|
10791
10918
|
} else {
|
|
10792
|
-
cache = await fetchCache(name,
|
|
10919
|
+
cache = await fetchCache(name, config2);
|
|
10793
10920
|
shouldWriteCache = true;
|
|
10794
10921
|
}
|
|
10795
10922
|
}
|
|
10796
10923
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10797
10924
|
validateRenameMap2(name, tools, internal.rename);
|
|
10798
10925
|
const previousConnection = getProxyConnection(group);
|
|
10799
|
-
const nextConnection = createConnection(name,
|
|
10926
|
+
const nextConnection = createConnection(name, config2);
|
|
10800
10927
|
try {
|
|
10801
10928
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10802
10929
|
if (shouldWriteCache) {
|
|
@@ -10821,11 +10948,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10821
10948
|
);
|
|
10822
10949
|
}
|
|
10823
10950
|
}
|
|
10824
|
-
function cacheMatchesConfig(cache,
|
|
10825
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
10951
|
+
function cacheMatchesConfig(cache, config2) {
|
|
10952
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10826
10953
|
}
|
|
10827
|
-
function fingerprintMcpServerConfig(
|
|
10828
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
10954
|
+
function fingerprintMcpServerConfig(config2) {
|
|
10955
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10829
10956
|
}
|
|
10830
10957
|
function collectProxyGroups(root) {
|
|
10831
10958
|
const groups = [];
|
|
@@ -10903,20 +11030,20 @@ function parseRefreshEnv(value) {
|
|
|
10903
11030
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10904
11031
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10905
11032
|
}
|
|
10906
|
-
async function dialUpstream(name,
|
|
11033
|
+
async function dialUpstream(name, config2) {
|
|
10907
11034
|
const client = new McpClient({
|
|
10908
11035
|
clientInfo: {
|
|
10909
11036
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10910
11037
|
version: DEFAULT_CLIENT_INFO.version
|
|
10911
11038
|
}
|
|
10912
11039
|
});
|
|
10913
|
-
const transport =
|
|
10914
|
-
command:
|
|
10915
|
-
...
|
|
10916
|
-
...
|
|
11040
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11041
|
+
command: config2.command,
|
|
11042
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11043
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10917
11044
|
}) : new HttpTransport({
|
|
10918
|
-
url:
|
|
10919
|
-
...
|
|
11045
|
+
url: config2.url,
|
|
11046
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10920
11047
|
});
|
|
10921
11048
|
await client.connect(transport);
|
|
10922
11049
|
return client;
|
|
@@ -10926,10 +11053,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
10926
11053
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
10927
11054
|
}
|
|
10928
11055
|
|
|
11056
|
+
// ../toolcraft/src/redaction.ts
|
|
11057
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11058
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11059
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11060
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11061
|
+
function isPlainObject2(value) {
|
|
11062
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11063
|
+
}
|
|
11064
|
+
function normalizeName(name) {
|
|
11065
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11066
|
+
}
|
|
11067
|
+
function isSensitiveName(name) {
|
|
11068
|
+
const normalized = normalizeName(name);
|
|
11069
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11070
|
+
}
|
|
11071
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11072
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11073
|
+
return REDACTED_VALUE;
|
|
11074
|
+
}
|
|
11075
|
+
if (Array.isArray(value)) {
|
|
11076
|
+
if (seen.has(value)) {
|
|
11077
|
+
return "[Circular]";
|
|
11078
|
+
}
|
|
11079
|
+
seen.add(value);
|
|
11080
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11081
|
+
}
|
|
11082
|
+
if (isPlainObject2(value)) {
|
|
11083
|
+
if (seen.has(value)) {
|
|
11084
|
+
return "[Circular]";
|
|
11085
|
+
}
|
|
11086
|
+
seen.add(value);
|
|
11087
|
+
return Object.fromEntries(
|
|
11088
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11089
|
+
key2,
|
|
11090
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11091
|
+
])
|
|
11092
|
+
);
|
|
11093
|
+
}
|
|
11094
|
+
return value;
|
|
11095
|
+
}
|
|
11096
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11097
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11098
|
+
}
|
|
11099
|
+
function parseJsonObjectOrArray(value) {
|
|
11100
|
+
const trimmed = value.trim();
|
|
11101
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11102
|
+
return void 0;
|
|
11103
|
+
}
|
|
11104
|
+
try {
|
|
11105
|
+
const parsed = JSON.parse(trimmed);
|
|
11106
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11107
|
+
} catch {
|
|
11108
|
+
return void 0;
|
|
11109
|
+
}
|
|
11110
|
+
}
|
|
11111
|
+
function redactHttpBody(body) {
|
|
11112
|
+
if (typeof body === "string") {
|
|
11113
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11114
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11115
|
+
}
|
|
11116
|
+
return redactSecretLikeFields(body);
|
|
11117
|
+
}
|
|
11118
|
+
function redactHttpHeaderValue(name, value) {
|
|
11119
|
+
const normalized = normalizeName(name);
|
|
11120
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11121
|
+
return "Bearer ****";
|
|
11122
|
+
}
|
|
11123
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11124
|
+
return REDACTED_VALUE;
|
|
11125
|
+
}
|
|
11126
|
+
return value;
|
|
11127
|
+
}
|
|
11128
|
+
|
|
10929
11129
|
// ../toolcraft/src/error-report.ts
|
|
10930
11130
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
10931
|
-
|
|
10932
|
-
function isPlainObject2(value) {
|
|
11131
|
+
function isPlainObject3(value) {
|
|
10933
11132
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10934
11133
|
}
|
|
10935
11134
|
function unwrapOptional(schema) {
|
|
@@ -10939,7 +11138,7 @@ function unwrapOptional(schema) {
|
|
|
10939
11138
|
return schema;
|
|
10940
11139
|
}
|
|
10941
11140
|
function hasHttpContext(error3) {
|
|
10942
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11141
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
10943
11142
|
}
|
|
10944
11143
|
function isSkippedError(error3) {
|
|
10945
11144
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -10976,8 +11175,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
|
10976
11175
|
throw new Error("Error report directory resolves outside project root.");
|
|
10977
11176
|
}
|
|
10978
11177
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
10979
|
-
|
|
10980
|
-
|
|
11178
|
+
realpath2(projectRoot),
|
|
11179
|
+
realpath2(reportDir)
|
|
10981
11180
|
]);
|
|
10982
11181
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
10983
11182
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -11032,9 +11231,24 @@ function redactValue(value) {
|
|
|
11032
11231
|
}
|
|
11033
11232
|
return `<set, ${value.length} chars>`;
|
|
11034
11233
|
}
|
|
11035
|
-
function
|
|
11036
|
-
|
|
11037
|
-
|
|
11234
|
+
function collectStringLeaves(value, output) {
|
|
11235
|
+
if (typeof value === "string") {
|
|
11236
|
+
if (value.length > 0) {
|
|
11237
|
+
output.add(value);
|
|
11238
|
+
}
|
|
11239
|
+
return;
|
|
11240
|
+
}
|
|
11241
|
+
if (Array.isArray(value)) {
|
|
11242
|
+
for (const entry of value) {
|
|
11243
|
+
collectStringLeaves(entry, output);
|
|
11244
|
+
}
|
|
11245
|
+
return;
|
|
11246
|
+
}
|
|
11247
|
+
if (isPlainObject3(value)) {
|
|
11248
|
+
for (const entry of Object.values(value)) {
|
|
11249
|
+
collectStringLeaves(entry, output);
|
|
11250
|
+
}
|
|
11251
|
+
}
|
|
11038
11252
|
}
|
|
11039
11253
|
function schemaSecretValue(schema) {
|
|
11040
11254
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -11055,7 +11269,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
11055
11269
|
return "<redacted>";
|
|
11056
11270
|
}
|
|
11057
11271
|
const unwrapped = unwrapOptional(schema);
|
|
11058
|
-
if (unwrapped.kind === "object" &&
|
|
11272
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11059
11273
|
return Object.fromEntries(
|
|
11060
11274
|
Object.entries(value).map(([key2, childValue]) => {
|
|
11061
11275
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -11077,6 +11291,52 @@ function redactParams(params17, command) {
|
|
|
11077
11291
|
}
|
|
11078
11292
|
return redactParamsValue(params17, command.params, "");
|
|
11079
11293
|
}
|
|
11294
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11295
|
+
if (shouldRedactParam(name, schema)) {
|
|
11296
|
+
collectStringLeaves(value, output);
|
|
11297
|
+
return;
|
|
11298
|
+
}
|
|
11299
|
+
const unwrapped = unwrapOptional(schema);
|
|
11300
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11301
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11302
|
+
const childSchema = unwrapped.shape[key2];
|
|
11303
|
+
if (childSchema !== void 0) {
|
|
11304
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11305
|
+
}
|
|
11306
|
+
}
|
|
11307
|
+
return;
|
|
11308
|
+
}
|
|
11309
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11310
|
+
for (const entry of value) {
|
|
11311
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11312
|
+
}
|
|
11313
|
+
}
|
|
11314
|
+
}
|
|
11315
|
+
function createReportStringRedactor(context, env) {
|
|
11316
|
+
const values = /* @__PURE__ */ new Set();
|
|
11317
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11318
|
+
if (value !== void 0 && value.length > 0) {
|
|
11319
|
+
values.add(value);
|
|
11320
|
+
}
|
|
11321
|
+
}
|
|
11322
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11323
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11324
|
+
if (value !== void 0 && value.length > 0) {
|
|
11325
|
+
values.add(value);
|
|
11326
|
+
}
|
|
11327
|
+
}
|
|
11328
|
+
if (context.command !== void 0) {
|
|
11329
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11330
|
+
}
|
|
11331
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11332
|
+
return (value) => {
|
|
11333
|
+
let redacted = value;
|
|
11334
|
+
for (const secretValue of orderedValues) {
|
|
11335
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11336
|
+
}
|
|
11337
|
+
return redacted;
|
|
11338
|
+
};
|
|
11339
|
+
}
|
|
11080
11340
|
function commandSecretEnvNames(secrets) {
|
|
11081
11341
|
if (secrets === void 0) {
|
|
11082
11342
|
return [];
|
|
@@ -11130,28 +11390,42 @@ function redactArgv(argv, options) {
|
|
|
11130
11390
|
function stableJson(value) {
|
|
11131
11391
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
11132
11392
|
}
|
|
11133
|
-
function redactStructuredErrorField(name, value) {
|
|
11134
|
-
if (typeof value === "string"
|
|
11135
|
-
|
|
11393
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11394
|
+
if (typeof value === "string") {
|
|
11395
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11396
|
+
if (redactedHeaderValue !== value) {
|
|
11397
|
+
return redactedHeaderValue;
|
|
11398
|
+
}
|
|
11399
|
+
if (isSensitiveName(name)) {
|
|
11400
|
+
return "<redacted>";
|
|
11401
|
+
}
|
|
11402
|
+
return redactString(value);
|
|
11136
11403
|
}
|
|
11137
11404
|
if (Array.isArray(value)) {
|
|
11138
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11405
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
11139
11406
|
}
|
|
11140
|
-
if (
|
|
11407
|
+
if (isPlainObject3(value)) {
|
|
11141
11408
|
return Object.fromEntries(
|
|
11142
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11409
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11410
|
+
key2,
|
|
11411
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11412
|
+
])
|
|
11143
11413
|
);
|
|
11144
11414
|
}
|
|
11145
11415
|
return value;
|
|
11146
11416
|
}
|
|
11147
|
-
function ownStructuredFields(error3) {
|
|
11417
|
+
function ownStructuredFields(error3, redactString) {
|
|
11148
11418
|
const fields = {};
|
|
11149
11419
|
for (const key2 of Object.keys(error3)) {
|
|
11150
11420
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
11151
11421
|
continue;
|
|
11152
11422
|
}
|
|
11153
11423
|
Object.defineProperty(fields, key2, {
|
|
11154
|
-
value: redactStructuredErrorField(
|
|
11424
|
+
value: redactStructuredErrorField(
|
|
11425
|
+
key2,
|
|
11426
|
+
error3[key2],
|
|
11427
|
+
redactString
|
|
11428
|
+
),
|
|
11155
11429
|
enumerable: true,
|
|
11156
11430
|
configurable: true,
|
|
11157
11431
|
writable: true
|
|
@@ -11159,43 +11433,44 @@ function ownStructuredFields(error3) {
|
|
|
11159
11433
|
}
|
|
11160
11434
|
return fields;
|
|
11161
11435
|
}
|
|
11162
|
-
function formatStackChain(error3) {
|
|
11436
|
+
function formatStackChain(error3, redactString) {
|
|
11163
11437
|
const lines = [];
|
|
11164
11438
|
let current = error3;
|
|
11165
11439
|
let index = 0;
|
|
11166
11440
|
while (current !== void 0) {
|
|
11167
11441
|
if (current instanceof Error) {
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
);
|
|
11442
|
+
const stack = current.stack ?? String(current);
|
|
11443
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
11171
11444
|
current = current.cause;
|
|
11172
11445
|
} else {
|
|
11173
|
-
|
|
11446
|
+
const message2 = String(current);
|
|
11447
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
11174
11448
|
current = void 0;
|
|
11175
11449
|
}
|
|
11176
11450
|
index += 1;
|
|
11177
11451
|
}
|
|
11178
11452
|
return lines.join("\n");
|
|
11179
11453
|
}
|
|
11180
|
-
function formatHeaderValue(name, value) {
|
|
11181
|
-
return name
|
|
11454
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11455
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
11182
11456
|
}
|
|
11183
|
-
function formatHeaders(headers) {
|
|
11184
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11457
|
+
function formatHeaders(headers, redactString) {
|
|
11458
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
11185
11459
|
}
|
|
11186
|
-
function formatBody(body) {
|
|
11187
|
-
|
|
11188
|
-
|
|
11460
|
+
function formatBody(body, redactString) {
|
|
11461
|
+
const redactedBody = redactHttpBody(body);
|
|
11462
|
+
if (typeof redactedBody === "string") {
|
|
11463
|
+
return redactString(redactedBody);
|
|
11189
11464
|
}
|
|
11190
|
-
return stableJson(
|
|
11465
|
+
return redactString(stableJson(redactedBody));
|
|
11191
11466
|
}
|
|
11192
|
-
function formatHttpTranscript(error3) {
|
|
11467
|
+
function formatHttpTranscript(error3, redactString) {
|
|
11193
11468
|
const requestLines = [
|
|
11194
11469
|
`${error3.request.method} ${error3.request.url}`,
|
|
11195
|
-
formatHeaders(error3.request.headers)
|
|
11470
|
+
formatHeaders(error3.request.headers, redactString)
|
|
11196
11471
|
].filter((line) => line.length > 0);
|
|
11197
11472
|
if (error3.request.body !== void 0) {
|
|
11198
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11473
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
11199
11474
|
}
|
|
11200
11475
|
return [
|
|
11201
11476
|
"Request:",
|
|
@@ -11203,9 +11478,9 @@ function formatHttpTranscript(error3) {
|
|
|
11203
11478
|
"",
|
|
11204
11479
|
"Response:",
|
|
11205
11480
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
11206
|
-
formatHeaders(error3.response.headers),
|
|
11481
|
+
formatHeaders(error3.response.headers, redactString),
|
|
11207
11482
|
"",
|
|
11208
|
-
formatBody(error3.response.body)
|
|
11483
|
+
formatBody(error3.response.body, redactString)
|
|
11209
11484
|
].join("\n");
|
|
11210
11485
|
}
|
|
11211
11486
|
function resolveToolcraftVersion(version) {
|
|
@@ -11214,9 +11489,10 @@ function resolveToolcraftVersion(version) {
|
|
|
11214
11489
|
function buildReport(context) {
|
|
11215
11490
|
const env = context.env ?? process.env;
|
|
11216
11491
|
const error3 = context.error;
|
|
11492
|
+
const redactString = createReportStringRedactor(context, env);
|
|
11217
11493
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11218
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11219
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11494
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11495
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11220
11496
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11221
11497
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11222
11498
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11230,7 +11506,9 @@ function buildReport(context) {
|
|
|
11230
11506
|
`platform: ${process.platform} ${process.arch}`,
|
|
11231
11507
|
"",
|
|
11232
11508
|
"Argv",
|
|
11233
|
-
|
|
11509
|
+
redactString(
|
|
11510
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11511
|
+
),
|
|
11234
11512
|
"",
|
|
11235
11513
|
"Resolved Secrets",
|
|
11236
11514
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11239,19 +11517,19 @@ function buildReport(context) {
|
|
|
11239
11517
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11240
11518
|
"",
|
|
11241
11519
|
"Parsed Params",
|
|
11242
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11520
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11243
11521
|
"",
|
|
11244
11522
|
"Error",
|
|
11245
11523
|
`name: ${errorName}`,
|
|
11246
11524
|
`message: ${errorMessage}`,
|
|
11247
11525
|
"structured fields:",
|
|
11248
|
-
stableJson(structuredFields),
|
|
11526
|
+
redactString(stableJson(structuredFields)),
|
|
11249
11527
|
"",
|
|
11250
11528
|
"Stack",
|
|
11251
|
-
formatStackChain(error3)
|
|
11529
|
+
formatStackChain(error3, redactString)
|
|
11252
11530
|
];
|
|
11253
11531
|
if (hasHttpContext(error3)) {
|
|
11254
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11532
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11255
11533
|
}
|
|
11256
11534
|
return `${lines.join("\n")}
|
|
11257
11535
|
`;
|
|
@@ -11711,6 +11989,7 @@ ${rendered.join("\n")}`);
|
|
|
11711
11989
|
}
|
|
11712
11990
|
|
|
11713
11991
|
// ../toolcraft/src/cli.ts
|
|
11992
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11714
11993
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11715
11994
|
"params",
|
|
11716
11995
|
"secrets",
|
|
@@ -13144,7 +13423,7 @@ function createEnv2(values = process.env) {
|
|
|
13144
13423
|
}
|
|
13145
13424
|
};
|
|
13146
13425
|
}
|
|
13147
|
-
function
|
|
13426
|
+
function isPlainObject4(value) {
|
|
13148
13427
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13149
13428
|
}
|
|
13150
13429
|
function hasFieldValue(value) {
|
|
@@ -13253,7 +13532,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13253
13532
|
{ cause: error3 }
|
|
13254
13533
|
);
|
|
13255
13534
|
}
|
|
13256
|
-
if (!
|
|
13535
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13257
13536
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13258
13537
|
}
|
|
13259
13538
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
@@ -13272,7 +13551,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13272
13551
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13273
13552
|
);
|
|
13274
13553
|
}
|
|
13275
|
-
if (!
|
|
13554
|
+
if (!isPlainObject4(value)) {
|
|
13276
13555
|
throw new UserError(
|
|
13277
13556
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13278
13557
|
);
|
|
@@ -13315,8 +13594,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13315
13594
|
}
|
|
13316
13595
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13317
13596
|
}
|
|
13318
|
-
if (
|
|
13319
|
-
if (!
|
|
13597
|
+
if (isPlainObject4(expected)) {
|
|
13598
|
+
if (!isPlainObject4(actual)) {
|
|
13320
13599
|
return false;
|
|
13321
13600
|
}
|
|
13322
13601
|
return Object.entries(expected).every(
|
|
@@ -13379,9 +13658,9 @@ function createFixtureFetch(entries) {
|
|
|
13379
13658
|
};
|
|
13380
13659
|
}
|
|
13381
13660
|
function createFixtureFs(definition) {
|
|
13382
|
-
const fsDefinition =
|
|
13383
|
-
const readFileEntries =
|
|
13384
|
-
const existsEntries =
|
|
13661
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13662
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13663
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13385
13664
|
return {
|
|
13386
13665
|
readFile: async (filePath) => {
|
|
13387
13666
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13404,10 +13683,10 @@ function createFixtureFs(definition) {
|
|
|
13404
13683
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13405
13684
|
if (Array.isArray(definition)) {
|
|
13406
13685
|
for (const entry of definition) {
|
|
13407
|
-
if (!
|
|
13686
|
+
if (!isPlainObject4(entry)) {
|
|
13408
13687
|
continue;
|
|
13409
13688
|
}
|
|
13410
|
-
const explicitMatcher =
|
|
13689
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13411
13690
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13412
13691
|
Object.entries(entry).filter(
|
|
13413
13692
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13419,7 +13698,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13419
13698
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13420
13699
|
} else if (Object.keys(matcher).length === 0) {
|
|
13421
13700
|
matched = true;
|
|
13422
|
-
} else if (
|
|
13701
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13423
13702
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13424
13703
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13425
13704
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13440,7 +13719,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13440
13719
|
return Promise.resolve(null);
|
|
13441
13720
|
}
|
|
13442
13721
|
}
|
|
13443
|
-
if (
|
|
13722
|
+
if (isPlainObject4(definition)) {
|
|
13444
13723
|
const firstArg = args[0];
|
|
13445
13724
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13446
13725
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13452,7 +13731,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13452
13731
|
return Promise.resolve(null);
|
|
13453
13732
|
}
|
|
13454
13733
|
function createFixtureService(definition) {
|
|
13455
|
-
const methods =
|
|
13734
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13456
13735
|
return new Proxy(
|
|
13457
13736
|
{},
|
|
13458
13737
|
{
|
|
@@ -13550,7 +13829,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13550
13829
|
};
|
|
13551
13830
|
}
|
|
13552
13831
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13553
|
-
const scenarioServices =
|
|
13832
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13554
13833
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13555
13834
|
...Object.keys(services),
|
|
13556
13835
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13832,7 +14111,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13832
14111
|
if (itemSchema.kind !== "object") {
|
|
13833
14112
|
return value;
|
|
13834
14113
|
}
|
|
13835
|
-
if (!
|
|
14114
|
+
if (!isPlainObject4(value)) {
|
|
13836
14115
|
errors2.push({
|
|
13837
14116
|
path: displayPath,
|
|
13838
14117
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13867,7 +14146,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13867
14146
|
);
|
|
13868
14147
|
}
|
|
13869
14148
|
case "object": {
|
|
13870
|
-
if (!
|
|
14149
|
+
if (!isPlainObject4(value)) {
|
|
13871
14150
|
errors2.push({
|
|
13872
14151
|
path: displayPath,
|
|
13873
14152
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13898,7 +14177,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13898
14177
|
return result;
|
|
13899
14178
|
}
|
|
13900
14179
|
case "record": {
|
|
13901
|
-
if (!
|
|
14180
|
+
if (!isPlainObject4(value)) {
|
|
13902
14181
|
errors2.push({
|
|
13903
14182
|
path: displayPath,
|
|
13904
14183
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14324,10 +14603,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14324
14603
|
}
|
|
14325
14604
|
}
|
|
14326
14605
|
function isStringRecord(value) {
|
|
14327
|
-
return
|
|
14606
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14328
14607
|
}
|
|
14329
14608
|
function isHttpErrorLike(error3) {
|
|
14330
|
-
if (!
|
|
14609
|
+
if (!isPlainObject4(error3)) {
|
|
14331
14610
|
return false;
|
|
14332
14611
|
}
|
|
14333
14612
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14335,7 +14614,7 @@ function isHttpErrorLike(error3) {
|
|
|
14335
14614
|
}
|
|
14336
14615
|
const request = error3.request;
|
|
14337
14616
|
const response = error3.response;
|
|
14338
|
-
return
|
|
14617
|
+
return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
|
|
14339
14618
|
}
|
|
14340
14619
|
function hasTypedOptionalField(value, field, type2) {
|
|
14341
14620
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14344,7 +14623,7 @@ function isNonEmptyString(value) {
|
|
|
14344
14623
|
return typeof value === "string" && value.trim().length > 0;
|
|
14345
14624
|
}
|
|
14346
14625
|
function isProblemDetailsLike(body) {
|
|
14347
|
-
if (!
|
|
14626
|
+
if (!isPlainObject4(body)) {
|
|
14348
14627
|
return false;
|
|
14349
14628
|
}
|
|
14350
14629
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14365,11 +14644,11 @@ function isProblemDetailsLike(body) {
|
|
|
14365
14644
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14366
14645
|
}
|
|
14367
14646
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14368
|
-
if (!
|
|
14647
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14369
14648
|
return false;
|
|
14370
14649
|
}
|
|
14371
14650
|
return body.errors.every((error3) => {
|
|
14372
|
-
if (!
|
|
14651
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14373
14652
|
return false;
|
|
14374
14653
|
}
|
|
14375
14654
|
if ("path" in error3) {
|
|
@@ -14379,7 +14658,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14379
14658
|
}
|
|
14380
14659
|
}
|
|
14381
14660
|
if ("extensions" in error3) {
|
|
14382
|
-
if (!
|
|
14661
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14383
14662
|
return false;
|
|
14384
14663
|
}
|
|
14385
14664
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14427,23 +14706,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14427
14706
|
}).join("\n\n");
|
|
14428
14707
|
}
|
|
14429
14708
|
function formatHttpErrorBody(body) {
|
|
14430
|
-
|
|
14431
|
-
|
|
14709
|
+
const redactedBody = redactHttpBody(body);
|
|
14710
|
+
if (typeof redactedBody === "string") {
|
|
14711
|
+
return redactedBody;
|
|
14432
14712
|
}
|
|
14433
|
-
if (isProblemDetailsLike(
|
|
14434
|
-
return formatProblemDetailsBody(
|
|
14713
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
14714
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14435
14715
|
}
|
|
14436
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14437
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
14716
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
14717
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14438
14718
|
}
|
|
14439
|
-
const serialized = JSON.stringify(
|
|
14440
|
-
return serialized === void 0 ? String(
|
|
14719
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
14720
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14441
14721
|
}
|
|
14442
14722
|
function indentHttpErrorBlock(value) {
|
|
14443
14723
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14444
14724
|
}
|
|
14445
14725
|
function formatHttpHeaderValue(name, value) {
|
|
14446
|
-
return name
|
|
14726
|
+
return redactHttpHeaderValue(name, value);
|
|
14447
14727
|
}
|
|
14448
14728
|
function formatHttpErrorHeaders(headers) {
|
|
14449
14729
|
return Object.entries(headers).map(
|
|
@@ -14461,7 +14741,11 @@ function renderHttpError(error3, options) {
|
|
|
14461
14741
|
if (detailed) {
|
|
14462
14742
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14463
14743
|
if (error3.request.body !== void 0) {
|
|
14464
|
-
lines.push(
|
|
14744
|
+
lines.push(
|
|
14745
|
+
"Request body:",
|
|
14746
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
14747
|
+
""
|
|
14748
|
+
);
|
|
14465
14749
|
}
|
|
14466
14750
|
}
|
|
14467
14751
|
lines.push(
|
|
@@ -16616,11 +16900,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16616
16900
|
if (!resolvedId) {
|
|
16617
16901
|
return { status: "unknown", input };
|
|
16618
16902
|
}
|
|
16619
|
-
const
|
|
16620
|
-
if (!
|
|
16903
|
+
const config2 = registry[resolvedId];
|
|
16904
|
+
if (!config2) {
|
|
16621
16905
|
return { status: "unsupported", input, id: resolvedId };
|
|
16622
16906
|
}
|
|
16623
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
16907
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16624
16908
|
}
|
|
16625
16909
|
function getAgentConfig(agentId) {
|
|
16626
16910
|
const support = resolveAgentSupport(agentId);
|
|
@@ -17952,14 +18236,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17952
18236
|
throw new UnsupportedAgentError(agentId);
|
|
17953
18237
|
}
|
|
17954
18238
|
const scope = options.scope ?? "local";
|
|
17955
|
-
const
|
|
18239
|
+
const config2 = support.config;
|
|
17956
18240
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17957
18241
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17958
18242
|
}
|
|
17959
|
-
const skillDir = scope === "global" ?
|
|
18243
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17960
18244
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17961
18245
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17962
|
-
const displayPath = `${scope === "global" ?
|
|
18246
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17963
18247
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17964
18248
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17965
18249
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -18080,17 +18364,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
18080
18364
|
return targetPath;
|
|
18081
18365
|
}
|
|
18082
18366
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
18083
|
-
const
|
|
18084
|
-
if (!
|
|
18367
|
+
const config2 = getAgentConfig(agent);
|
|
18368
|
+
if (!config2) {
|
|
18085
18369
|
throwUnsupportedAgent(agent);
|
|
18086
18370
|
}
|
|
18087
18371
|
return {
|
|
18088
18372
|
displayPath: path22.join(
|
|
18089
|
-
scope === "global" ?
|
|
18373
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
18090
18374
|
TERMINAL_PILOT_SKILL_NAME
|
|
18091
18375
|
),
|
|
18092
18376
|
fullPath: path22.join(
|
|
18093
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18377
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
18094
18378
|
TERMINAL_PILOT_SKILL_NAME
|
|
18095
18379
|
)
|
|
18096
18380
|
};
|
|
@@ -19407,6 +19691,7 @@ function createTerminalPilotGroup() {
|
|
|
19407
19691
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19408
19692
|
|
|
19409
19693
|
// src/cli.ts
|
|
19694
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19410
19695
|
function normalizeArgv(argv) {
|
|
19411
19696
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19412
19697
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19430,8 +19715,8 @@ async function isDirectExecution(argv) {
|
|
|
19430
19715
|
try {
|
|
19431
19716
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19432
19717
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19433
|
-
|
|
19434
|
-
|
|
19718
|
+
realpath3(path23.resolve(entryPoint)),
|
|
19719
|
+
realpath3(modulePath)
|
|
19435
19720
|
]);
|
|
19436
19721
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19437
19722
|
} catch {
|