terminal-pilot 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1011 -452
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js +6 -4
- package/dist/commands/close-session.js.map +3 -3
- package/dist/commands/create-session.js +6 -4
- package/dist/commands/create-session.js.map +3 -3
- package/dist/commands/fill.js +6 -4
- package/dist/commands/fill.js.map +3 -3
- package/dist/commands/get-session.js +6 -4
- package/dist/commands/get-session.js.map +3 -3
- package/dist/commands/index.js +299 -159
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +251 -113
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +190 -62
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js +6 -4
- package/dist/commands/list-sessions.js.map +3 -3
- package/dist/commands/press-key.js +6 -4
- package/dist/commands/press-key.js.map +3 -3
- package/dist/commands/read-history.js +6 -4
- package/dist/commands/read-history.js.map +3 -3
- package/dist/commands/read-screen.js +6 -4
- package/dist/commands/read-screen.js.map +3 -3
- package/dist/commands/resize.js +6 -4
- package/dist/commands/resize.js.map +3 -3
- package/dist/commands/runtime.js +6 -4
- package/dist/commands/runtime.js.map +3 -3
- package/dist/commands/screenshot.js +17 -8
- package/dist/commands/screenshot.js.map +3 -3
- package/dist/commands/send-signal.js +6 -4
- package/dist/commands/send-signal.js.map +3 -3
- package/dist/commands/type.js +6 -4
- package/dist/commands/type.js.map +3 -3
- package/dist/commands/uninstall.js +226 -98
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js +6 -4
- package/dist/commands/wait-for-exit.js.map +3 -3
- package/dist/commands/wait-for.js +6 -4
- package/dist/commands/wait-for.js.map +3 -3
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +8 -0
- package/dist/errors.js.map +7 -0
- package/dist/index.js +8 -4
- package/dist/index.js.map +3 -3
- package/dist/terminal-pilot.js +6 -4
- package/dist/terminal-pilot.js.map +3 -3
- package/dist/terminal-session.js +6 -4
- package/dist/terminal-session.js.map +3 -3
- package/dist/testing/cli-repl.js +1011 -452
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +1011 -452
- package/dist/testing/qa-cli.js.map +4 -4
- package/node_modules/@poe-code/agent-skill-config/dist/apply.js +4 -1
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +1 -1
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +17 -9
- package/node_modules/@poe-code/agent-skill-config/dist/templates.js +4 -1
- package/package.json +2 -1
package/dist/testing/cli-repl.js
CHANGED
|
@@ -78,12 +78,12 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// src/cli.ts
|
|
81
|
-
import { realpath as
|
|
81
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
82
82
|
import path23 from "node:path";
|
|
83
83
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
84
84
|
|
|
85
85
|
// ../toolcraft/src/cli.ts
|
|
86
|
-
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as
|
|
86
|
+
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
87
87
|
import path14 from "node:path";
|
|
88
88
|
import {
|
|
89
89
|
Command as CommanderCommand,
|
|
@@ -92,7 +92,7 @@ import {
|
|
|
92
92
|
Option
|
|
93
93
|
} from "commander";
|
|
94
94
|
|
|
95
|
-
// ../design
|
|
95
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
96
96
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
97
97
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
98
98
|
return true;
|
|
@@ -106,7 +106,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
106
106
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// ../design
|
|
109
|
+
// ../toolcraft-design/src/components/color.ts
|
|
110
110
|
var reset = "\x1B[0m";
|
|
111
111
|
var ansiStyles = {
|
|
112
112
|
reset: { open: reset },
|
|
@@ -208,41 +208,135 @@ function createColor(styles = []) {
|
|
|
208
208
|
}
|
|
209
209
|
var color = createColor();
|
|
210
210
|
|
|
211
|
-
// ../design
|
|
212
|
-
var
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
number: (text5) => color.cyanBright(text5),
|
|
217
|
-
intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
|
|
218
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
219
|
-
errorSymbol: color.red("\u25A0"),
|
|
220
|
-
accent: (text5) => color.cyan(text5),
|
|
221
|
-
muted: (text5) => color.dim(text5),
|
|
222
|
-
success: (text5) => color.green(text5),
|
|
223
|
-
warning: (text5) => color.yellow(text5),
|
|
224
|
-
error: (text5) => color.red(text5),
|
|
225
|
-
info: (text5) => color.magenta(text5),
|
|
226
|
-
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
211
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
212
|
+
var brands = {
|
|
213
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
214
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
215
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
227
216
|
};
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
|
|
234
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
235
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
236
|
-
accent: (text5) => color.hex("#006699").bold(text5),
|
|
237
|
-
muted: (text5) => color.hex("#666666")(text5),
|
|
238
|
-
success: (text5) => color.hex("#008800")(text5),
|
|
239
|
-
warning: (text5) => color.hex("#cc6600")(text5),
|
|
240
|
-
error: (text5) => color.hex("#cc0000")(text5),
|
|
241
|
-
info: (text5) => color.hex("#a200ff")(text5),
|
|
242
|
-
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
217
|
+
|
|
218
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
219
|
+
var defaults = {
|
|
220
|
+
brand: "purple",
|
|
221
|
+
label: "Poe"
|
|
243
222
|
};
|
|
223
|
+
var config = { ...defaults };
|
|
224
|
+
var revision = 0;
|
|
225
|
+
var brandConfigured = false;
|
|
226
|
+
function configureTheme(patch) {
|
|
227
|
+
if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
|
|
228
|
+
throw new Error(`Unknown brand: ${patch.brand}`);
|
|
229
|
+
}
|
|
230
|
+
config = {
|
|
231
|
+
brand: patch.brand ?? config.brand,
|
|
232
|
+
label: patch.label ?? config.label
|
|
233
|
+
};
|
|
234
|
+
if (patch.brand !== void 0) {
|
|
235
|
+
brandConfigured = true;
|
|
236
|
+
}
|
|
237
|
+
revision += 1;
|
|
238
|
+
}
|
|
239
|
+
function getThemeConfig() {
|
|
240
|
+
return { ...config };
|
|
241
|
+
}
|
|
242
|
+
function getThemeRevision() {
|
|
243
|
+
return revision;
|
|
244
|
+
}
|
|
245
|
+
function isThemeBrandConfigured() {
|
|
246
|
+
return brandConfigured;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
250
|
+
var brand = brands.purple.primary;
|
|
251
|
+
function withStyles(palette, styles) {
|
|
252
|
+
return Object.defineProperty(palette, "styles", {
|
|
253
|
+
value: styles,
|
|
254
|
+
enumerable: false
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function brandColor(activeBrand, purple) {
|
|
258
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
259
|
+
}
|
|
260
|
+
function brandBackground(activeBrand, purple) {
|
|
261
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
262
|
+
}
|
|
263
|
+
function createPalette(activeBrand, mode) {
|
|
264
|
+
const isPurple = activeBrand.name === "purple";
|
|
265
|
+
if (mode === "light") {
|
|
266
|
+
const active2 = color.hex(activeBrand.primary);
|
|
267
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
268
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
269
|
+
return withStyles(
|
|
270
|
+
{
|
|
271
|
+
header: (text5) => active2.bold(text5),
|
|
272
|
+
divider: (text5) => color.hex("#666666")(text5),
|
|
273
|
+
prompt: (text5) => prompt2.bold(text5),
|
|
274
|
+
number: (text5) => number2.bold(text5),
|
|
275
|
+
intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
|
|
276
|
+
get resolvedSymbol() {
|
|
277
|
+
return active2("\u25C7");
|
|
278
|
+
},
|
|
279
|
+
get errorSymbol() {
|
|
280
|
+
return color.hex("#cc0000")("\u25A0");
|
|
281
|
+
},
|
|
282
|
+
accent: (text5) => prompt2.bold(text5),
|
|
283
|
+
muted: (text5) => color.hex("#666666")(text5),
|
|
284
|
+
success: (text5) => color.hex("#008800")(text5),
|
|
285
|
+
warning: (text5) => color.hex("#cc6600")(text5),
|
|
286
|
+
error: (text5) => color.hex("#cc0000")(text5),
|
|
287
|
+
info: (text5) => active2(text5),
|
|
288
|
+
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
292
|
+
muted: { fg: "#666666" },
|
|
293
|
+
success: { fg: "#008800" },
|
|
294
|
+
warning: { fg: "#cc6600" },
|
|
295
|
+
error: { fg: "#cc0000" },
|
|
296
|
+
info: { fg: activeBrand.primary }
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
301
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
302
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
303
|
+
const prompt = isPurple ? color.cyan : active;
|
|
304
|
+
const number = isPurple ? color.cyanBright : active;
|
|
305
|
+
return withStyles(
|
|
306
|
+
{
|
|
307
|
+
header: (text5) => activeBright.bold(text5),
|
|
308
|
+
divider: (text5) => color.dim(text5),
|
|
309
|
+
prompt: (text5) => prompt(text5),
|
|
310
|
+
number: (text5) => number(text5),
|
|
311
|
+
intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
|
|
312
|
+
get resolvedSymbol() {
|
|
313
|
+
return active("\u25C7");
|
|
314
|
+
},
|
|
315
|
+
get errorSymbol() {
|
|
316
|
+
return color.red("\u25A0");
|
|
317
|
+
},
|
|
318
|
+
accent: (text5) => prompt(text5),
|
|
319
|
+
muted: (text5) => color.dim(text5),
|
|
320
|
+
success: (text5) => color.green(text5),
|
|
321
|
+
warning: (text5) => color.yellow(text5),
|
|
322
|
+
error: (text5) => color.red(text5),
|
|
323
|
+
info: (text5) => active(text5),
|
|
324
|
+
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
328
|
+
muted: { dim: true },
|
|
329
|
+
success: { fg: "green" },
|
|
330
|
+
warning: { fg: "yellow" },
|
|
331
|
+
error: { fg: "red" },
|
|
332
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
var dark = createPalette(brands.purple, "dark");
|
|
337
|
+
var light = createPalette(brands.purple, "light");
|
|
244
338
|
|
|
245
|
-
// ../design
|
|
339
|
+
// ../toolcraft-design/src/tokens/typography.ts
|
|
246
340
|
var typography = {
|
|
247
341
|
bold: (text5) => color.bold(text5),
|
|
248
342
|
dim: (text5) => color.dim(text5),
|
|
@@ -251,14 +345,14 @@ var typography = {
|
|
|
251
345
|
strikethrough: (text5) => color.strikethrough(text5)
|
|
252
346
|
};
|
|
253
347
|
|
|
254
|
-
// ../design
|
|
348
|
+
// ../toolcraft-design/src/tokens/widths.ts
|
|
255
349
|
var widths = {
|
|
256
350
|
header: 60,
|
|
257
351
|
helpColumn: 24,
|
|
258
352
|
maxLine: 80
|
|
259
353
|
};
|
|
260
354
|
|
|
261
|
-
// ../design
|
|
355
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
262
356
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
263
357
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
264
358
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -279,7 +373,7 @@ function resetOutputFormatCache() {
|
|
|
279
373
|
cached = void 0;
|
|
280
374
|
}
|
|
281
375
|
|
|
282
|
-
// ../design
|
|
376
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
283
377
|
function detectThemeFromEnv(env) {
|
|
284
378
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
285
379
|
if (typeof apple === "string") {
|
|
@@ -316,17 +410,30 @@ function resolveThemeName(env = process.env) {
|
|
|
316
410
|
}
|
|
317
411
|
return "dark";
|
|
318
412
|
}
|
|
319
|
-
var
|
|
413
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
414
|
+
var cachedRevision = -1;
|
|
320
415
|
function getTheme(env) {
|
|
416
|
+
const themeName = resolveThemeName(env);
|
|
417
|
+
const config2 = getThemeConfig();
|
|
418
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
419
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
420
|
+
const revision2 = getThemeRevision();
|
|
421
|
+
if (revision2 !== cachedRevision) {
|
|
422
|
+
themeCache.clear();
|
|
423
|
+
cachedRevision = revision2;
|
|
424
|
+
}
|
|
425
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
426
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
321
427
|
if (cachedTheme) {
|
|
322
428
|
return cachedTheme;
|
|
323
429
|
}
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
430
|
+
const activeBrand = brands[activeBrandName];
|
|
431
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
432
|
+
themeCache.set(cacheKey, theme);
|
|
433
|
+
return theme;
|
|
327
434
|
}
|
|
328
435
|
|
|
329
|
-
// ../design
|
|
436
|
+
// ../toolcraft-design/src/components/text.ts
|
|
330
437
|
function renderMarkdownInline(content) {
|
|
331
438
|
return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
332
439
|
}
|
|
@@ -442,7 +549,7 @@ var text = {
|
|
|
442
549
|
}
|
|
443
550
|
};
|
|
444
551
|
|
|
445
|
-
// ../design
|
|
552
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
446
553
|
var symbols = {
|
|
447
554
|
get info() {
|
|
448
555
|
const format = resolveOutputFormat();
|
|
@@ -496,12 +603,12 @@ var symbols = {
|
|
|
496
603
|
}
|
|
497
604
|
};
|
|
498
605
|
|
|
499
|
-
// ../design
|
|
606
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
500
607
|
function stripAnsi2(value) {
|
|
501
608
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
502
609
|
}
|
|
503
610
|
|
|
504
|
-
// ../design
|
|
611
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
505
612
|
function renderMarkdownInline2(value) {
|
|
506
613
|
return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
507
614
|
}
|
|
@@ -628,7 +735,7 @@ var log = {
|
|
|
628
735
|
error
|
|
629
736
|
};
|
|
630
737
|
|
|
631
|
-
// ../design
|
|
738
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
632
739
|
function createLogger(emitter) {
|
|
633
740
|
const emit = (level, message2) => {
|
|
634
741
|
if (emitter) {
|
|
@@ -689,7 +796,7 @@ function createLogger(emitter) {
|
|
|
689
796
|
}
|
|
690
797
|
var logger = createLogger();
|
|
691
798
|
|
|
692
|
-
// ../design
|
|
799
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
693
800
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
694
801
|
function normalizeInline(value) {
|
|
695
802
|
return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
@@ -865,7 +972,7 @@ function formatOptionList(options) {
|
|
|
865
972
|
});
|
|
866
973
|
}
|
|
867
974
|
|
|
868
|
-
// ../design
|
|
975
|
+
// ../toolcraft-design/src/components/help-formatter-plain.ts
|
|
869
976
|
var help_formatter_plain_exports = {};
|
|
870
977
|
__export(help_formatter_plain_exports, {
|
|
871
978
|
formatColumns: () => formatColumns2,
|
|
@@ -1002,7 +1109,7 @@ function formatOptionList2(options) {
|
|
|
1002
1109
|
});
|
|
1003
1110
|
}
|
|
1004
1111
|
|
|
1005
|
-
// ../design
|
|
1112
|
+
// ../toolcraft-design/src/components/table.ts
|
|
1006
1113
|
var reset2 = "\x1B[0m";
|
|
1007
1114
|
var ellipsis = "\u2026";
|
|
1008
1115
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -1286,7 +1393,7 @@ function renderTable(options) {
|
|
|
1286
1393
|
}
|
|
1287
1394
|
}
|
|
1288
1395
|
|
|
1289
|
-
// ../design
|
|
1396
|
+
// ../toolcraft-design/src/components/detail-card.ts
|
|
1290
1397
|
function wrap(value, width) {
|
|
1291
1398
|
const lines = [];
|
|
1292
1399
|
for (const paragraph of value.split("\n")) {
|
|
@@ -1349,7 +1456,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1349
1456
|
return blocks.join("\n\n");
|
|
1350
1457
|
}
|
|
1351
1458
|
|
|
1352
|
-
// ../design
|
|
1459
|
+
// ../toolcraft-design/src/components/template.ts
|
|
1353
1460
|
var MAX_PARTIAL_DEPTH = 100;
|
|
1354
1461
|
var HTML_ESCAPE = {
|
|
1355
1462
|
"&": "&",
|
|
@@ -1761,22 +1868,22 @@ function hasProperty(value, key2) {
|
|
|
1761
1868
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1762
1869
|
}
|
|
1763
1870
|
|
|
1764
|
-
// ../design
|
|
1871
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1765
1872
|
import { spawn } from "node:child_process";
|
|
1766
1873
|
import process2 from "node:process";
|
|
1767
1874
|
|
|
1768
|
-
// ../design
|
|
1875
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1769
1876
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1770
1877
|
var storage = new AsyncLocalStorage2();
|
|
1771
1878
|
|
|
1772
|
-
// ../design
|
|
1879
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1773
1880
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1774
1881
|
|
|
1775
|
-
// ../design
|
|
1882
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1776
1883
|
import readline from "node:readline";
|
|
1777
1884
|
import { PassThrough } from "node:stream";
|
|
1778
1885
|
|
|
1779
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1780
1887
|
var REGION_HEADER = 1 << 0;
|
|
1781
1888
|
var REGION_LIST = 1 << 1;
|
|
1782
1889
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1785,10 +1892,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1785
1892
|
var REGION_TOAST = 1 << 5;
|
|
1786
1893
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1787
1894
|
|
|
1788
|
-
// ../design
|
|
1895
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1789
1896
|
import * as clack from "@clack/prompts";
|
|
1790
1897
|
|
|
1791
|
-
// ../design
|
|
1898
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1792
1899
|
import { isCancel } from "@clack/prompts";
|
|
1793
1900
|
function cancel(msg = "") {
|
|
1794
1901
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1799,7 +1906,7 @@ function cancel(msg = "") {
|
|
|
1799
1906
|
`);
|
|
1800
1907
|
}
|
|
1801
1908
|
|
|
1802
|
-
// ../design
|
|
1909
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1803
1910
|
function getVisibleWidth(value) {
|
|
1804
1911
|
return stripAnsi2(value).length;
|
|
1805
1912
|
}
|
|
@@ -1848,10 +1955,10 @@ function note(message2, title) {
|
|
|
1848
1955
|
`);
|
|
1849
1956
|
}
|
|
1850
1957
|
|
|
1851
|
-
// ../design
|
|
1958
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1852
1959
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1853
1960
|
|
|
1854
|
-
// ../design
|
|
1961
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1855
1962
|
async function select2(opts) {
|
|
1856
1963
|
return clack.select(opts);
|
|
1857
1964
|
}
|
|
@@ -1894,19 +2001,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1894
2001
|
};
|
|
1895
2002
|
|
|
1896
2003
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1897
|
-
function validateHumanInLoopOnDefine(
|
|
1898
|
-
const label = Array.isArray(
|
|
1899
|
-
if (
|
|
1900
|
-
throw new Error(`${label} '${
|
|
2004
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
2005
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
2006
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
2007
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
1901
2008
|
}
|
|
1902
|
-
if (
|
|
2009
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1903
2010
|
return;
|
|
1904
2011
|
}
|
|
1905
|
-
if (
|
|
1906
|
-
throw new Error(`${label} '${
|
|
2012
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
2013
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
1907
2014
|
}
|
|
1908
|
-
if (typeof
|
|
1909
|
-
throw new Error(`${label} '${
|
|
2015
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
2016
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1910
2017
|
}
|
|
1911
2018
|
}
|
|
1912
2019
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1982,12 +2089,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1982
2089
|
}
|
|
1983
2090
|
}
|
|
1984
2091
|
}
|
|
1985
|
-
function OneOf(
|
|
1986
|
-
assertValidBranches(
|
|
2092
|
+
function OneOf(config2) {
|
|
2093
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1987
2094
|
return {
|
|
1988
2095
|
kind: "oneOf",
|
|
1989
|
-
discriminator:
|
|
1990
|
-
branches:
|
|
2096
|
+
discriminator: config2.discriminator,
|
|
2097
|
+
branches: config2.branches
|
|
1991
2098
|
};
|
|
1992
2099
|
}
|
|
1993
2100
|
|
|
@@ -2237,22 +2344,22 @@ function cloneStringArray(values) {
|
|
|
2237
2344
|
function cloneStringRecord(values) {
|
|
2238
2345
|
return values === void 0 ? void 0 : { ...values };
|
|
2239
2346
|
}
|
|
2240
|
-
function cloneMcpServerConfig(
|
|
2241
|
-
if (
|
|
2347
|
+
function cloneMcpServerConfig(config2) {
|
|
2348
|
+
if (config2 === void 0) {
|
|
2242
2349
|
return void 0;
|
|
2243
2350
|
}
|
|
2244
|
-
if (
|
|
2351
|
+
if (config2.transport === "stdio") {
|
|
2245
2352
|
return {
|
|
2246
2353
|
transport: "stdio",
|
|
2247
|
-
command:
|
|
2248
|
-
args: cloneStringArray(
|
|
2249
|
-
env: cloneStringRecord(
|
|
2354
|
+
command: config2.command,
|
|
2355
|
+
args: cloneStringArray(config2.args),
|
|
2356
|
+
env: cloneStringRecord(config2.env)
|
|
2250
2357
|
};
|
|
2251
2358
|
}
|
|
2252
2359
|
return {
|
|
2253
2360
|
transport: "http",
|
|
2254
|
-
url:
|
|
2255
|
-
headers: cloneStringRecord(
|
|
2361
|
+
url: config2.url,
|
|
2362
|
+
headers: cloneStringRecord(config2.headers)
|
|
2256
2363
|
};
|
|
2257
2364
|
}
|
|
2258
2365
|
function cloneRenameMap(rename5) {
|
|
@@ -2493,57 +2600,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2493
2600
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2494
2601
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2495
2602
|
}
|
|
2496
|
-
function createBaseCommand(
|
|
2603
|
+
function createBaseCommand(config2) {
|
|
2497
2604
|
const command = {
|
|
2498
2605
|
kind: "command",
|
|
2499
|
-
name:
|
|
2500
|
-
description:
|
|
2501
|
-
aliases: [...
|
|
2502
|
-
positional: [...
|
|
2503
|
-
params:
|
|
2504
|
-
secrets: cloneSecrets(
|
|
2505
|
-
scope: resolveCommandScope(
|
|
2506
|
-
confirm:
|
|
2507
|
-
humanInLoop:
|
|
2508
|
-
requires: cloneRequires(
|
|
2509
|
-
handler:
|
|
2510
|
-
render:
|
|
2606
|
+
name: config2.name,
|
|
2607
|
+
description: config2.description,
|
|
2608
|
+
aliases: [...config2.aliases ?? []],
|
|
2609
|
+
positional: [...config2.positional ?? []],
|
|
2610
|
+
params: config2.params,
|
|
2611
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2612
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
2613
|
+
confirm: config2.confirm ?? false,
|
|
2614
|
+
humanInLoop: config2.humanInLoop,
|
|
2615
|
+
requires: cloneRequires(config2.requires),
|
|
2616
|
+
handler: config2.handler,
|
|
2617
|
+
render: config2.render
|
|
2511
2618
|
};
|
|
2512
2619
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2513
2620
|
value: {
|
|
2514
|
-
scope: cloneScope(
|
|
2515
|
-
humanInLoop:
|
|
2516
|
-
secrets: cloneSecrets(
|
|
2517
|
-
requires: cloneRequires(
|
|
2621
|
+
scope: cloneScope(config2.scope),
|
|
2622
|
+
humanInLoop: config2.humanInLoop,
|
|
2623
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2624
|
+
requires: cloneRequires(config2.requires),
|
|
2518
2625
|
sourcePath: inferCommandSourcePath()
|
|
2519
2626
|
}
|
|
2520
2627
|
});
|
|
2521
2628
|
return command;
|
|
2522
2629
|
}
|
|
2523
|
-
function createBaseGroup(
|
|
2630
|
+
function createBaseGroup(config2) {
|
|
2524
2631
|
const group = {
|
|
2525
2632
|
kind: "group",
|
|
2526
|
-
name:
|
|
2527
|
-
description:
|
|
2528
|
-
aliases: [...
|
|
2529
|
-
scope: resolveGroupScope(
|
|
2530
|
-
humanInLoop:
|
|
2531
|
-
secrets: cloneSecrets(
|
|
2532
|
-
requires: cloneRequires(
|
|
2633
|
+
name: config2.name,
|
|
2634
|
+
description: config2.description,
|
|
2635
|
+
aliases: [...config2.aliases ?? []],
|
|
2636
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
2637
|
+
humanInLoop: config2.humanInLoop,
|
|
2638
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2639
|
+
requires: cloneRequires(config2.requires),
|
|
2533
2640
|
children: [],
|
|
2534
2641
|
default: void 0
|
|
2535
2642
|
};
|
|
2536
2643
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2537
2644
|
value: {
|
|
2538
|
-
mcp: cloneMcpServerConfig(
|
|
2539
|
-
scope: cloneScope(
|
|
2540
|
-
humanInLoop:
|
|
2541
|
-
secrets: cloneSecrets(
|
|
2542
|
-
tools: cloneStringArray(
|
|
2543
|
-
rename: cloneRenameMap(
|
|
2544
|
-
requires: cloneRequires(
|
|
2545
|
-
children: [...
|
|
2546
|
-
default:
|
|
2645
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
2646
|
+
scope: cloneScope(config2.scope),
|
|
2647
|
+
humanInLoop: config2.humanInLoop,
|
|
2648
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2649
|
+
tools: cloneStringArray(config2.tools),
|
|
2650
|
+
rename: cloneRenameMap(config2.rename),
|
|
2651
|
+
requires: cloneRequires(config2.requires),
|
|
2652
|
+
children: [...config2.children],
|
|
2653
|
+
default: config2.default
|
|
2547
2654
|
}
|
|
2548
2655
|
});
|
|
2549
2656
|
return group;
|
|
@@ -2646,10 +2753,10 @@ function materializeNode(node, inherited) {
|
|
|
2646
2753
|
}
|
|
2647
2754
|
return materializeGroup(node, inherited);
|
|
2648
2755
|
}
|
|
2649
|
-
function defineCommand(
|
|
2650
|
-
validateHumanInLoopOnDefine(
|
|
2756
|
+
function defineCommand(config2) {
|
|
2757
|
+
validateHumanInLoopOnDefine(config2);
|
|
2651
2758
|
return materializeCommand(
|
|
2652
|
-
createBaseCommand(
|
|
2759
|
+
createBaseCommand(config2),
|
|
2653
2760
|
{
|
|
2654
2761
|
scope: void 0,
|
|
2655
2762
|
humanInLoop: void 0,
|
|
@@ -2658,10 +2765,10 @@ function defineCommand(config) {
|
|
|
2658
2765
|
}
|
|
2659
2766
|
);
|
|
2660
2767
|
}
|
|
2661
|
-
function defineGroup(
|
|
2662
|
-
validateRenameMap(
|
|
2663
|
-
validateHumanInLoopOnDefine(
|
|
2664
|
-
return materializeGroup(createBaseGroup(
|
|
2768
|
+
function defineGroup(config2) {
|
|
2769
|
+
validateRenameMap(config2.rename);
|
|
2770
|
+
validateHumanInLoopOnDefine(config2);
|
|
2771
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2665
2772
|
scope: void 0,
|
|
2666
2773
|
humanInLoop: void 0,
|
|
2667
2774
|
secrets: {},
|
|
@@ -2692,27 +2799,27 @@ function validateMachine(machine) {
|
|
|
2692
2799
|
if (!isRecord(machine)) {
|
|
2693
2800
|
throw new TypeError("State machine must be an object.");
|
|
2694
2801
|
}
|
|
2695
|
-
if (!isStateList(machine.states)) {
|
|
2802
|
+
if (!hasOwnRecordField(machine, "states") || !isStateList(machine.states)) {
|
|
2696
2803
|
throw new TypeError("State machine states must be a string array.");
|
|
2697
2804
|
}
|
|
2698
2805
|
const states = new Set(machine.states);
|
|
2699
|
-
if (typeof machine.initial !== "string") {
|
|
2806
|
+
if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
|
|
2700
2807
|
throw new TypeError("State machine initial must be a string.");
|
|
2701
2808
|
}
|
|
2702
2809
|
if (!states.has(machine.initial)) {
|
|
2703
2810
|
throw new Error(`Initial state "${machine.initial}" is not declared.`);
|
|
2704
2811
|
}
|
|
2705
|
-
if (!isRecord(machine.events)) {
|
|
2812
|
+
if (!hasOwnRecordField(machine, "events") || !isRecord(machine.events)) {
|
|
2706
2813
|
throw new TypeError("State machine events must be an object.");
|
|
2707
2814
|
}
|
|
2708
2815
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
2709
2816
|
if (!isRecord(event)) {
|
|
2710
2817
|
throw new TypeError(`Event "${eventName}" must be an object.`);
|
|
2711
2818
|
}
|
|
2712
|
-
if (event.from !== "*" && !isStateList(event.from)) {
|
|
2819
|
+
if (!hasOwnRecordField(event, "from") || event.from !== "*" && !isStateList(event.from)) {
|
|
2713
2820
|
throw new TypeError(`Event "${eventName}" has an invalid "from" definition.`);
|
|
2714
2821
|
}
|
|
2715
|
-
if (typeof event.to !== "string") {
|
|
2822
|
+
if (!hasOwnRecordField(event, "to") || typeof event.to !== "string") {
|
|
2716
2823
|
throw new TypeError(`Event "${eventName}" target state must be a string.`);
|
|
2717
2824
|
}
|
|
2718
2825
|
if (!states.has(event.to)) {
|
|
@@ -2727,6 +2834,9 @@ function validateMachine(machine) {
|
|
|
2727
2834
|
}
|
|
2728
2835
|
}
|
|
2729
2836
|
}
|
|
2837
|
+
function hasOwnRecordField(record, key2) {
|
|
2838
|
+
return Object.prototype.hasOwnProperty.call(record, key2);
|
|
2839
|
+
}
|
|
2730
2840
|
function eventsFromState(machine, fromState) {
|
|
2731
2841
|
const events = [];
|
|
2732
2842
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
@@ -2830,7 +2940,7 @@ import path3 from "node:path";
|
|
|
2830
2940
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2831
2941
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2832
2942
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2833
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2943
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2834
2944
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2835
2945
|
import path5 from "node:path";
|
|
2836
2946
|
|
|
@@ -2998,6 +3108,7 @@ function resolveEndpoint(options = {}) {
|
|
|
2998
3108
|
}
|
|
2999
3109
|
|
|
3000
3110
|
// ../task-list/src/backends/utils.ts
|
|
3111
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3001
3112
|
import path6 from "node:path";
|
|
3002
3113
|
function compareCreated(left, right) {
|
|
3003
3114
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
@@ -3018,9 +3129,8 @@ function applyOrder(entries, order) {
|
|
|
3018
3129
|
}
|
|
3019
3130
|
return entries.map((entry) => entry.task);
|
|
3020
3131
|
}
|
|
3021
|
-
var tmpFileCounter = 0;
|
|
3022
3132
|
function hasErrorCode(error3, code) {
|
|
3023
|
-
return !!error3 && typeof error3 === "object" && "code"
|
|
3133
|
+
return !!error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
|
|
3024
3134
|
}
|
|
3025
3135
|
function isRecord2(value) {
|
|
3026
3136
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -3067,18 +3177,22 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
3067
3177
|
}
|
|
3068
3178
|
}
|
|
3069
3179
|
async function writeAtomically(fs4, filePath, content) {
|
|
3070
|
-
const tempPath = `${filePath}
|
|
3071
|
-
|
|
3180
|
+
const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
|
|
3181
|
+
let tempCreated = false;
|
|
3072
3182
|
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
3073
3183
|
try {
|
|
3074
3184
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
3185
|
+
tempCreated = true;
|
|
3075
3186
|
await fs4.rename(tempPath, filePath);
|
|
3187
|
+
tempCreated = false;
|
|
3076
3188
|
} catch (error3) {
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3189
|
+
if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
|
|
3190
|
+
try {
|
|
3191
|
+
await fs4.unlink(tempPath);
|
|
3192
|
+
} catch (unlinkError) {
|
|
3193
|
+
if (!hasErrorCode(unlinkError, "ENOENT")) {
|
|
3194
|
+
throw unlinkError;
|
|
3195
|
+
}
|
|
3082
3196
|
}
|
|
3083
3197
|
}
|
|
3084
3198
|
throw error3;
|
|
@@ -3092,6 +3206,7 @@ async function withFileLock(fs4, lockPath, operation) {
|
|
|
3092
3206
|
break;
|
|
3093
3207
|
} catch (error3) {
|
|
3094
3208
|
if (!hasErrorCode(error3, "EEXIST")) {
|
|
3209
|
+
await fs4.unlink(lockPath).catch(() => void 0);
|
|
3095
3210
|
throw error3;
|
|
3096
3211
|
}
|
|
3097
3212
|
if (await removeAbandonedLock(fs4, lockPath)) {
|
|
@@ -4375,27 +4490,30 @@ function readFrontmatter(frontmatterContent, filePath) {
|
|
|
4375
4490
|
return parsed;
|
|
4376
4491
|
}
|
|
4377
4492
|
function assertValidTaskRecord(frontmatter, filePath, validStates) {
|
|
4378
|
-
if ("$schema"
|
|
4493
|
+
if (hasOwnTaskField(frontmatter, "$schema") && frontmatter.$schema !== TASK_SCHEMA_ID) {
|
|
4379
4494
|
throw malformedTask(filePath, "$schema");
|
|
4380
4495
|
}
|
|
4381
|
-
if ("kind"
|
|
4496
|
+
if (hasOwnTaskField(frontmatter, "kind") && frontmatter.kind !== TASK_KIND) {
|
|
4382
4497
|
throw malformedTask(filePath, "kind");
|
|
4383
4498
|
}
|
|
4384
|
-
if ("version"
|
|
4499
|
+
if (hasOwnTaskField(frontmatter, "version")) {
|
|
4385
4500
|
if (typeof frontmatter.version !== "number" || !Number.isInteger(frontmatter.version) || frontmatter.version !== TASK_VERSION) {
|
|
4386
4501
|
throw malformedTask(filePath, "version");
|
|
4387
4502
|
}
|
|
4388
4503
|
}
|
|
4389
|
-
if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
4504
|
+
if (!hasOwnTaskField(frontmatter, "name") || typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
4390
4505
|
throw malformedTask(filePath, "name");
|
|
4391
4506
|
}
|
|
4392
|
-
if (typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
|
|
4507
|
+
if (!hasOwnTaskField(frontmatter, "state") || typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
|
|
4393
4508
|
throw malformedTask(filePath, "state");
|
|
4394
4509
|
}
|
|
4395
|
-
if ("description"
|
|
4510
|
+
if (hasOwnTaskField(frontmatter, "description") && typeof frontmatter.description !== "string") {
|
|
4396
4511
|
throw malformedTask(filePath, "description");
|
|
4397
4512
|
}
|
|
4398
4513
|
}
|
|
4514
|
+
function hasOwnTaskField(frontmatter, key2) {
|
|
4515
|
+
return Object.prototype.hasOwnProperty.call(frontmatter, key2);
|
|
4516
|
+
}
|
|
4399
4517
|
function reservedFrontmatterKeys(mode) {
|
|
4400
4518
|
return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
|
|
4401
4519
|
}
|
|
@@ -4518,7 +4636,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4518
4636
|
}
|
|
4519
4637
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4520
4638
|
}
|
|
4521
|
-
function createdFrontmatter(
|
|
4639
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4522
4640
|
const frontmatter = mode !== "passthrough" ? {
|
|
4523
4641
|
$schema: TASK_SCHEMA_ID,
|
|
4524
4642
|
kind: TASK_KIND,
|
|
@@ -4530,7 +4648,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4530
4648
|
state: initialState
|
|
4531
4649
|
};
|
|
4532
4650
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4533
|
-
for (const [key2, value] of Object.entries(
|
|
4651
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4534
4652
|
if (!reservedKeys.has(key2)) {
|
|
4535
4653
|
setOwnValue(frontmatter, key2, value);
|
|
4536
4654
|
}
|
|
@@ -5244,7 +5362,8 @@ function parseQualifiedId3(qualifiedId) {
|
|
|
5244
5362
|
};
|
|
5245
5363
|
}
|
|
5246
5364
|
function descriptionFromTaskRecord(taskRecord) {
|
|
5247
|
-
|
|
5365
|
+
const description = getOwnEntry(taskRecord, "description");
|
|
5366
|
+
return typeof description === "string" ? description : "";
|
|
5248
5367
|
}
|
|
5249
5368
|
function metadataFromTaskRecord(taskRecord) {
|
|
5250
5369
|
const metadata = /* @__PURE__ */ Object.create(null);
|
|
@@ -5260,8 +5379,8 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5260
5379
|
list,
|
|
5261
5380
|
id,
|
|
5262
5381
|
qualifiedId: `${list}/${id}`,
|
|
5263
|
-
name: taskRecord
|
|
5264
|
-
state: taskRecord
|
|
5382
|
+
name: getOwnEntry(taskRecord, "name"),
|
|
5383
|
+
state: getOwnEntry(taskRecord, "state"),
|
|
5265
5384
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5266
5385
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5267
5386
|
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
@@ -5276,13 +5395,13 @@ function matchesFilter(task, filter) {
|
|
|
5276
5395
|
}
|
|
5277
5396
|
return true;
|
|
5278
5397
|
}
|
|
5279
|
-
function createTaskRecord(
|
|
5398
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5280
5399
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5281
5400
|
name: input.name,
|
|
5282
5401
|
state: initialState,
|
|
5283
5402
|
description: input.description ?? ""
|
|
5284
5403
|
});
|
|
5285
|
-
for (const [key2, value] of Object.entries(
|
|
5404
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5286
5405
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5287
5406
|
taskRecord[key2] = value;
|
|
5288
5407
|
}
|
|
@@ -5358,16 +5477,17 @@ function assertValidStoreRecord(store, filePath) {
|
|
|
5358
5477
|
if (!isRecord2(store)) {
|
|
5359
5478
|
throw malformedStore(filePath, "store");
|
|
5360
5479
|
}
|
|
5361
|
-
if (store
|
|
5480
|
+
if (getOwnEntry(store, "$schema") !== STORE_SCHEMA_ID) {
|
|
5362
5481
|
throw malformedStore(filePath, "$schema");
|
|
5363
5482
|
}
|
|
5364
|
-
if (store
|
|
5483
|
+
if (getOwnEntry(store, "kind") !== STORE_KIND) {
|
|
5365
5484
|
throw malformedStore(filePath, "kind");
|
|
5366
5485
|
}
|
|
5367
|
-
|
|
5486
|
+
const version = getOwnEntry(store, "version");
|
|
5487
|
+
if (typeof version !== "number" || !Number.isInteger(version) || version !== STORE_VERSION) {
|
|
5368
5488
|
throw malformedStore(filePath, "version");
|
|
5369
5489
|
}
|
|
5370
|
-
if (!isRecord2(store
|
|
5490
|
+
if (!isRecord2(getOwnEntry(store, "lists"))) {
|
|
5371
5491
|
throw malformedStore(filePath, "lists");
|
|
5372
5492
|
}
|
|
5373
5493
|
}
|
|
@@ -5375,29 +5495,38 @@ function assertValidTaskRecord2(taskRecord, list, id, validStates) {
|
|
|
5375
5495
|
if (!isRecord2(taskRecord)) {
|
|
5376
5496
|
throw malformedTask2(list, id, "task");
|
|
5377
5497
|
}
|
|
5378
|
-
if ("$schema"
|
|
5498
|
+
if (hasOwnTaskField2(taskRecord, "$schema") && getOwnEntry(taskRecord, "$schema") !== TASK_SCHEMA_ID2) {
|
|
5379
5499
|
throw malformedTask2(list, id, "$schema");
|
|
5380
5500
|
}
|
|
5381
|
-
if ("kind"
|
|
5501
|
+
if (hasOwnTaskField2(taskRecord, "kind") && getOwnEntry(taskRecord, "kind") !== TASK_KIND2) {
|
|
5382
5502
|
throw malformedTask2(list, id, "kind");
|
|
5383
5503
|
}
|
|
5384
|
-
if ("version"
|
|
5385
|
-
|
|
5504
|
+
if (hasOwnTaskField2(taskRecord, "version")) {
|
|
5505
|
+
const version = getOwnEntry(taskRecord, "version");
|
|
5506
|
+
if (typeof version !== "number" || !Number.isInteger(version) || version !== TASK_VERSION2) {
|
|
5386
5507
|
throw malformedTask2(list, id, "version");
|
|
5387
5508
|
}
|
|
5388
5509
|
}
|
|
5389
|
-
|
|
5510
|
+
const name = getOwnEntry(taskRecord, "name");
|
|
5511
|
+
if (!hasOwnTaskField2(taskRecord, "name") || typeof name !== "string" || name.length === 0) {
|
|
5390
5512
|
throw malformedTask2(list, id, "name");
|
|
5391
5513
|
}
|
|
5392
|
-
|
|
5514
|
+
const state = getOwnEntry(taskRecord, "state");
|
|
5515
|
+
if (!hasOwnTaskField2(taskRecord, "state") || typeof state !== "string" || !validStates.has(state)) {
|
|
5393
5516
|
throw malformedTask2(list, id, "state");
|
|
5394
5517
|
}
|
|
5395
|
-
if ("description"
|
|
5518
|
+
if (hasOwnTaskField2(taskRecord, "description") && typeof getOwnEntry(taskRecord, "description") !== "string") {
|
|
5396
5519
|
throw malformedTask2(list, id, "description");
|
|
5397
5520
|
}
|
|
5398
5521
|
}
|
|
5522
|
+
function hasOwnTaskField2(taskRecord, key2) {
|
|
5523
|
+
return Object.prototype.hasOwnProperty.call(taskRecord, key2);
|
|
5524
|
+
}
|
|
5525
|
+
function getOwnEntry(record, key2) {
|
|
5526
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
5527
|
+
}
|
|
5399
5528
|
function validateStoreEntries(store, filePath, validStates) {
|
|
5400
|
-
const lists = store
|
|
5529
|
+
const lists = getOwnEntry(store, "lists");
|
|
5401
5530
|
if (!isRecord2(lists)) {
|
|
5402
5531
|
throw malformedStore(filePath, "lists");
|
|
5403
5532
|
}
|
|
@@ -5437,10 +5566,11 @@ async function readStore(fs4, filePath, validStates) {
|
|
|
5437
5566
|
};
|
|
5438
5567
|
}
|
|
5439
5568
|
function getListsRecord(store) {
|
|
5440
|
-
|
|
5569
|
+
const lists = getOwnEntry(store, "lists");
|
|
5570
|
+
return isRecord2(lists) ? lists : {};
|
|
5441
5571
|
}
|
|
5442
5572
|
function getListRecord(store, list) {
|
|
5443
|
-
const listRecord = getListsRecord(store)
|
|
5573
|
+
const listRecord = getOwnEntry(getListsRecord(store), list);
|
|
5444
5574
|
return isRecord2(listRecord) ? listRecord : void 0;
|
|
5445
5575
|
}
|
|
5446
5576
|
function getTaskRecord(store, list, id) {
|
|
@@ -5733,7 +5863,7 @@ async function yamlFileBackend(deps) {
|
|
|
5733
5863
|
const result = [];
|
|
5734
5864
|
const listNames = sortStrings(Object.keys(getListsRecord(store)));
|
|
5735
5865
|
for (const listName of listNames) {
|
|
5736
|
-
const listRecord = getListsRecord(store)
|
|
5866
|
+
const listRecord = getOwnEntry(getListsRecord(store), listName);
|
|
5737
5867
|
if (!isRecord2(listRecord)) continue;
|
|
5738
5868
|
const entries = Object.entries(listRecord).map(([id, taskRecord]) => ({
|
|
5739
5869
|
task: createTask2(listName, id, taskRecord, deps.path),
|
|
@@ -6367,8 +6497,8 @@ function createHandlerContext(command, params17) {
|
|
|
6367
6497
|
function createFs() {
|
|
6368
6498
|
return {
|
|
6369
6499
|
readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
|
|
6370
|
-
writeFile: async (path24, contents) => {
|
|
6371
|
-
await writeFile2(path24, contents);
|
|
6500
|
+
writeFile: async (path24, contents, options) => {
|
|
6501
|
+
await writeFile2(path24, contents, options);
|
|
6372
6502
|
},
|
|
6373
6503
|
exists: async (path24) => {
|
|
6374
6504
|
try {
|
|
@@ -6656,17 +6786,17 @@ function isMissingStateError(error3) {
|
|
|
6656
6786
|
}
|
|
6657
6787
|
|
|
6658
6788
|
// ../toolcraft/src/error-report.ts
|
|
6659
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6660
|
-
import { randomUUID as
|
|
6789
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6790
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
6661
6791
|
import os from "node:os";
|
|
6662
6792
|
import path13 from "node:path";
|
|
6663
6793
|
import { CommanderError } from "commander";
|
|
6664
6794
|
|
|
6665
6795
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6666
6796
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6667
|
-
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6797
|
+
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6668
6798
|
import path12 from "node:path";
|
|
6669
|
-
import { createHash as createHash3, randomUUID as
|
|
6799
|
+
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
6670
6800
|
|
|
6671
6801
|
// ../tiny-mcp-client/src/internal.ts
|
|
6672
6802
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6677,7 +6807,7 @@ import crypto from "node:crypto";
|
|
|
6677
6807
|
import path11 from "node:path";
|
|
6678
6808
|
|
|
6679
6809
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6680
|
-
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6810
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
|
|
6681
6811
|
import { promises as fs } from "node:fs";
|
|
6682
6812
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6683
6813
|
import path10 from "node:path";
|
|
@@ -6688,7 +6818,6 @@ var ENCRYPTION_KEY_BYTES = 32;
|
|
|
6688
6818
|
var ENCRYPTION_IV_BYTES = 12;
|
|
6689
6819
|
var ENCRYPTION_AUTH_TAG_BYTES = 16;
|
|
6690
6820
|
var ENCRYPTION_FILE_MODE = 384;
|
|
6691
|
-
var temporaryFileSequence = 0;
|
|
6692
6821
|
var EncryptedFileStore = class {
|
|
6693
6822
|
fs;
|
|
6694
6823
|
filePath;
|
|
@@ -6720,7 +6849,7 @@ var EncryptedFileStore = class {
|
|
|
6720
6849
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6721
6850
|
}
|
|
6722
6851
|
async get() {
|
|
6723
|
-
await this.
|
|
6852
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6724
6853
|
let rawDocument;
|
|
6725
6854
|
try {
|
|
6726
6855
|
rawDocument = await this.fs.readFile(this.filePath, "utf8");
|
|
@@ -6751,7 +6880,7 @@ var EncryptedFileStore = class {
|
|
|
6751
6880
|
}
|
|
6752
6881
|
}
|
|
6753
6882
|
async set(value) {
|
|
6754
|
-
await this.
|
|
6883
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6755
6884
|
const key2 = await this.getEncryptionKey();
|
|
6756
6885
|
const iv = this.getRandomBytes(ENCRYPTION_IV_BYTES);
|
|
6757
6886
|
const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key2, iv);
|
|
@@ -6767,25 +6896,28 @@ var EncryptedFileStore = class {
|
|
|
6767
6896
|
ciphertext: ciphertext.toString("base64")
|
|
6768
6897
|
};
|
|
6769
6898
|
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6770
|
-
await this.
|
|
6771
|
-
const temporaryPath = `${this.filePath}.${process.pid}.${
|
|
6899
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6900
|
+
const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
6901
|
+
let temporaryCreated = false;
|
|
6772
6902
|
try {
|
|
6903
|
+
await this.assertCredentialPathHasNoSymbolicLinks(temporaryPath);
|
|
6773
6904
|
await this.fs.writeFile(temporaryPath, JSON.stringify(document), {
|
|
6774
6905
|
encoding: "utf8",
|
|
6775
6906
|
flag: "wx",
|
|
6776
6907
|
mode: ENCRYPTION_FILE_MODE
|
|
6777
6908
|
});
|
|
6909
|
+
temporaryCreated = true;
|
|
6778
6910
|
await this.fs.chmod(temporaryPath, ENCRYPTION_FILE_MODE);
|
|
6779
6911
|
await this.fs.rename(temporaryPath, this.filePath);
|
|
6780
6912
|
} catch (error3) {
|
|
6781
|
-
if (!isAlreadyExistsError(error3)) {
|
|
6913
|
+
if (temporaryCreated || !isAlreadyExistsError(error3)) {
|
|
6782
6914
|
await removeIfPresent(this.fs, temporaryPath).catch(() => void 0);
|
|
6783
6915
|
}
|
|
6784
6916
|
throw error3;
|
|
6785
6917
|
}
|
|
6786
6918
|
}
|
|
6787
6919
|
async delete() {
|
|
6788
|
-
await this.
|
|
6920
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6789
6921
|
try {
|
|
6790
6922
|
await this.fs.unlink(this.filePath);
|
|
6791
6923
|
} catch (error3) {
|
|
@@ -6794,8 +6926,8 @@ var EncryptedFileStore = class {
|
|
|
6794
6926
|
}
|
|
6795
6927
|
}
|
|
6796
6928
|
}
|
|
6797
|
-
async
|
|
6798
|
-
const resolvedPath = path10.resolve(
|
|
6929
|
+
async assertCredentialPathHasNoSymbolicLinks(targetPath) {
|
|
6930
|
+
const resolvedPath = path10.resolve(targetPath);
|
|
6799
6931
|
const protectedPaths = getProtectedCredentialPaths(
|
|
6800
6932
|
resolvedPath,
|
|
6801
6933
|
this.symbolicLinkCheckStartPath
|
|
@@ -6860,9 +6992,6 @@ async function removeIfPresent(fileSystem, filePath) {
|
|
|
6860
6992
|
}
|
|
6861
6993
|
}
|
|
6862
6994
|
}
|
|
6863
|
-
function isAlreadyExistsError(error3) {
|
|
6864
|
-
return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "EEXIST";
|
|
6865
|
-
}
|
|
6866
6995
|
function defaultMachineIdentity() {
|
|
6867
6996
|
return {
|
|
6868
6997
|
hostname: hostname(),
|
|
@@ -6900,17 +7029,21 @@ function parseEncryptedDocument(raw) {
|
|
|
6900
7029
|
if (!isRecord4(parsed)) {
|
|
6901
7030
|
return null;
|
|
6902
7031
|
}
|
|
6903
|
-
|
|
7032
|
+
const version = getOwnEntry2(parsed, "version");
|
|
7033
|
+
const iv = getOwnEntry2(parsed, "iv");
|
|
7034
|
+
const authTag = getOwnEntry2(parsed, "authTag");
|
|
7035
|
+
const ciphertext = getOwnEntry2(parsed, "ciphertext");
|
|
7036
|
+
if (version !== ENCRYPTION_VERSION) {
|
|
6904
7037
|
return null;
|
|
6905
7038
|
}
|
|
6906
|
-
if (typeof
|
|
7039
|
+
if (typeof iv !== "string" || typeof authTag !== "string" || typeof ciphertext !== "string") {
|
|
6907
7040
|
return null;
|
|
6908
7041
|
}
|
|
6909
7042
|
return {
|
|
6910
|
-
version
|
|
6911
|
-
iv
|
|
6912
|
-
authTag
|
|
6913
|
-
ciphertext
|
|
7043
|
+
version,
|
|
7044
|
+
iv,
|
|
7045
|
+
authTag,
|
|
7046
|
+
ciphertext
|
|
6914
7047
|
};
|
|
6915
7048
|
} catch {
|
|
6916
7049
|
return null;
|
|
@@ -6919,9 +7052,17 @@ function parseEncryptedDocument(raw) {
|
|
|
6919
7052
|
function isRecord4(value) {
|
|
6920
7053
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
6921
7054
|
}
|
|
7055
|
+
function getOwnEntry2(record, key2) {
|
|
7056
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7057
|
+
}
|
|
6922
7058
|
function isNotFoundError(error3) {
|
|
6923
7059
|
return Boolean(
|
|
6924
|
-
error3 && typeof error3 === "object" && "code"
|
|
7060
|
+
error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT"
|
|
7061
|
+
);
|
|
7062
|
+
}
|
|
7063
|
+
function isAlreadyExistsError(error3) {
|
|
7064
|
+
return Boolean(
|
|
7065
|
+
error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST"
|
|
6925
7066
|
);
|
|
6926
7067
|
}
|
|
6927
7068
|
|
|
@@ -6943,8 +7084,8 @@ var KeychainStore = class {
|
|
|
6943
7084
|
["find-generic-password", "-s", this.service, "-a", this.account, "-w"],
|
|
6944
7085
|
"read secret from macOS Keychain"
|
|
6945
7086
|
);
|
|
6946
|
-
if (result
|
|
6947
|
-
return stripTrailingLineBreak(result
|
|
7087
|
+
if (getCommandExitCode(result) === 0) {
|
|
7088
|
+
return stripTrailingLineBreak(getCommandOutput(result, "stdout"));
|
|
6948
7089
|
}
|
|
6949
7090
|
if (isKeychainEntryNotFound(result)) {
|
|
6950
7091
|
return null;
|
|
@@ -6968,7 +7109,7 @@ var KeychainStore = class {
|
|
|
6968
7109
|
"store secret in macOS Keychain",
|
|
6969
7110
|
{ stdin: value }
|
|
6970
7111
|
);
|
|
6971
|
-
if (result
|
|
7112
|
+
if (getCommandExitCode(result) !== 0) {
|
|
6972
7113
|
throw createSecurityCliFailure("store secret in macOS Keychain", result);
|
|
6973
7114
|
}
|
|
6974
7115
|
}
|
|
@@ -6977,7 +7118,7 @@ var KeychainStore = class {
|
|
|
6977
7118
|
["delete-generic-password", "-s", this.service, "-a", this.account],
|
|
6978
7119
|
"delete secret from macOS Keychain"
|
|
6979
7120
|
);
|
|
6980
|
-
if (result
|
|
7121
|
+
if (getCommandExitCode(result) === 0 || isKeychainEntryNotFound(result)) {
|
|
6981
7122
|
return;
|
|
6982
7123
|
}
|
|
6983
7124
|
throw createSecurityCliFailure("delete secret from macOS Keychain", result);
|
|
@@ -7056,16 +7197,28 @@ function stripTrailingLineBreak(value) {
|
|
|
7056
7197
|
return value;
|
|
7057
7198
|
}
|
|
7058
7199
|
function isKeychainEntryNotFound(result) {
|
|
7059
|
-
return result
|
|
7200
|
+
return getCommandExitCode(result) === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
|
|
7060
7201
|
}
|
|
7061
7202
|
function createSecurityCliFailure(operation, result) {
|
|
7062
|
-
const
|
|
7203
|
+
const exitCode = getCommandExitCode(result);
|
|
7204
|
+
const details = getCommandOutput(result, "stderr").trim() || getCommandOutput(result, "stdout").trim();
|
|
7063
7205
|
if (details) {
|
|
7064
7206
|
return new Error(
|
|
7065
|
-
`Failed to ${operation}: security exited with code ${
|
|
7207
|
+
`Failed to ${operation}: security exited with code ${exitCode}: ${details}`
|
|
7066
7208
|
);
|
|
7067
7209
|
}
|
|
7068
|
-
return new Error(`Failed to ${operation}: security exited with code ${
|
|
7210
|
+
return new Error(`Failed to ${operation}: security exited with code ${exitCode}`);
|
|
7211
|
+
}
|
|
7212
|
+
function getCommandExitCode(result) {
|
|
7213
|
+
const value = getOwnEntry3(result, "exitCode");
|
|
7214
|
+
return typeof value === "number" && Number.isInteger(value) ? value : 1;
|
|
7215
|
+
}
|
|
7216
|
+
function getCommandOutput(result, key2) {
|
|
7217
|
+
const value = getOwnEntry3(result, key2);
|
|
7218
|
+
return typeof value === "string" ? value : "";
|
|
7219
|
+
}
|
|
7220
|
+
function getOwnEntry3(record, key2) {
|
|
7221
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7069
7222
|
}
|
|
7070
7223
|
|
|
7071
7224
|
// ../auth-store/src/create-secret-store.ts
|
|
@@ -7098,7 +7251,7 @@ function createSecretStore(input) {
|
|
|
7098
7251
|
}
|
|
7099
7252
|
function resolveBackend(input) {
|
|
7100
7253
|
const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
|
|
7101
|
-
const configuredBackend = input.backend ?? input.env
|
|
7254
|
+
const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
|
|
7102
7255
|
if (configuredBackend === "keychain") {
|
|
7103
7256
|
return "keychain";
|
|
7104
7257
|
}
|
|
@@ -7107,6 +7260,9 @@ function resolveBackend(input) {
|
|
|
7107
7260
|
}
|
|
7108
7261
|
throw new Error(`Unsupported auth store backend: ${configuredBackend}`);
|
|
7109
7262
|
}
|
|
7263
|
+
function getOwnEnvValue(env, key2) {
|
|
7264
|
+
return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
|
|
7265
|
+
}
|
|
7110
7266
|
|
|
7111
7267
|
// ../mcp-oauth/src/resource-indicator.ts
|
|
7112
7268
|
function canonicalizeResourceIndicator(value) {
|
|
@@ -7160,8 +7316,13 @@ function createAuthStoreClientStore(options) {
|
|
|
7160
7316
|
return null;
|
|
7161
7317
|
}
|
|
7162
7318
|
const parsed = JSON.parse(value);
|
|
7163
|
-
|
|
7164
|
-
|
|
7319
|
+
const clientId = isObjectRecord(parsed) ? getOwnString(parsed, "clientId") : void 0;
|
|
7320
|
+
if (clientId !== void 0) {
|
|
7321
|
+
const client = { clientId };
|
|
7322
|
+
if (isObjectRecord(parsed) && Object.prototype.hasOwnProperty.call(parsed, "clientSecret")) {
|
|
7323
|
+
client.clientSecret = getOwnEntry4(parsed, "clientSecret");
|
|
7324
|
+
}
|
|
7325
|
+
return client;
|
|
7165
7326
|
}
|
|
7166
7327
|
throw new Error("Stored OAuth client must be a JSON object with clientId");
|
|
7167
7328
|
},
|
|
@@ -7175,19 +7336,24 @@ function createAuthStoreClientStore(options) {
|
|
|
7175
7336
|
}
|
|
7176
7337
|
};
|
|
7177
7338
|
}
|
|
7178
|
-
function createNamedSecretStore(key2, options,
|
|
7339
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
7179
7340
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
7180
|
-
const
|
|
7341
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7342
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
7181
7343
|
const fileStore = {
|
|
7182
7344
|
...options.fileStore,
|
|
7183
|
-
|
|
7184
|
-
|
|
7345
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7346
|
+
parsedFilePath.dir,
|
|
7347
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7348
|
+
),
|
|
7349
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7350
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
7185
7351
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7186
7352
|
};
|
|
7187
7353
|
const keychainStore = {
|
|
7188
7354
|
...options.keychainStore,
|
|
7189
|
-
service: options.keychainStore?.service ??
|
|
7190
|
-
account: `${options.keychainStore?.account ??
|
|
7355
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7356
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
7191
7357
|
};
|
|
7192
7358
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
7193
7359
|
}
|
|
@@ -7215,6 +7381,16 @@ function createIssuerSecretStore(issuer, options) {
|
|
|
7215
7381
|
}
|
|
7216
7382
|
);
|
|
7217
7383
|
}
|
|
7384
|
+
function isObjectRecord(value) {
|
|
7385
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7386
|
+
}
|
|
7387
|
+
function getOwnEntry4(record, key2) {
|
|
7388
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7389
|
+
}
|
|
7390
|
+
function getOwnString(record, key2) {
|
|
7391
|
+
const value = getOwnEntry4(record, key2);
|
|
7392
|
+
return typeof value === "string" ? value : void 0;
|
|
7393
|
+
}
|
|
7218
7394
|
|
|
7219
7395
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
7220
7396
|
import { URL as URL2 } from "node:url";
|
|
@@ -7240,17 +7416,30 @@ function parseAuthorizationState(value) {
|
|
|
7240
7416
|
try {
|
|
7241
7417
|
const decoded = Buffer.from(value, "base64url").toString("utf8");
|
|
7242
7418
|
const parsed = JSON.parse(decoded);
|
|
7243
|
-
if (parsed
|
|
7419
|
+
if (!isObjectRecord2(parsed)) {
|
|
7420
|
+
return null;
|
|
7421
|
+
}
|
|
7422
|
+
const version = getOwnEntry5(parsed, "v");
|
|
7423
|
+
const nonce = getOwnEntry5(parsed, "n");
|
|
7424
|
+
const issuer = getOwnEntry5(parsed, "i");
|
|
7425
|
+
const requireIssuer = getOwnEntry5(parsed, "r");
|
|
7426
|
+
if (version !== 1 || typeof nonce !== "string" || nonce.length === 0 || typeof issuer !== "string" || issuer.length === 0 || typeof requireIssuer !== "boolean") {
|
|
7244
7427
|
return null;
|
|
7245
7428
|
}
|
|
7246
7429
|
return {
|
|
7247
|
-
issuer
|
|
7248
|
-
requireIssuer
|
|
7430
|
+
issuer,
|
|
7431
|
+
requireIssuer
|
|
7249
7432
|
};
|
|
7250
7433
|
} catch {
|
|
7251
7434
|
return null;
|
|
7252
7435
|
}
|
|
7253
7436
|
}
|
|
7437
|
+
function isObjectRecord2(value) {
|
|
7438
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7439
|
+
}
|
|
7440
|
+
function getOwnEntry5(record, key2) {
|
|
7441
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7442
|
+
}
|
|
7254
7443
|
|
|
7255
7444
|
// ../mcp-oauth/src/client/loopback-authorization.ts
|
|
7256
7445
|
async function createLoopbackAuthorizationSession(options = {}) {
|
|
@@ -7527,22 +7716,26 @@ async function requestTokens(input) {
|
|
|
7527
7716
|
body: body.toString()
|
|
7528
7717
|
});
|
|
7529
7718
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
7530
|
-
|
|
7719
|
+
const accessToken = getOwnEntry6(payload, "access_token");
|
|
7720
|
+
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
7531
7721
|
throw new Error("OAuth token response missing access_token");
|
|
7532
7722
|
}
|
|
7533
|
-
const tokenType = normalizeBearerTokenType(payload
|
|
7723
|
+
const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
|
|
7534
7724
|
if (tokenType === null) {
|
|
7535
7725
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
7536
7726
|
}
|
|
7537
|
-
|
|
7727
|
+
const expiresIn = getOwnEntry6(payload, "expires_in");
|
|
7728
|
+
if (typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn < 0) {
|
|
7538
7729
|
throw new Error("OAuth token response has invalid expires_in");
|
|
7539
7730
|
}
|
|
7731
|
+
const refreshToken = getOwnEntry6(payload, "refresh_token");
|
|
7732
|
+
const scope = getOwnEntry6(payload, "scope");
|
|
7540
7733
|
return {
|
|
7541
|
-
accessToken
|
|
7542
|
-
refreshToken: typeof
|
|
7734
|
+
accessToken,
|
|
7735
|
+
refreshToken: typeof refreshToken === "string" && refreshToken.length > 0 ? refreshToken : void 0,
|
|
7543
7736
|
tokenType,
|
|
7544
|
-
expiresAt: typeof
|
|
7545
|
-
scope: typeof
|
|
7737
|
+
expiresAt: typeof expiresIn === "number" && Number.isFinite(expiresIn) ? input.now() + expiresIn * 1e3 : null,
|
|
7738
|
+
scope: typeof scope === "string" && scope.length > 0 ? scope : void 0
|
|
7546
7739
|
};
|
|
7547
7740
|
}
|
|
7548
7741
|
async function readOAuthJsonObjectResponse(response) {
|
|
@@ -7569,12 +7762,18 @@ async function readOAuthJsonObjectResponse(response) {
|
|
|
7569
7762
|
return record;
|
|
7570
7763
|
}
|
|
7571
7764
|
function readOAuthError(payload, fallbackError = "server_error") {
|
|
7765
|
+
const error3 = getOwnEntry6(payload, "error");
|
|
7766
|
+
const errorDescription = getOwnEntry6(payload, "error_description");
|
|
7767
|
+
const errorUri = getOwnEntry6(payload, "error_uri");
|
|
7572
7768
|
return {
|
|
7573
|
-
error: typeof
|
|
7574
|
-
error_description: typeof
|
|
7575
|
-
error_uri: typeof
|
|
7769
|
+
error: typeof error3 === "string" ? error3 : fallbackError,
|
|
7770
|
+
error_description: typeof errorDescription === "string" ? errorDescription : void 0,
|
|
7771
|
+
error_uri: typeof errorUri === "string" ? errorUri : void 0
|
|
7576
7772
|
};
|
|
7577
7773
|
}
|
|
7774
|
+
function getOwnEntry6(record, key2) {
|
|
7775
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7776
|
+
}
|
|
7578
7777
|
function createFallbackOAuthError(status) {
|
|
7579
7778
|
const error3 = status === 503 ? "temporarily_unavailable" : "server_error";
|
|
7580
7779
|
return new OAuthError({ error: error3 }, status);
|
|
@@ -7679,7 +7878,11 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7679
7878
|
while (true) {
|
|
7680
7879
|
try {
|
|
7681
7880
|
refreshedTokens = await refreshAccessToken({
|
|
7682
|
-
tokenEndpoint:
|
|
7881
|
+
tokenEndpoint: requireOwnString(
|
|
7882
|
+
discovery.authorizationServerMetadata,
|
|
7883
|
+
"token_endpoint",
|
|
7884
|
+
"Authorization server metadata"
|
|
7885
|
+
),
|
|
7683
7886
|
clientId: session.client.clientId,
|
|
7684
7887
|
clientSecret: session.client.clientSecret,
|
|
7685
7888
|
refreshToken: session.tokens.refreshToken,
|
|
@@ -7767,7 +7970,11 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7767
7970
|
});
|
|
7768
7971
|
const code = await loopback.waitForCode(authorizationUrl);
|
|
7769
7972
|
const tokens = await exchangeAuthorizationCode({
|
|
7770
|
-
tokenEndpoint:
|
|
7973
|
+
tokenEndpoint: requireOwnString(
|
|
7974
|
+
discovery.authorizationServerMetadata,
|
|
7975
|
+
"token_endpoint",
|
|
7976
|
+
"Authorization server metadata"
|
|
7977
|
+
),
|
|
7771
7978
|
clientId: resolvedClient.client.clientId,
|
|
7772
7979
|
clientSecret: resolvedClient.client.clientSecret,
|
|
7773
7980
|
code,
|
|
@@ -7820,7 +8027,10 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7820
8027
|
}
|
|
7821
8028
|
};
|
|
7822
8029
|
}
|
|
7823
|
-
const registrationEndpoint =
|
|
8030
|
+
const registrationEndpoint = getOwnString2(
|
|
8031
|
+
discovery.authorizationServerMetadata,
|
|
8032
|
+
"registration_endpoint"
|
|
8033
|
+
);
|
|
7824
8034
|
if (registrationEndpoint === void 0 && options.client.clientId !== void 0) {
|
|
7825
8035
|
return {
|
|
7826
8036
|
kind: "static",
|
|
@@ -7872,12 +8082,14 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7872
8082
|
body: JSON.stringify(registrationBody)
|
|
7873
8083
|
});
|
|
7874
8084
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
7875
|
-
|
|
8085
|
+
const clientId = getOwnString2(payload, "client_id");
|
|
8086
|
+
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
7876
8087
|
throw new Error("OAuth client registration response missing client_id");
|
|
7877
8088
|
}
|
|
8089
|
+
const clientSecret = getOwnString2(payload, "client_secret");
|
|
7878
8090
|
const registeredClient = {
|
|
7879
|
-
clientId
|
|
7880
|
-
clientSecret:
|
|
8091
|
+
clientId,
|
|
8092
|
+
clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
|
|
7881
8093
|
};
|
|
7882
8094
|
await saveRegisteredClient(discovery.authorizationServer, registeredClient);
|
|
7883
8095
|
return {
|
|
@@ -7903,12 +8115,13 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7903
8115
|
return null;
|
|
7904
8116
|
}
|
|
7905
8117
|
const client = await clientStore.load(issuer);
|
|
7906
|
-
|
|
8118
|
+
const normalizedClient = client === null ? null : normalizeStoredClient(client);
|
|
8119
|
+
if (client !== null && normalizedClient === null) {
|
|
7907
8120
|
await clientStore.clear(issuer);
|
|
7908
8121
|
return null;
|
|
7909
8122
|
}
|
|
7910
|
-
registeredClients.set(issuer,
|
|
7911
|
-
return
|
|
8123
|
+
registeredClients.set(issuer, normalizedClient);
|
|
8124
|
+
return normalizedClient;
|
|
7912
8125
|
}
|
|
7913
8126
|
async function saveRegisteredClient(issuer, client) {
|
|
7914
8127
|
registeredClients.set(issuer, client);
|
|
@@ -7924,7 +8137,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7924
8137
|
}
|
|
7925
8138
|
}
|
|
7926
8139
|
function isProviderOptions(options) {
|
|
7927
|
-
return "provider"
|
|
8140
|
+
return Object.prototype.hasOwnProperty.call(options, "provider");
|
|
7928
8141
|
}
|
|
7929
8142
|
function isExpired(tokens, now) {
|
|
7930
8143
|
return tokens.expiresAt !== null && tokens.expiresAt <= now();
|
|
@@ -7940,7 +8153,14 @@ function resolveDiscovery(discovery, session) {
|
|
|
7940
8153
|
return void 0;
|
|
7941
8154
|
}
|
|
7942
8155
|
const metadata = session.discovery.authorizationServerMetadata;
|
|
7943
|
-
|
|
8156
|
+
const issuer = getOwnString2(metadata, "issuer");
|
|
8157
|
+
const authorizationEndpoint = getOwnString2(metadata, "authorization_endpoint");
|
|
8158
|
+
const tokenEndpoint = getOwnString2(metadata, "token_endpoint");
|
|
8159
|
+
const codeChallengeMethodsSupported = getOwnStringArray(
|
|
8160
|
+
metadata,
|
|
8161
|
+
"code_challenge_methods_supported"
|
|
8162
|
+
);
|
|
8163
|
+
if (issuer === void 0 || authorizationEndpoint === void 0 || tokenEndpoint === void 0 || codeChallengeMethodsSupported === void 0 || !codeChallengeMethodsSupported.includes("S256")) {
|
|
7944
8164
|
return void 0;
|
|
7945
8165
|
}
|
|
7946
8166
|
return {
|
|
@@ -7964,29 +8184,94 @@ function normalizeLoadedSession(session) {
|
|
|
7964
8184
|
if (session === null) {
|
|
7965
8185
|
return null;
|
|
7966
8186
|
}
|
|
7967
|
-
|
|
8187
|
+
const client = normalizeStoredClient(getOwnEntry7(session, "client"));
|
|
8188
|
+
if (client === null) {
|
|
7968
8189
|
return { ...session, client: { clientId: "" }, tokens: void 0 };
|
|
7969
8190
|
}
|
|
7970
|
-
return
|
|
8191
|
+
return {
|
|
8192
|
+
...session,
|
|
8193
|
+
client,
|
|
8194
|
+
tokens: normalizeStoredTokens(getOwnEntry7(session, "tokens"))
|
|
8195
|
+
};
|
|
7971
8196
|
}
|
|
7972
|
-
function
|
|
7973
|
-
|
|
8197
|
+
function normalizeStoredClient(value) {
|
|
8198
|
+
if (!isObjectRecord3(value)) {
|
|
8199
|
+
return null;
|
|
8200
|
+
}
|
|
8201
|
+
const clientId = getOwnString2(value, "clientId");
|
|
8202
|
+
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
8203
|
+
return null;
|
|
8204
|
+
}
|
|
8205
|
+
const clientSecret = getOwnEntry7(value, "clientSecret");
|
|
8206
|
+
if (clientSecret === void 0) {
|
|
8207
|
+
return { clientId };
|
|
8208
|
+
}
|
|
8209
|
+
if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
|
|
8210
|
+
return null;
|
|
8211
|
+
}
|
|
8212
|
+
return { clientId, clientSecret };
|
|
7974
8213
|
}
|
|
7975
|
-
function
|
|
7976
|
-
if (
|
|
7977
|
-
return
|
|
8214
|
+
function normalizeStoredTokens(value) {
|
|
8215
|
+
if (value === void 0 || !isObjectRecord3(value)) {
|
|
8216
|
+
return void 0;
|
|
7978
8217
|
}
|
|
7979
|
-
|
|
8218
|
+
const accessToken = getOwnString2(value, "accessToken");
|
|
8219
|
+
const tokenType = getOwnString2(value, "tokenType");
|
|
8220
|
+
const expiresAt = getOwnEntry7(value, "expiresAt");
|
|
8221
|
+
const refreshToken = getOwnEntry7(value, "refreshToken");
|
|
8222
|
+
const scope = getOwnString2(value, "scope");
|
|
8223
|
+
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken : void 0;
|
|
8224
|
+
if (accessToken === void 0 || accessToken.trim().length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isFinite(expiresAt)) || refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
|
|
8225
|
+
return void 0;
|
|
8226
|
+
}
|
|
8227
|
+
return {
|
|
8228
|
+
accessToken,
|
|
8229
|
+
tokenType,
|
|
8230
|
+
expiresAt,
|
|
8231
|
+
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
8232
|
+
...scope === void 0 || scope.length === 0 ? {} : { scope }
|
|
8233
|
+
};
|
|
7980
8234
|
}
|
|
7981
8235
|
function getClientMetadata(client) {
|
|
7982
8236
|
return client.metadata;
|
|
7983
8237
|
}
|
|
8238
|
+
function getOwnEntry7(record, key2) {
|
|
8239
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
8240
|
+
}
|
|
8241
|
+
function isObjectRecord3(value) {
|
|
8242
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8243
|
+
}
|
|
8244
|
+
function getOwnString2(record, key2) {
|
|
8245
|
+
const value = getOwnEntry7(record, key2);
|
|
8246
|
+
return typeof value === "string" ? value : void 0;
|
|
8247
|
+
}
|
|
8248
|
+
function requireOwnString(record, key2, label) {
|
|
8249
|
+
const value = getOwnString2(record, key2);
|
|
8250
|
+
if (value === void 0) {
|
|
8251
|
+
throw new Error(`${label} is missing ${key2}`);
|
|
8252
|
+
}
|
|
8253
|
+
return value;
|
|
8254
|
+
}
|
|
8255
|
+
function getOwnStringArray(record, key2) {
|
|
8256
|
+
const value = getOwnEntry7(record, key2);
|
|
8257
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
|
|
8258
|
+
}
|
|
7984
8259
|
function buildAuthorizationUrl(input) {
|
|
7985
|
-
const
|
|
8260
|
+
const authorizationEndpoint = requireOwnString(
|
|
8261
|
+
input.metadata,
|
|
8262
|
+
"authorization_endpoint",
|
|
8263
|
+
"Authorization server metadata"
|
|
8264
|
+
);
|
|
8265
|
+
const issuer = requireOwnString(
|
|
8266
|
+
input.metadata,
|
|
8267
|
+
"issuer",
|
|
8268
|
+
"Authorization server metadata"
|
|
8269
|
+
);
|
|
8270
|
+
const url = new URL2(authorizationEndpoint);
|
|
7986
8271
|
const resource = canonicalizeResourceIndicator(input.resource);
|
|
7987
8272
|
const state = createAuthorizationState({
|
|
7988
|
-
issuer
|
|
7989
|
-
requireIssuer: input.metadata
|
|
8273
|
+
issuer,
|
|
8274
|
+
requireIssuer: getOwnEntry7(input.metadata, "authorization_response_iss_parameter_supported") === true
|
|
7990
8275
|
});
|
|
7991
8276
|
url.searchParams.set("response_type", "code");
|
|
7992
8277
|
url.searchParams.set("client_id", input.clientId);
|
|
@@ -8001,7 +8286,7 @@ function buildAuthorizationUrl(input) {
|
|
|
8001
8286
|
return url.toString();
|
|
8002
8287
|
}
|
|
8003
8288
|
function assertS256PkceSupport(metadata) {
|
|
8004
|
-
if (!metadata
|
|
8289
|
+
if (!getOwnStringArray(metadata, "code_challenge_methods_supported")?.includes("S256")) {
|
|
8005
8290
|
throw new Error(
|
|
8006
8291
|
"Authorization server metadata must advertise code_challenge_methods_supported including S256"
|
|
8007
8292
|
);
|
|
@@ -8025,13 +8310,24 @@ function assertSecureUrl(value, label) {
|
|
|
8025
8310
|
throw new Error(`${label} must use https unless it targets a loopback host`);
|
|
8026
8311
|
}
|
|
8027
8312
|
function assertSecureOAuthFlowEndpoints(metadata) {
|
|
8028
|
-
|
|
8029
|
-
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8313
|
+
const authorizationEndpoint = requireOwnString(
|
|
8314
|
+
metadata,
|
|
8315
|
+
"authorization_endpoint",
|
|
8316
|
+
"Authorization server metadata"
|
|
8317
|
+
);
|
|
8318
|
+
const tokenEndpoint = requireOwnString(
|
|
8319
|
+
metadata,
|
|
8320
|
+
"token_endpoint",
|
|
8321
|
+
"Authorization server metadata"
|
|
8322
|
+
);
|
|
8323
|
+
const registrationEndpoint = getOwnString2(metadata, "registration_endpoint");
|
|
8324
|
+
assertNoAccessTokenInUrl(authorizationEndpoint, "Authorization endpoint");
|
|
8325
|
+
assertNoAccessTokenInUrl(tokenEndpoint, "Token endpoint");
|
|
8326
|
+
assertSecureUrl(authorizationEndpoint, "Authorization endpoint");
|
|
8327
|
+
assertSecureUrl(tokenEndpoint, "Token endpoint");
|
|
8328
|
+
if (registrationEndpoint !== void 0) {
|
|
8329
|
+
assertNoAccessTokenInUrl(registrationEndpoint, "Registration endpoint");
|
|
8330
|
+
assertSecureUrl(registrationEndpoint, "Registration endpoint");
|
|
8035
8331
|
}
|
|
8036
8332
|
}
|
|
8037
8333
|
function assertNoAccessTokenInUrl(value, label) {
|
|
@@ -8054,17 +8350,21 @@ function buildClientRegistrationBody(metadata, redirectUri) {
|
|
|
8054
8350
|
response_types: ["code"],
|
|
8055
8351
|
token_endpoint_auth_method: "none"
|
|
8056
8352
|
};
|
|
8057
|
-
|
|
8058
|
-
|
|
8353
|
+
const clientName = metadata === void 0 ? void 0 : getOwnString2(metadata, "clientName");
|
|
8354
|
+
const scope = metadata === void 0 ? void 0 : getOwnString2(metadata, "scope");
|
|
8355
|
+
const softwareId = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareId");
|
|
8356
|
+
const softwareVersion = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareVersion");
|
|
8357
|
+
if (clientName !== void 0 && clientName.length > 0) {
|
|
8358
|
+
body.client_name = clientName;
|
|
8059
8359
|
}
|
|
8060
|
-
if (
|
|
8061
|
-
body.scope =
|
|
8360
|
+
if (scope !== void 0 && scope.length > 0) {
|
|
8361
|
+
body.scope = scope;
|
|
8062
8362
|
}
|
|
8063
|
-
if (
|
|
8064
|
-
body.software_id =
|
|
8363
|
+
if (softwareId !== void 0 && softwareId.length > 0) {
|
|
8364
|
+
body.software_id = softwareId;
|
|
8065
8365
|
}
|
|
8066
|
-
if (
|
|
8067
|
-
body.software_version =
|
|
8366
|
+
if (softwareVersion !== void 0 && softwareVersion.length > 0) {
|
|
8367
|
+
body.software_version = softwareVersion;
|
|
8068
8368
|
}
|
|
8069
8369
|
return body;
|
|
8070
8370
|
}
|
|
@@ -8100,7 +8400,7 @@ import {
|
|
|
8100
8400
|
function defaultOAuthMetadataFetch(input, init) {
|
|
8101
8401
|
return fetch(input, init);
|
|
8102
8402
|
}
|
|
8103
|
-
function
|
|
8403
|
+
function isObjectRecord4(value) {
|
|
8104
8404
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8105
8405
|
}
|
|
8106
8406
|
function isStringArray(value) {
|
|
@@ -8123,7 +8423,7 @@ function assertSecureUrl2(url, label) {
|
|
|
8123
8423
|
throw new Error(`${label} must use https unless it targets a loopback host`);
|
|
8124
8424
|
}
|
|
8125
8425
|
function validateProtectedResourceMetadata(value, resourceUrl) {
|
|
8126
|
-
if (!
|
|
8426
|
+
if (!isObjectRecord4(value)) {
|
|
8127
8427
|
throw new Error("Protected resource metadata must be a JSON object");
|
|
8128
8428
|
}
|
|
8129
8429
|
if (typeof value.resource !== "string" || value.resource.length === 0) {
|
|
@@ -8146,7 +8446,7 @@ function validateProtectedResourceMetadata(value, resourceUrl) {
|
|
|
8146
8446
|
};
|
|
8147
8447
|
}
|
|
8148
8448
|
function validateAuthorizationServerMetadata(value, issuer) {
|
|
8149
|
-
if (!
|
|
8449
|
+
if (!isObjectRecord4(value)) {
|
|
8150
8450
|
throw new Error("Authorization server metadata must be a JSON object");
|
|
8151
8451
|
}
|
|
8152
8452
|
if (typeof value.issuer !== "string" || value.issuer.length === 0) {
|
|
@@ -8599,7 +8899,7 @@ var McpClient = class {
|
|
|
8599
8899
|
await onPromptsChanged();
|
|
8600
8900
|
});
|
|
8601
8901
|
messageLayer.onNotification("notifications/message", async (params17) => {
|
|
8602
|
-
if (onLog === void 0 || !
|
|
8902
|
+
if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
|
|
8603
8903
|
return;
|
|
8604
8904
|
}
|
|
8605
8905
|
if (!hasOwn(params17, "data")) {
|
|
@@ -8618,7 +8918,7 @@ var McpClient = class {
|
|
|
8618
8918
|
await onLog(message2);
|
|
8619
8919
|
});
|
|
8620
8920
|
messageLayer.onNotification("notifications/progress", async (params17) => {
|
|
8621
|
-
if (onProgress === void 0 || !
|
|
8921
|
+
if (onProgress === void 0 || !isObjectRecord5(params17)) {
|
|
8622
8922
|
return;
|
|
8623
8923
|
}
|
|
8624
8924
|
const { progressToken, progress } = params17;
|
|
@@ -8787,6 +9087,9 @@ var McpClient = class {
|
|
|
8787
9087
|
const abortPromise = new Promise((_, reject) => {
|
|
8788
9088
|
const rejectWithAbortReason = () => {
|
|
8789
9089
|
sendCancellationNotification();
|
|
9090
|
+
if (requestId !== void 0) {
|
|
9091
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
9092
|
+
}
|
|
8790
9093
|
reject(signal.reason);
|
|
8791
9094
|
};
|
|
8792
9095
|
abortListener = rejectWithAbortReason;
|
|
@@ -8961,11 +9264,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8961
9264
|
const child = this.child;
|
|
8962
9265
|
this.readable = child.stdout;
|
|
8963
9266
|
this.writable = child.stdin;
|
|
9267
|
+
const stderrDecoder = new TextDecoder();
|
|
8964
9268
|
child.stderr.on("data", (chunk) => {
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
9269
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9270
|
+
this.appendStderrOutput(decoded);
|
|
9271
|
+
});
|
|
9272
|
+
child.stderr.once("end", () => {
|
|
9273
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8969
9274
|
});
|
|
8970
9275
|
this.closed = new Promise((resolve) => {
|
|
8971
9276
|
let settled = false;
|
|
@@ -9005,6 +9310,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
9005
9310
|
getStderrOutput() {
|
|
9006
9311
|
return this.stderrOutput;
|
|
9007
9312
|
}
|
|
9313
|
+
appendStderrOutput(chunk) {
|
|
9314
|
+
if (chunk.length === 0) {
|
|
9315
|
+
return;
|
|
9316
|
+
}
|
|
9317
|
+
this.stderrOutput += chunk;
|
|
9318
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9319
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9008
9322
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
9009
9323
|
void reason;
|
|
9010
9324
|
if (this.disposed) {
|
|
@@ -9412,15 +9726,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9412
9726
|
return `${JSON.stringify(message2)}
|
|
9413
9727
|
`;
|
|
9414
9728
|
}
|
|
9415
|
-
function chunkToString(chunk) {
|
|
9416
|
-
if (typeof chunk === "string") {
|
|
9417
|
-
return chunk;
|
|
9418
|
-
}
|
|
9419
|
-
if (chunk instanceof Uint8Array) {
|
|
9420
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9421
|
-
}
|
|
9422
|
-
return String(chunk);
|
|
9423
|
-
}
|
|
9424
9729
|
function normalizeLine(line) {
|
|
9425
9730
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9426
9731
|
}
|
|
@@ -9610,6 +9915,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9610
9915
|
}
|
|
9611
9916
|
});
|
|
9612
9917
|
}
|
|
9918
|
+
cancelRequest(requestId, reason) {
|
|
9919
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9920
|
+
if (pending === void 0) {
|
|
9921
|
+
return false;
|
|
9922
|
+
}
|
|
9923
|
+
this.pendingRequests.delete(requestId);
|
|
9924
|
+
clearTimeout(pending.timeout);
|
|
9925
|
+
pending.reject(reason);
|
|
9926
|
+
return true;
|
|
9927
|
+
}
|
|
9613
9928
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9614
9929
|
if (this.disposedError !== void 0) {
|
|
9615
9930
|
return;
|
|
@@ -9804,7 +10119,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9804
10119
|
})();
|
|
9805
10120
|
}
|
|
9806
10121
|
handleCancellationNotification(params17) {
|
|
9807
|
-
if (!
|
|
10122
|
+
if (!isObjectRecord5(params17)) {
|
|
9808
10123
|
return;
|
|
9809
10124
|
}
|
|
9810
10125
|
const requestId = params17.requestId;
|
|
@@ -9819,34 +10134,34 @@ var JsonRpcMessageLayer = class {
|
|
|
9819
10134
|
this.activeIncomingRequests.delete(requestId);
|
|
9820
10135
|
}
|
|
9821
10136
|
};
|
|
9822
|
-
function
|
|
10137
|
+
function isObjectRecord5(value) {
|
|
9823
10138
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9824
10139
|
}
|
|
9825
10140
|
function isInitializeResult(value) {
|
|
9826
|
-
if (!
|
|
10141
|
+
if (!isObjectRecord5(value) || typeof value.protocolVersion !== "string") {
|
|
9827
10142
|
return false;
|
|
9828
10143
|
}
|
|
9829
10144
|
if (!isServerCapabilities(value.capabilities)) {
|
|
9830
10145
|
return false;
|
|
9831
10146
|
}
|
|
9832
|
-
if (!
|
|
10147
|
+
if (!isObjectRecord5(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
|
|
9833
10148
|
return false;
|
|
9834
10149
|
}
|
|
9835
10150
|
return value.instructions === void 0 || typeof value.instructions === "string";
|
|
9836
10151
|
}
|
|
9837
10152
|
function isServerCapabilities(value) {
|
|
9838
|
-
if (!
|
|
10153
|
+
if (!isObjectRecord5(value)) {
|
|
9839
10154
|
return false;
|
|
9840
10155
|
}
|
|
9841
10156
|
for (const capability of ["prompts", "resources", "tools", "logging", "completions", "experimental"]) {
|
|
9842
|
-
if (value[capability] !== void 0 && !
|
|
10157
|
+
if (value[capability] !== void 0 && !isObjectRecord5(value[capability])) {
|
|
9843
10158
|
return false;
|
|
9844
10159
|
}
|
|
9845
10160
|
}
|
|
9846
10161
|
return true;
|
|
9847
10162
|
}
|
|
9848
10163
|
function isCallToolResult(value) {
|
|
9849
|
-
if (!
|
|
10164
|
+
if (!isObjectRecord5(value) || !Array.isArray(value.content)) {
|
|
9850
10165
|
return false;
|
|
9851
10166
|
}
|
|
9852
10167
|
if (value.isError !== void 0 && typeof value.isError !== "boolean") {
|
|
@@ -9855,10 +10170,10 @@ function isCallToolResult(value) {
|
|
|
9855
10170
|
return value.content.every(isContentItem);
|
|
9856
10171
|
}
|
|
9857
10172
|
function isToolsListResult(value) {
|
|
9858
|
-
return
|
|
10173
|
+
return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
9859
10174
|
}
|
|
9860
10175
|
function isContentItem(value) {
|
|
9861
|
-
if (!
|
|
10176
|
+
if (!isObjectRecord5(value)) {
|
|
9862
10177
|
return false;
|
|
9863
10178
|
}
|
|
9864
10179
|
if (value.type === "text") {
|
|
@@ -9867,7 +10182,7 @@ function isContentItem(value) {
|
|
|
9867
10182
|
if (value.type === "image" || value.type === "audio") {
|
|
9868
10183
|
return typeof value.data === "string" && typeof value.mimeType === "string";
|
|
9869
10184
|
}
|
|
9870
|
-
if (value.type !== "resource" || !
|
|
10185
|
+
if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
|
|
9871
10186
|
return false;
|
|
9872
10187
|
}
|
|
9873
10188
|
return typeof value.resource.uri === "string" && (value.resource.mimeType === void 0 || typeof value.resource.mimeType === "string") && (typeof value.resource.text === "string" || typeof value.resource.blob === "string");
|
|
@@ -9891,7 +10206,7 @@ function invalidRequest() {
|
|
|
9891
10206
|
return new McpError(ERROR_INVALID_REQUEST, "Invalid Request");
|
|
9892
10207
|
}
|
|
9893
10208
|
function isJsonRpcErrorObject(value) {
|
|
9894
|
-
if (!
|
|
10209
|
+
if (!isObjectRecord5(value)) {
|
|
9895
10210
|
return false;
|
|
9896
10211
|
}
|
|
9897
10212
|
if (typeof value.code !== "number" || typeof value.message !== "string") {
|
|
@@ -9900,7 +10215,7 @@ function isJsonRpcErrorObject(value) {
|
|
|
9900
10215
|
return value.data === void 0 || hasOwn(value, "data");
|
|
9901
10216
|
}
|
|
9902
10217
|
function parseJsonRpcPayload(parsed) {
|
|
9903
|
-
if (!
|
|
10218
|
+
if (!isObjectRecord5(parsed)) {
|
|
9904
10219
|
return {
|
|
9905
10220
|
type: "invalid",
|
|
9906
10221
|
id: null,
|
|
@@ -10227,7 +10542,11 @@ function convertObjectSchema(schema, root, options) {
|
|
|
10227
10542
|
"properties",
|
|
10228
10543
|
key2
|
|
10229
10544
|
]);
|
|
10230
|
-
|
|
10545
|
+
setOwnShapeProperty(
|
|
10546
|
+
shape,
|
|
10547
|
+
key2,
|
|
10548
|
+
requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty)
|
|
10549
|
+
);
|
|
10231
10550
|
}
|
|
10232
10551
|
return applyMetadata(
|
|
10233
10552
|
S.Object(shape, {
|
|
@@ -10239,6 +10558,14 @@ function convertObjectSchema(schema, root, options) {
|
|
|
10239
10558
|
}
|
|
10240
10559
|
);
|
|
10241
10560
|
}
|
|
10561
|
+
function setOwnShapeProperty(shape, key2, value) {
|
|
10562
|
+
Object.defineProperty(shape, key2, {
|
|
10563
|
+
configurable: true,
|
|
10564
|
+
enumerable: true,
|
|
10565
|
+
writable: true,
|
|
10566
|
+
value
|
|
10567
|
+
});
|
|
10568
|
+
}
|
|
10242
10569
|
function createCommonOptions(schema, nullable, defaultValue) {
|
|
10243
10570
|
return {
|
|
10244
10571
|
...schema.description === void 0 ? {} : { description: schema.description },
|
|
@@ -10489,6 +10816,9 @@ function resolveLocalRef(root, ref) {
|
|
|
10489
10816
|
if (!isPlainObject(current)) {
|
|
10490
10817
|
return void 0;
|
|
10491
10818
|
}
|
|
10819
|
+
if (!Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
10820
|
+
return void 0;
|
|
10821
|
+
}
|
|
10492
10822
|
current = current[segment];
|
|
10493
10823
|
}
|
|
10494
10824
|
return isPlainObject(current) ? current : void 0;
|
|
@@ -10678,10 +11008,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10678
11008
|
}
|
|
10679
11009
|
}
|
|
10680
11010
|
}
|
|
10681
|
-
function createConnection(name,
|
|
11011
|
+
function createConnection(name, config2) {
|
|
10682
11012
|
const connection = {
|
|
10683
11013
|
name,
|
|
10684
|
-
config,
|
|
11014
|
+
config: config2,
|
|
10685
11015
|
async dispose() {
|
|
10686
11016
|
shutdownDisposers.delete(connection.dispose);
|
|
10687
11017
|
connection.connecting = void 0;
|
|
@@ -10737,24 +11067,42 @@ async function readCache(cachePath) {
|
|
|
10737
11067
|
}
|
|
10738
11068
|
async function writeCache(cachePath, cache) {
|
|
10739
11069
|
const directory = path12.dirname(cachePath);
|
|
10740
|
-
const tempPath = `${cachePath}.tmp-${
|
|
11070
|
+
const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
|
|
11071
|
+
let tempCreated = false;
|
|
10741
11072
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10742
11073
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10743
11074
|
await mkdir(directory, { recursive: true });
|
|
10744
11075
|
await assertCachePathHasNoSymlinks(directory);
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
11076
|
+
try {
|
|
11077
|
+
await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
|
|
11078
|
+
`, {
|
|
11079
|
+
encoding: "utf8",
|
|
11080
|
+
flag: "wx"
|
|
11081
|
+
});
|
|
11082
|
+
tempCreated = true;
|
|
11083
|
+
await assertCachePathHasNoSymlinks(tempPath);
|
|
11084
|
+
await assertCachePathHasNoSymlinks(cachePath);
|
|
11085
|
+
await rename2(tempPath, cachePath);
|
|
11086
|
+
tempCreated = false;
|
|
11087
|
+
} catch (error3) {
|
|
11088
|
+
if (tempCreated || !isAlreadyExistsError2(error3)) {
|
|
11089
|
+
await unlink2(tempPath).catch(() => void 0);
|
|
11090
|
+
}
|
|
11091
|
+
throw error3;
|
|
11092
|
+
}
|
|
10750
11093
|
}
|
|
10751
|
-
|
|
11094
|
+
function isAlreadyExistsError2(error3) {
|
|
11095
|
+
return Boolean(
|
|
11096
|
+
error3 && typeof error3 === "object" && error3.code === "EEXIST"
|
|
11097
|
+
);
|
|
11098
|
+
}
|
|
11099
|
+
async function fetchCache(name, config2) {
|
|
10752
11100
|
const logger2 = createLogger((message2) => {
|
|
10753
11101
|
process.stderr.write(`${message2}
|
|
10754
11102
|
`);
|
|
10755
11103
|
});
|
|
10756
11104
|
logger2.info(`MCP ${name}: connecting`);
|
|
10757
|
-
const client = await dialUpstream(name,
|
|
11105
|
+
const client = await dialUpstream(name, config2);
|
|
10758
11106
|
try {
|
|
10759
11107
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10760
11108
|
const tools = [];
|
|
@@ -10773,7 +11121,7 @@ async function fetchCache(name, config) {
|
|
|
10773
11121
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10774
11122
|
version: 1,
|
|
10775
11123
|
upstream,
|
|
10776
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
11124
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10777
11125
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10778
11126
|
tools
|
|
10779
11127
|
};
|
|
@@ -10843,8 +11191,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10843
11191
|
}
|
|
10844
11192
|
async function resolveSingleProxy(group, options) {
|
|
10845
11193
|
const internal = getInternalGroupConfig2(group);
|
|
10846
|
-
const
|
|
10847
|
-
if (
|
|
11194
|
+
const config2 = internal.mcp;
|
|
11195
|
+
if (config2 === void 0) {
|
|
10848
11196
|
return;
|
|
10849
11197
|
}
|
|
10850
11198
|
const name = group.name;
|
|
@@ -10854,21 +11202,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10854
11202
|
let cache;
|
|
10855
11203
|
let shouldWriteCache = false;
|
|
10856
11204
|
if (isRefreshRequested(name, refresh)) {
|
|
10857
|
-
cache = await fetchCache(name,
|
|
11205
|
+
cache = await fetchCache(name, config2);
|
|
10858
11206
|
shouldWriteCache = true;
|
|
10859
11207
|
} else {
|
|
10860
11208
|
const storedCache = await readCache(cachePath);
|
|
10861
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
11209
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10862
11210
|
cache = storedCache;
|
|
10863
11211
|
} else {
|
|
10864
|
-
cache = await fetchCache(name,
|
|
11212
|
+
cache = await fetchCache(name, config2);
|
|
10865
11213
|
shouldWriteCache = true;
|
|
10866
11214
|
}
|
|
10867
11215
|
}
|
|
10868
11216
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10869
11217
|
validateRenameMap2(name, tools, internal.rename);
|
|
10870
11218
|
const previousConnection = getProxyConnection(group);
|
|
10871
|
-
const nextConnection = createConnection(name,
|
|
11219
|
+
const nextConnection = createConnection(name, config2);
|
|
10872
11220
|
try {
|
|
10873
11221
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10874
11222
|
if (shouldWriteCache) {
|
|
@@ -10893,11 +11241,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10893
11241
|
);
|
|
10894
11242
|
}
|
|
10895
11243
|
}
|
|
10896
|
-
function cacheMatchesConfig(cache,
|
|
10897
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
11244
|
+
function cacheMatchesConfig(cache, config2) {
|
|
11245
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10898
11246
|
}
|
|
10899
|
-
function fingerprintMcpServerConfig(
|
|
10900
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
11247
|
+
function fingerprintMcpServerConfig(config2) {
|
|
11248
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10901
11249
|
}
|
|
10902
11250
|
function collectProxyGroups(root) {
|
|
10903
11251
|
const groups = [];
|
|
@@ -10975,20 +11323,20 @@ function parseRefreshEnv(value) {
|
|
|
10975
11323
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10976
11324
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10977
11325
|
}
|
|
10978
|
-
async function dialUpstream(name,
|
|
11326
|
+
async function dialUpstream(name, config2) {
|
|
10979
11327
|
const client = new McpClient({
|
|
10980
11328
|
clientInfo: {
|
|
10981
11329
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10982
11330
|
version: DEFAULT_CLIENT_INFO.version
|
|
10983
11331
|
}
|
|
10984
11332
|
});
|
|
10985
|
-
const transport =
|
|
10986
|
-
command:
|
|
10987
|
-
...
|
|
10988
|
-
...
|
|
11333
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11334
|
+
command: config2.command,
|
|
11335
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11336
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10989
11337
|
}) : new HttpTransport({
|
|
10990
|
-
url:
|
|
10991
|
-
...
|
|
11338
|
+
url: config2.url,
|
|
11339
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10992
11340
|
});
|
|
10993
11341
|
await client.connect(transport);
|
|
10994
11342
|
return client;
|
|
@@ -10998,10 +11346,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
10998
11346
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
10999
11347
|
}
|
|
11000
11348
|
|
|
11349
|
+
// ../toolcraft/src/redaction.ts
|
|
11350
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11351
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11352
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11353
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11354
|
+
function isPlainObject2(value) {
|
|
11355
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11356
|
+
}
|
|
11357
|
+
function normalizeName(name) {
|
|
11358
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11359
|
+
}
|
|
11360
|
+
function isSensitiveName(name) {
|
|
11361
|
+
const normalized = normalizeName(name);
|
|
11362
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11363
|
+
}
|
|
11364
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11365
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11366
|
+
return REDACTED_VALUE;
|
|
11367
|
+
}
|
|
11368
|
+
if (Array.isArray(value)) {
|
|
11369
|
+
if (seen.has(value)) {
|
|
11370
|
+
return "[Circular]";
|
|
11371
|
+
}
|
|
11372
|
+
seen.add(value);
|
|
11373
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11374
|
+
}
|
|
11375
|
+
if (isPlainObject2(value)) {
|
|
11376
|
+
if (seen.has(value)) {
|
|
11377
|
+
return "[Circular]";
|
|
11378
|
+
}
|
|
11379
|
+
seen.add(value);
|
|
11380
|
+
return Object.fromEntries(
|
|
11381
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11382
|
+
key2,
|
|
11383
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11384
|
+
])
|
|
11385
|
+
);
|
|
11386
|
+
}
|
|
11387
|
+
return value;
|
|
11388
|
+
}
|
|
11389
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11390
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11391
|
+
}
|
|
11392
|
+
function parseJsonObjectOrArray(value) {
|
|
11393
|
+
const trimmed = value.trim();
|
|
11394
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11395
|
+
return void 0;
|
|
11396
|
+
}
|
|
11397
|
+
try {
|
|
11398
|
+
const parsed = JSON.parse(trimmed);
|
|
11399
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11400
|
+
} catch {
|
|
11401
|
+
return void 0;
|
|
11402
|
+
}
|
|
11403
|
+
}
|
|
11404
|
+
function redactHttpBody(body) {
|
|
11405
|
+
if (typeof body === "string") {
|
|
11406
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11407
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11408
|
+
}
|
|
11409
|
+
return redactSecretLikeFields(body);
|
|
11410
|
+
}
|
|
11411
|
+
function redactHttpHeaderValue(name, value) {
|
|
11412
|
+
const normalized = normalizeName(name);
|
|
11413
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11414
|
+
return "Bearer ****";
|
|
11415
|
+
}
|
|
11416
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11417
|
+
return REDACTED_VALUE;
|
|
11418
|
+
}
|
|
11419
|
+
return value;
|
|
11420
|
+
}
|
|
11421
|
+
|
|
11001
11422
|
// ../toolcraft/src/error-report.ts
|
|
11002
11423
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
11003
|
-
|
|
11004
|
-
function isPlainObject2(value) {
|
|
11424
|
+
function isPlainObject3(value) {
|
|
11005
11425
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11006
11426
|
}
|
|
11007
11427
|
function unwrapOptional(schema) {
|
|
@@ -11011,7 +11431,7 @@ function unwrapOptional(schema) {
|
|
|
11011
11431
|
return schema;
|
|
11012
11432
|
}
|
|
11013
11433
|
function hasHttpContext(error3) {
|
|
11014
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11434
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
11015
11435
|
}
|
|
11016
11436
|
function isSkippedError(error3) {
|
|
11017
11437
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -11048,8 +11468,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
|
11048
11468
|
throw new Error("Error report directory resolves outside project root.");
|
|
11049
11469
|
}
|
|
11050
11470
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
11051
|
-
|
|
11052
|
-
|
|
11471
|
+
realpath2(projectRoot),
|
|
11472
|
+
realpath2(reportDir)
|
|
11053
11473
|
]);
|
|
11054
11474
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
11055
11475
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -11104,9 +11524,24 @@ function redactValue(value) {
|
|
|
11104
11524
|
}
|
|
11105
11525
|
return `<set, ${value.length} chars>`;
|
|
11106
11526
|
}
|
|
11107
|
-
function
|
|
11108
|
-
|
|
11109
|
-
|
|
11527
|
+
function collectStringLeaves(value, output) {
|
|
11528
|
+
if (typeof value === "string") {
|
|
11529
|
+
if (value.length > 0) {
|
|
11530
|
+
output.add(value);
|
|
11531
|
+
}
|
|
11532
|
+
return;
|
|
11533
|
+
}
|
|
11534
|
+
if (Array.isArray(value)) {
|
|
11535
|
+
for (const entry of value) {
|
|
11536
|
+
collectStringLeaves(entry, output);
|
|
11537
|
+
}
|
|
11538
|
+
return;
|
|
11539
|
+
}
|
|
11540
|
+
if (isPlainObject3(value)) {
|
|
11541
|
+
for (const entry of Object.values(value)) {
|
|
11542
|
+
collectStringLeaves(entry, output);
|
|
11543
|
+
}
|
|
11544
|
+
}
|
|
11110
11545
|
}
|
|
11111
11546
|
function schemaSecretValue(schema) {
|
|
11112
11547
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -11127,7 +11562,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
11127
11562
|
return "<redacted>";
|
|
11128
11563
|
}
|
|
11129
11564
|
const unwrapped = unwrapOptional(schema);
|
|
11130
|
-
if (unwrapped.kind === "object" &&
|
|
11565
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11131
11566
|
return Object.fromEntries(
|
|
11132
11567
|
Object.entries(value).map(([key2, childValue]) => {
|
|
11133
11568
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -11149,6 +11584,52 @@ function redactParams(params17, command) {
|
|
|
11149
11584
|
}
|
|
11150
11585
|
return redactParamsValue(params17, command.params, "");
|
|
11151
11586
|
}
|
|
11587
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11588
|
+
if (shouldRedactParam(name, schema)) {
|
|
11589
|
+
collectStringLeaves(value, output);
|
|
11590
|
+
return;
|
|
11591
|
+
}
|
|
11592
|
+
const unwrapped = unwrapOptional(schema);
|
|
11593
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11594
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11595
|
+
const childSchema = unwrapped.shape[key2];
|
|
11596
|
+
if (childSchema !== void 0) {
|
|
11597
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11598
|
+
}
|
|
11599
|
+
}
|
|
11600
|
+
return;
|
|
11601
|
+
}
|
|
11602
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11603
|
+
for (const entry of value) {
|
|
11604
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11605
|
+
}
|
|
11606
|
+
}
|
|
11607
|
+
}
|
|
11608
|
+
function createReportStringRedactor(context, env) {
|
|
11609
|
+
const values = /* @__PURE__ */ new Set();
|
|
11610
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11611
|
+
if (value !== void 0 && value.length > 0) {
|
|
11612
|
+
values.add(value);
|
|
11613
|
+
}
|
|
11614
|
+
}
|
|
11615
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11616
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11617
|
+
if (value !== void 0 && value.length > 0) {
|
|
11618
|
+
values.add(value);
|
|
11619
|
+
}
|
|
11620
|
+
}
|
|
11621
|
+
if (context.command !== void 0) {
|
|
11622
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11623
|
+
}
|
|
11624
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11625
|
+
return (value) => {
|
|
11626
|
+
let redacted = value;
|
|
11627
|
+
for (const secretValue of orderedValues) {
|
|
11628
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11629
|
+
}
|
|
11630
|
+
return redacted;
|
|
11631
|
+
};
|
|
11632
|
+
}
|
|
11152
11633
|
function commandSecretEnvNames(secrets) {
|
|
11153
11634
|
if (secrets === void 0) {
|
|
11154
11635
|
return [];
|
|
@@ -11202,28 +11683,42 @@ function redactArgv(argv, options) {
|
|
|
11202
11683
|
function stableJson(value) {
|
|
11203
11684
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
11204
11685
|
}
|
|
11205
|
-
function redactStructuredErrorField(name, value) {
|
|
11206
|
-
if (typeof value === "string"
|
|
11207
|
-
|
|
11686
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11687
|
+
if (typeof value === "string") {
|
|
11688
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11689
|
+
if (redactedHeaderValue !== value) {
|
|
11690
|
+
return redactedHeaderValue;
|
|
11691
|
+
}
|
|
11692
|
+
if (isSensitiveName(name)) {
|
|
11693
|
+
return "<redacted>";
|
|
11694
|
+
}
|
|
11695
|
+
return redactString(value);
|
|
11208
11696
|
}
|
|
11209
11697
|
if (Array.isArray(value)) {
|
|
11210
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11698
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
11211
11699
|
}
|
|
11212
|
-
if (
|
|
11700
|
+
if (isPlainObject3(value)) {
|
|
11213
11701
|
return Object.fromEntries(
|
|
11214
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11702
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11703
|
+
key2,
|
|
11704
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11705
|
+
])
|
|
11215
11706
|
);
|
|
11216
11707
|
}
|
|
11217
11708
|
return value;
|
|
11218
11709
|
}
|
|
11219
|
-
function ownStructuredFields(error3) {
|
|
11710
|
+
function ownStructuredFields(error3, redactString) {
|
|
11220
11711
|
const fields = {};
|
|
11221
11712
|
for (const key2 of Object.keys(error3)) {
|
|
11222
11713
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
11223
11714
|
continue;
|
|
11224
11715
|
}
|
|
11225
11716
|
Object.defineProperty(fields, key2, {
|
|
11226
|
-
value: redactStructuredErrorField(
|
|
11717
|
+
value: redactStructuredErrorField(
|
|
11718
|
+
key2,
|
|
11719
|
+
error3[key2],
|
|
11720
|
+
redactString
|
|
11721
|
+
),
|
|
11227
11722
|
enumerable: true,
|
|
11228
11723
|
configurable: true,
|
|
11229
11724
|
writable: true
|
|
@@ -11231,43 +11726,44 @@ function ownStructuredFields(error3) {
|
|
|
11231
11726
|
}
|
|
11232
11727
|
return fields;
|
|
11233
11728
|
}
|
|
11234
|
-
function formatStackChain(error3) {
|
|
11729
|
+
function formatStackChain(error3, redactString) {
|
|
11235
11730
|
const lines = [];
|
|
11236
11731
|
let current = error3;
|
|
11237
11732
|
let index = 0;
|
|
11238
11733
|
while (current !== void 0) {
|
|
11239
11734
|
if (current instanceof Error) {
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
);
|
|
11735
|
+
const stack = current.stack ?? String(current);
|
|
11736
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
11243
11737
|
current = current.cause;
|
|
11244
11738
|
} else {
|
|
11245
|
-
|
|
11739
|
+
const message2 = String(current);
|
|
11740
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
11246
11741
|
current = void 0;
|
|
11247
11742
|
}
|
|
11248
11743
|
index += 1;
|
|
11249
11744
|
}
|
|
11250
11745
|
return lines.join("\n");
|
|
11251
11746
|
}
|
|
11252
|
-
function formatHeaderValue(name, value) {
|
|
11253
|
-
return name
|
|
11747
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11748
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
11254
11749
|
}
|
|
11255
|
-
function formatHeaders(headers) {
|
|
11256
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11750
|
+
function formatHeaders(headers, redactString) {
|
|
11751
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
11257
11752
|
}
|
|
11258
|
-
function formatBody(body) {
|
|
11259
|
-
|
|
11260
|
-
|
|
11753
|
+
function formatBody(body, redactString) {
|
|
11754
|
+
const redactedBody = redactHttpBody(body);
|
|
11755
|
+
if (typeof redactedBody === "string") {
|
|
11756
|
+
return redactString(redactedBody);
|
|
11261
11757
|
}
|
|
11262
|
-
return stableJson(
|
|
11758
|
+
return redactString(stableJson(redactedBody));
|
|
11263
11759
|
}
|
|
11264
|
-
function formatHttpTranscript(error3) {
|
|
11760
|
+
function formatHttpTranscript(error3, redactString) {
|
|
11265
11761
|
const requestLines = [
|
|
11266
11762
|
`${error3.request.method} ${error3.request.url}`,
|
|
11267
|
-
formatHeaders(error3.request.headers)
|
|
11763
|
+
formatHeaders(error3.request.headers, redactString)
|
|
11268
11764
|
].filter((line) => line.length > 0);
|
|
11269
11765
|
if (error3.request.body !== void 0) {
|
|
11270
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11766
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
11271
11767
|
}
|
|
11272
11768
|
return [
|
|
11273
11769
|
"Request:",
|
|
@@ -11275,9 +11771,9 @@ function formatHttpTranscript(error3) {
|
|
|
11275
11771
|
"",
|
|
11276
11772
|
"Response:",
|
|
11277
11773
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
11278
|
-
formatHeaders(error3.response.headers),
|
|
11774
|
+
formatHeaders(error3.response.headers, redactString),
|
|
11279
11775
|
"",
|
|
11280
|
-
formatBody(error3.response.body)
|
|
11776
|
+
formatBody(error3.response.body, redactString)
|
|
11281
11777
|
].join("\n");
|
|
11282
11778
|
}
|
|
11283
11779
|
function resolveToolcraftVersion(version) {
|
|
@@ -11286,9 +11782,10 @@ function resolveToolcraftVersion(version) {
|
|
|
11286
11782
|
function buildReport(context) {
|
|
11287
11783
|
const env = context.env ?? process.env;
|
|
11288
11784
|
const error3 = context.error;
|
|
11785
|
+
const redactString = createReportStringRedactor(context, env);
|
|
11289
11786
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11290
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11291
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11787
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11788
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11292
11789
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11293
11790
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11294
11791
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11302,7 +11799,9 @@ function buildReport(context) {
|
|
|
11302
11799
|
`platform: ${process.platform} ${process.arch}`,
|
|
11303
11800
|
"",
|
|
11304
11801
|
"Argv",
|
|
11305
|
-
|
|
11802
|
+
redactString(
|
|
11803
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11804
|
+
),
|
|
11306
11805
|
"",
|
|
11307
11806
|
"Resolved Secrets",
|
|
11308
11807
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11311,19 +11810,19 @@ function buildReport(context) {
|
|
|
11311
11810
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11312
11811
|
"",
|
|
11313
11812
|
"Parsed Params",
|
|
11314
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11813
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11315
11814
|
"",
|
|
11316
11815
|
"Error",
|
|
11317
11816
|
`name: ${errorName}`,
|
|
11318
11817
|
`message: ${errorMessage}`,
|
|
11319
11818
|
"structured fields:",
|
|
11320
|
-
stableJson(structuredFields),
|
|
11819
|
+
redactString(stableJson(structuredFields)),
|
|
11321
11820
|
"",
|
|
11322
11821
|
"Stack",
|
|
11323
|
-
formatStackChain(error3)
|
|
11822
|
+
formatStackChain(error3, redactString)
|
|
11324
11823
|
];
|
|
11325
11824
|
if (hasHttpContext(error3)) {
|
|
11326
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11825
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11327
11826
|
}
|
|
11328
11827
|
return `${lines.join("\n")}
|
|
11329
11828
|
`;
|
|
@@ -11335,7 +11834,7 @@ async function writeErrorReport(context) {
|
|
|
11335
11834
|
}
|
|
11336
11835
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11337
11836
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11338
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11837
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
|
|
11339
11838
|
const absolutePath = path13.join(reportDir, fileName);
|
|
11340
11839
|
await mkdir2(reportDir, { recursive: true });
|
|
11341
11840
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
@@ -11783,6 +12282,7 @@ ${rendered.join("\n")}`);
|
|
|
11783
12282
|
}
|
|
11784
12283
|
|
|
11785
12284
|
// ../toolcraft/src/cli.ts
|
|
12285
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11786
12286
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11787
12287
|
"params",
|
|
11788
12288
|
"secrets",
|
|
@@ -12813,10 +13313,10 @@ function renderHelpSections(sections) {
|
|
|
12813
13313
|
return sections.filter((section) => section.length > 0).join("\n\n");
|
|
12814
13314
|
}
|
|
12815
13315
|
function formatHelpCommandList(rows) {
|
|
12816
|
-
return process.stdout.isTTY
|
|
13316
|
+
return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
|
|
12817
13317
|
}
|
|
12818
13318
|
function formatHelpOptionList(rows) {
|
|
12819
|
-
return process.stdout.isTTY
|
|
13319
|
+
return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
|
|
12820
13320
|
}
|
|
12821
13321
|
function buildUsageLine(breadcrumb, rootUsageName, suffix) {
|
|
12822
13322
|
const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
|
|
@@ -13104,11 +13604,18 @@ function formatResolvedValue(value) {
|
|
|
13104
13604
|
function fieldPromptLabel(field) {
|
|
13105
13605
|
return field.positionalIndex === void 0 ? field.optionFlag : `<${field.displayPath}>`;
|
|
13106
13606
|
}
|
|
13607
|
+
function enumOptionLabel(schema, value) {
|
|
13608
|
+
const key2 = String(value);
|
|
13609
|
+
if (schema.labels === void 0 || !Object.prototype.hasOwnProperty.call(schema.labels, key2)) {
|
|
13610
|
+
return key2;
|
|
13611
|
+
}
|
|
13612
|
+
return schema.labels[key2] ?? key2;
|
|
13613
|
+
}
|
|
13107
13614
|
async function promptForField(field) {
|
|
13108
13615
|
const schema = field.schema;
|
|
13109
13616
|
if (schema.kind === "enum") {
|
|
13110
13617
|
const options = schema.loadOptions ? await schema.loadOptions() : schema.values.map((value) => ({
|
|
13111
|
-
label: schema
|
|
13618
|
+
label: enumOptionLabel(schema, value),
|
|
13112
13619
|
value
|
|
13113
13620
|
}));
|
|
13114
13621
|
const selected = await select2({
|
|
@@ -13193,8 +13700,8 @@ async function withOutputFormat2(output, fn) {
|
|
|
13193
13700
|
function createFs2() {
|
|
13194
13701
|
return {
|
|
13195
13702
|
readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
|
|
13196
|
-
writeFile: async (path24, contents) => {
|
|
13197
|
-
await writeFile5(path24, contents);
|
|
13703
|
+
writeFile: async (path24, contents, options) => {
|
|
13704
|
+
await writeFile5(path24, contents, options);
|
|
13198
13705
|
},
|
|
13199
13706
|
exists: async (path24) => {
|
|
13200
13707
|
try {
|
|
@@ -13206,7 +13713,7 @@ function createFs2() {
|
|
|
13206
13713
|
},
|
|
13207
13714
|
lstat: async (path24) => lstat3(path24),
|
|
13208
13715
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
13209
|
-
unlink: async (path24) =>
|
|
13716
|
+
unlink: async (path24) => unlink3(path24)
|
|
13210
13717
|
};
|
|
13211
13718
|
}
|
|
13212
13719
|
function createEnv2(values = process.env) {
|
|
@@ -13216,7 +13723,7 @@ function createEnv2(values = process.env) {
|
|
|
13216
13723
|
}
|
|
13217
13724
|
};
|
|
13218
13725
|
}
|
|
13219
|
-
function
|
|
13726
|
+
function isPlainObject4(value) {
|
|
13220
13727
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13221
13728
|
}
|
|
13222
13729
|
function hasFieldValue(value) {
|
|
@@ -13325,7 +13832,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13325
13832
|
{ cause: error3 }
|
|
13326
13833
|
);
|
|
13327
13834
|
}
|
|
13328
|
-
if (!
|
|
13835
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13329
13836
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13330
13837
|
}
|
|
13331
13838
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
@@ -13344,7 +13851,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13344
13851
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13345
13852
|
);
|
|
13346
13853
|
}
|
|
13347
|
-
if (!
|
|
13854
|
+
if (!isPlainObject4(value)) {
|
|
13348
13855
|
throw new UserError(
|
|
13349
13856
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13350
13857
|
);
|
|
@@ -13387,8 +13894,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13387
13894
|
}
|
|
13388
13895
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13389
13896
|
}
|
|
13390
|
-
if (
|
|
13391
|
-
if (!
|
|
13897
|
+
if (isPlainObject4(expected)) {
|
|
13898
|
+
if (!isPlainObject4(actual)) {
|
|
13392
13899
|
return false;
|
|
13393
13900
|
}
|
|
13394
13901
|
return Object.entries(expected).every(
|
|
@@ -13451,9 +13958,9 @@ function createFixtureFetch(entries) {
|
|
|
13451
13958
|
};
|
|
13452
13959
|
}
|
|
13453
13960
|
function createFixtureFs(definition) {
|
|
13454
|
-
const fsDefinition =
|
|
13455
|
-
const readFileEntries =
|
|
13456
|
-
const existsEntries =
|
|
13961
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13962
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13963
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13457
13964
|
return {
|
|
13458
13965
|
readFile: async (filePath) => {
|
|
13459
13966
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13476,10 +13983,10 @@ function createFixtureFs(definition) {
|
|
|
13476
13983
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13477
13984
|
if (Array.isArray(definition)) {
|
|
13478
13985
|
for (const entry of definition) {
|
|
13479
|
-
if (!
|
|
13986
|
+
if (!isPlainObject4(entry)) {
|
|
13480
13987
|
continue;
|
|
13481
13988
|
}
|
|
13482
|
-
const explicitMatcher =
|
|
13989
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13483
13990
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13484
13991
|
Object.entries(entry).filter(
|
|
13485
13992
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13491,7 +13998,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13491
13998
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13492
13999
|
} else if (Object.keys(matcher).length === 0) {
|
|
13493
14000
|
matched = true;
|
|
13494
|
-
} else if (
|
|
14001
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13495
14002
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13496
14003
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13497
14004
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13512,7 +14019,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13512
14019
|
return Promise.resolve(null);
|
|
13513
14020
|
}
|
|
13514
14021
|
}
|
|
13515
|
-
if (
|
|
14022
|
+
if (isPlainObject4(definition)) {
|
|
13516
14023
|
const firstArg = args[0];
|
|
13517
14024
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13518
14025
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13524,7 +14031,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13524
14031
|
return Promise.resolve(null);
|
|
13525
14032
|
}
|
|
13526
14033
|
function createFixtureService(definition) {
|
|
13527
|
-
const methods =
|
|
14034
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13528
14035
|
return new Proxy(
|
|
13529
14036
|
{},
|
|
13530
14037
|
{
|
|
@@ -13622,7 +14129,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13622
14129
|
};
|
|
13623
14130
|
}
|
|
13624
14131
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13625
|
-
const scenarioServices =
|
|
14132
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13626
14133
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13627
14134
|
...Object.keys(services),
|
|
13628
14135
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13904,7 +14411,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13904
14411
|
if (itemSchema.kind !== "object") {
|
|
13905
14412
|
return value;
|
|
13906
14413
|
}
|
|
13907
|
-
if (!
|
|
14414
|
+
if (!isPlainObject4(value)) {
|
|
13908
14415
|
errors2.push({
|
|
13909
14416
|
path: displayPath,
|
|
13910
14417
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13939,7 +14446,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13939
14446
|
);
|
|
13940
14447
|
}
|
|
13941
14448
|
case "object": {
|
|
13942
|
-
if (!
|
|
14449
|
+
if (!isPlainObject4(value)) {
|
|
13943
14450
|
errors2.push({
|
|
13944
14451
|
path: displayPath,
|
|
13945
14452
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13970,7 +14477,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13970
14477
|
return result;
|
|
13971
14478
|
}
|
|
13972
14479
|
case "record": {
|
|
13973
|
-
if (!
|
|
14480
|
+
if (!isPlainObject4(value)) {
|
|
13974
14481
|
errors2.push({
|
|
13975
14482
|
path: displayPath,
|
|
13976
14483
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14396,10 +14903,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14396
14903
|
}
|
|
14397
14904
|
}
|
|
14398
14905
|
function isStringRecord(value) {
|
|
14399
|
-
return
|
|
14906
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14400
14907
|
}
|
|
14401
14908
|
function isHttpErrorLike(error3) {
|
|
14402
|
-
if (!
|
|
14909
|
+
if (!isPlainObject4(error3)) {
|
|
14403
14910
|
return false;
|
|
14404
14911
|
}
|
|
14405
14912
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14407,7 +14914,7 @@ function isHttpErrorLike(error3) {
|
|
|
14407
14914
|
}
|
|
14408
14915
|
const request = error3.request;
|
|
14409
14916
|
const response = error3.response;
|
|
14410
|
-
return
|
|
14917
|
+
return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
|
|
14411
14918
|
}
|
|
14412
14919
|
function hasTypedOptionalField(value, field, type2) {
|
|
14413
14920
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14416,7 +14923,7 @@ function isNonEmptyString(value) {
|
|
|
14416
14923
|
return typeof value === "string" && value.trim().length > 0;
|
|
14417
14924
|
}
|
|
14418
14925
|
function isProblemDetailsLike(body) {
|
|
14419
|
-
if (!
|
|
14926
|
+
if (!isPlainObject4(body)) {
|
|
14420
14927
|
return false;
|
|
14421
14928
|
}
|
|
14422
14929
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14437,11 +14944,11 @@ function isProblemDetailsLike(body) {
|
|
|
14437
14944
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14438
14945
|
}
|
|
14439
14946
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14440
|
-
if (!
|
|
14947
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14441
14948
|
return false;
|
|
14442
14949
|
}
|
|
14443
14950
|
return body.errors.every((error3) => {
|
|
14444
|
-
if (!
|
|
14951
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14445
14952
|
return false;
|
|
14446
14953
|
}
|
|
14447
14954
|
if ("path" in error3) {
|
|
@@ -14451,7 +14958,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14451
14958
|
}
|
|
14452
14959
|
}
|
|
14453
14960
|
if ("extensions" in error3) {
|
|
14454
|
-
if (!
|
|
14961
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14455
14962
|
return false;
|
|
14456
14963
|
}
|
|
14457
14964
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14462,7 +14969,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14462
14969
|
});
|
|
14463
14970
|
}
|
|
14464
14971
|
function styleHttpErrorLine(value, style) {
|
|
14465
|
-
return process.stdout.isTTY
|
|
14972
|
+
return process.stdout.isTTY !== true ? value : style(value);
|
|
14466
14973
|
}
|
|
14467
14974
|
function formatHttpErrorStatus(value) {
|
|
14468
14975
|
return styleHttpErrorLine(value, text.error);
|
|
@@ -14499,23 +15006,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14499
15006
|
}).join("\n\n");
|
|
14500
15007
|
}
|
|
14501
15008
|
function formatHttpErrorBody(body) {
|
|
14502
|
-
|
|
14503
|
-
|
|
15009
|
+
const redactedBody = redactHttpBody(body);
|
|
15010
|
+
if (typeof redactedBody === "string") {
|
|
15011
|
+
return redactedBody;
|
|
14504
15012
|
}
|
|
14505
|
-
if (isProblemDetailsLike(
|
|
14506
|
-
return formatProblemDetailsBody(
|
|
15013
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
15014
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14507
15015
|
}
|
|
14508
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14509
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
15016
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
15017
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14510
15018
|
}
|
|
14511
|
-
const serialized = JSON.stringify(
|
|
14512
|
-
return serialized === void 0 ? String(
|
|
15019
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
15020
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14513
15021
|
}
|
|
14514
15022
|
function indentHttpErrorBlock(value) {
|
|
14515
15023
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14516
15024
|
}
|
|
14517
15025
|
function formatHttpHeaderValue(name, value) {
|
|
14518
|
-
return name
|
|
15026
|
+
return redactHttpHeaderValue(name, value);
|
|
14519
15027
|
}
|
|
14520
15028
|
function formatHttpErrorHeaders(headers) {
|
|
14521
15029
|
return Object.entries(headers).map(
|
|
@@ -14533,7 +15041,11 @@ function renderHttpError(error3, options) {
|
|
|
14533
15041
|
if (detailed) {
|
|
14534
15042
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14535
15043
|
if (error3.request.body !== void 0) {
|
|
14536
|
-
lines.push(
|
|
15044
|
+
lines.push(
|
|
15045
|
+
"Request body:",
|
|
15046
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
15047
|
+
""
|
|
15048
|
+
);
|
|
14537
15049
|
}
|
|
14538
15050
|
}
|
|
14539
15051
|
lines.push(
|
|
@@ -14939,7 +15451,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14939
15451
|
}
|
|
14940
15452
|
|
|
14941
15453
|
// src/terminal-pilot.ts
|
|
14942
|
-
import { randomUUID as
|
|
15454
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
14943
15455
|
|
|
14944
15456
|
// src/terminal-session.ts
|
|
14945
15457
|
import { EventEmitter } from "node:events";
|
|
@@ -14948,6 +15460,11 @@ import { createRequire } from "node:module";
|
|
|
14948
15460
|
import { dirname, join } from "node:path";
|
|
14949
15461
|
import * as nodePty from "node-pty";
|
|
14950
15462
|
|
|
15463
|
+
// src/errors.ts
|
|
15464
|
+
function hasOwnErrorCode(error3, code) {
|
|
15465
|
+
return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
|
|
15466
|
+
}
|
|
15467
|
+
|
|
14951
15468
|
// src/terminal-buffer.ts
|
|
14952
15469
|
var RESET_SGR = "\x1B[0m";
|
|
14953
15470
|
var DEC_SPECIAL_GRAPHICS = {
|
|
@@ -16047,10 +16564,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
16047
16564
|
}
|
|
16048
16565
|
}
|
|
16049
16566
|
function isMissingFileError(error3) {
|
|
16050
|
-
|
|
16051
|
-
return false;
|
|
16052
|
-
}
|
|
16053
|
-
return "code" in error3 && error3.code === "ENOENT";
|
|
16567
|
+
return hasOwnErrorCode(error3, "ENOENT");
|
|
16054
16568
|
}
|
|
16055
16569
|
function matchPattern(buffer, pattern) {
|
|
16056
16570
|
const clean = normalizeHistoryBuffer(stripAnsi(buffer));
|
|
@@ -16141,7 +16655,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
16141
16655
|
}
|
|
16142
16656
|
async newSession(opts) {
|
|
16143
16657
|
const session = new TerminalSession({
|
|
16144
|
-
id:
|
|
16658
|
+
id: randomUUID6(),
|
|
16145
16659
|
command: opts.command,
|
|
16146
16660
|
args: opts.args,
|
|
16147
16661
|
cwd: opts.cwd,
|
|
@@ -16427,6 +16941,11 @@ var claudeCodeAgent = {
|
|
|
16427
16941
|
aliases: ["claude"],
|
|
16428
16942
|
binaryName: "claude",
|
|
16429
16943
|
apiShapes: ["anthropic-messages"],
|
|
16944
|
+
otelCapture: {
|
|
16945
|
+
env: {
|
|
16946
|
+
CLAUDE_CODE_ENABLE_TELEMETRY: "1"
|
|
16947
|
+
}
|
|
16948
|
+
},
|
|
16430
16949
|
configPath: "~/.claude/settings.json",
|
|
16431
16950
|
branding: {
|
|
16432
16951
|
colors: {
|
|
@@ -16459,6 +16978,16 @@ var codexAgent = {
|
|
|
16459
16978
|
summary: "Configure Codex to use Poe as the model provider.",
|
|
16460
16979
|
binaryName: "codex",
|
|
16461
16980
|
apiShapes: ["openai-responses"],
|
|
16981
|
+
otelCapture: {
|
|
16982
|
+
args: (endpoint, content) => [
|
|
16983
|
+
"-c",
|
|
16984
|
+
`otel.trace_exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/traces`)},protocol="json"}}`,
|
|
16985
|
+
"-c",
|
|
16986
|
+
`otel.exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/logs`)},protocol="json"}}`,
|
|
16987
|
+
"-c",
|
|
16988
|
+
`otel.log_user_prompt=${content}`
|
|
16989
|
+
]
|
|
16990
|
+
},
|
|
16462
16991
|
configPath: "~/.codex/config.toml",
|
|
16463
16992
|
branding: {
|
|
16464
16993
|
colors: {
|
|
@@ -16494,6 +17023,11 @@ var openCodeAgent = {
|
|
|
16494
17023
|
summary: "Configure OpenCode CLI to use the Poe API.",
|
|
16495
17024
|
binaryName: "opencode",
|
|
16496
17025
|
apiShapes: ["openai-chat-completions"],
|
|
17026
|
+
otelCapture: {
|
|
17027
|
+
env: {
|
|
17028
|
+
OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
|
|
17029
|
+
}
|
|
17030
|
+
},
|
|
16497
17031
|
configPath: "~/.config/opencode/config.json",
|
|
16498
17032
|
branding: {
|
|
16499
17033
|
colors: {
|
|
@@ -16529,6 +17063,7 @@ var gooseAgent = {
|
|
|
16529
17063
|
summary: "Block's open-source AI agent with ACP support.",
|
|
16530
17064
|
binaryName: "goose",
|
|
16531
17065
|
apiShapes: ["openai-chat-completions"],
|
|
17066
|
+
otelCapture: {},
|
|
16532
17067
|
configPath: "~/.config/goose/config.yaml",
|
|
16533
17068
|
branding: {
|
|
16534
17069
|
colors: {
|
|
@@ -16562,6 +17097,12 @@ function freezeAgent(agent) {
|
|
|
16562
17097
|
if (agent.apiShapes !== void 0) {
|
|
16563
17098
|
Object.freeze(agent.apiShapes);
|
|
16564
17099
|
}
|
|
17100
|
+
if (agent.otelCapture?.env !== void 0) {
|
|
17101
|
+
Object.freeze(agent.otelCapture.env);
|
|
17102
|
+
}
|
|
17103
|
+
if (agent.otelCapture !== void 0) {
|
|
17104
|
+
Object.freeze(agent.otelCapture);
|
|
17105
|
+
}
|
|
16565
17106
|
Object.freeze(agent.branding.colors);
|
|
16566
17107
|
Object.freeze(agent.branding);
|
|
16567
17108
|
return Object.freeze(agent);
|
|
@@ -16622,11 +17163,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16622
17163
|
if (!resolvedId) {
|
|
16623
17164
|
return { status: "unknown", input };
|
|
16624
17165
|
}
|
|
16625
|
-
const
|
|
16626
|
-
if (!
|
|
17166
|
+
const config2 = registry[resolvedId];
|
|
17167
|
+
if (!config2) {
|
|
16627
17168
|
return { status: "unsupported", input, id: resolvedId };
|
|
16628
17169
|
}
|
|
16629
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
17170
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16630
17171
|
}
|
|
16631
17172
|
function getAgentConfig(agentId) {
|
|
16632
17173
|
const support = resolveAgentSupport(agentId);
|
|
@@ -16725,6 +17266,7 @@ var templateMutation = {
|
|
|
16725
17266
|
};
|
|
16726
17267
|
|
|
16727
17268
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
17269
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
16728
17270
|
import path17 from "node:path";
|
|
16729
17271
|
|
|
16730
17272
|
// ../config-mutations/src/formats/json.ts
|
|
@@ -16800,7 +17342,7 @@ function merge(base, patch) {
|
|
|
16800
17342
|
if (value === void 0) {
|
|
16801
17343
|
continue;
|
|
16802
17344
|
}
|
|
16803
|
-
const existing = result[key2];
|
|
17345
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
16804
17346
|
if (isConfigObject(existing) && isConfigObject(value)) {
|
|
16805
17347
|
setConfigEntry(result, key2, merge(existing, value));
|
|
16806
17348
|
continue;
|
|
@@ -16928,7 +17470,7 @@ function merge2(base, patch) {
|
|
|
16928
17470
|
if (value === void 0) {
|
|
16929
17471
|
continue;
|
|
16930
17472
|
}
|
|
16931
|
-
const existing = result[key2];
|
|
17473
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
16932
17474
|
if (isConfigObject2(existing) && isConfigObject2(value)) {
|
|
16933
17475
|
setConfigEntry(result, key2, merge2(existing, value));
|
|
16934
17476
|
continue;
|
|
@@ -17008,7 +17550,7 @@ function merge3(base, patch) {
|
|
|
17008
17550
|
if (value === void 0) {
|
|
17009
17551
|
continue;
|
|
17010
17552
|
}
|
|
17011
|
-
const existing = result[key2];
|
|
17553
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
17012
17554
|
if (isConfigObject3(existing) && isConfigObject3(value)) {
|
|
17013
17555
|
setConfigEntry(result, key2, merge3(existing, value));
|
|
17014
17556
|
continue;
|
|
@@ -17145,7 +17687,7 @@ function resolvePath(rawPath, homeDir, pathMapper) {
|
|
|
17145
17687
|
|
|
17146
17688
|
// ../config-mutations/src/fs-utils.ts
|
|
17147
17689
|
function isNotFound(error3) {
|
|
17148
|
-
return typeof error3 === "object" && error3 !== null && "code"
|
|
17690
|
+
return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT";
|
|
17149
17691
|
}
|
|
17150
17692
|
async function readFileIfExists(fs4, target) {
|
|
17151
17693
|
try {
|
|
@@ -17194,6 +17736,7 @@ async function backupInvalidDocument(context, targetPath, content) {
|
|
|
17194
17736
|
return;
|
|
17195
17737
|
} catch (error3) {
|
|
17196
17738
|
if (!isAlreadyExists(error3)) {
|
|
17739
|
+
await context.fs.unlink(backupPath).catch(() => void 0);
|
|
17197
17740
|
throw error3;
|
|
17198
17741
|
}
|
|
17199
17742
|
attempt += 1;
|
|
@@ -17201,7 +17744,7 @@ async function backupInvalidDocument(context, targetPath, content) {
|
|
|
17201
17744
|
}
|
|
17202
17745
|
}
|
|
17203
17746
|
function isAlreadyExists(error3) {
|
|
17204
|
-
return
|
|
17747
|
+
return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
|
|
17205
17748
|
}
|
|
17206
17749
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
17207
17750
|
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
@@ -17225,28 +17768,34 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
17225
17768
|
}
|
|
17226
17769
|
async function writeAtomically2(context, targetPath, content) {
|
|
17227
17770
|
await assertRegularWriteTarget(context, targetPath);
|
|
17228
|
-
let attempt = 0;
|
|
17229
|
-
|
|
17230
|
-
|
|
17771
|
+
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
17772
|
+
const tempPath = `${targetPath}.mutation-tmp-${process.pid}-${randomUUID7()}`;
|
|
17773
|
+
let tempCreated = false;
|
|
17231
17774
|
try {
|
|
17775
|
+
await assertRegularWriteTarget(context, tempPath);
|
|
17232
17776
|
await context.fs.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
17777
|
+
tempCreated = true;
|
|
17233
17778
|
await context.fs.rename(tempPath, targetPath);
|
|
17779
|
+
tempCreated = false;
|
|
17234
17780
|
return;
|
|
17235
17781
|
} catch (error3) {
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
|
|
17239
|
-
|
|
17240
|
-
|
|
17241
|
-
|
|
17242
|
-
|
|
17243
|
-
|
|
17244
|
-
void cleanupError;
|
|
17782
|
+
const alreadyExists = isAlreadyExists(error3);
|
|
17783
|
+
if (tempCreated || !alreadyExists) {
|
|
17784
|
+
try {
|
|
17785
|
+
await context.fs.unlink(tempPath);
|
|
17786
|
+
} catch (cleanupError) {
|
|
17787
|
+
if (!isNotFound(cleanupError)) {
|
|
17788
|
+
void cleanupError;
|
|
17789
|
+
}
|
|
17245
17790
|
}
|
|
17246
17791
|
}
|
|
17792
|
+
if (alreadyExists) {
|
|
17793
|
+
continue;
|
|
17794
|
+
}
|
|
17247
17795
|
throw error3;
|
|
17248
17796
|
}
|
|
17249
17797
|
}
|
|
17798
|
+
throw new Error(`Unable to create temporary mutation file for ${targetPath}.`);
|
|
17250
17799
|
}
|
|
17251
17800
|
function describeMutation(kind, targetPath) {
|
|
17252
17801
|
const displayPath = targetPath ?? "target";
|
|
@@ -17538,6 +18087,7 @@ async function applyBackup(mutation, context, options) {
|
|
|
17538
18087
|
break;
|
|
17539
18088
|
} catch (error3) {
|
|
17540
18089
|
if (!isAlreadyExists(error3)) {
|
|
18090
|
+
await context.fs.unlink(backupPath).catch(() => void 0);
|
|
17541
18091
|
throw error3;
|
|
17542
18092
|
}
|
|
17543
18093
|
attempt += 1;
|
|
@@ -17945,7 +18495,7 @@ async function pathExists2(fs4, targetPath) {
|
|
|
17945
18495
|
await fs4.stat(targetPath);
|
|
17946
18496
|
return true;
|
|
17947
18497
|
} catch (error3) {
|
|
17948
|
-
if (
|
|
18498
|
+
if (typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT") {
|
|
17949
18499
|
return false;
|
|
17950
18500
|
}
|
|
17951
18501
|
throw error3;
|
|
@@ -17958,14 +18508,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17958
18508
|
throw new UnsupportedAgentError(agentId);
|
|
17959
18509
|
}
|
|
17960
18510
|
const scope = options.scope ?? "local";
|
|
17961
|
-
const
|
|
18511
|
+
const config2 = support.config;
|
|
17962
18512
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17963
18513
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17964
18514
|
}
|
|
17965
|
-
const skillDir = scope === "global" ?
|
|
18515
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17966
18516
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17967
18517
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17968
|
-
const displayPath = `${scope === "global" ?
|
|
18518
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17969
18519
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17970
18520
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17971
18521
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -18004,12 +18554,13 @@ import path19 from "node:path";
|
|
|
18004
18554
|
|
|
18005
18555
|
// ../agent-skill-config/src/git-exclude.ts
|
|
18006
18556
|
import { execFileSync } from "node:child_process";
|
|
18557
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
18007
18558
|
import * as fs2 from "node:fs";
|
|
18008
18559
|
import path20 from "node:path";
|
|
18009
18560
|
|
|
18010
18561
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
18011
18562
|
import * as fs3 from "node:fs";
|
|
18012
|
-
import { createHash as createHash4, randomUUID as
|
|
18563
|
+
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
18013
18564
|
import path21 from "node:path";
|
|
18014
18565
|
|
|
18015
18566
|
// src/commands/installer.ts
|
|
@@ -18022,7 +18573,7 @@ var DEFAULT_INSTALL_SCOPE = "local";
|
|
|
18022
18573
|
var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
|
|
18023
18574
|
var installableAgents = supportedAgents;
|
|
18024
18575
|
function isNotFoundError2(error3) {
|
|
18025
|
-
return
|
|
18576
|
+
return hasOwnErrorCode(error3, "ENOENT");
|
|
18026
18577
|
}
|
|
18027
18578
|
function resolveInstallerServices(installer) {
|
|
18028
18579
|
return {
|
|
@@ -18086,17 +18637,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
18086
18637
|
return targetPath;
|
|
18087
18638
|
}
|
|
18088
18639
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
18089
|
-
const
|
|
18090
|
-
if (!
|
|
18640
|
+
const config2 = getAgentConfig(agent);
|
|
18641
|
+
if (!config2) {
|
|
18091
18642
|
throwUnsupportedAgent(agent);
|
|
18092
18643
|
}
|
|
18093
18644
|
return {
|
|
18094
18645
|
displayPath: path22.join(
|
|
18095
|
-
scope === "global" ?
|
|
18646
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
18096
18647
|
TERMINAL_PILOT_SKILL_NAME
|
|
18097
18648
|
),
|
|
18098
18649
|
fullPath: path22.join(
|
|
18099
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18650
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
18100
18651
|
TERMINAL_PILOT_SKILL_NAME
|
|
18101
18652
|
)
|
|
18102
18653
|
};
|
|
@@ -18253,7 +18804,7 @@ var resize = defineCommand({
|
|
|
18253
18804
|
});
|
|
18254
18805
|
|
|
18255
18806
|
// ../terminal-png/src/index.ts
|
|
18256
|
-
import { randomUUID as
|
|
18807
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
18257
18808
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
18258
18809
|
|
|
18259
18810
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -19193,21 +19744,28 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
19193
19744
|
});
|
|
19194
19745
|
const png = renderPng(svg);
|
|
19195
19746
|
if (options.output) {
|
|
19196
|
-
const temporaryPath = `${options.output}.${
|
|
19747
|
+
const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
|
|
19748
|
+
let temporaryCreated = false;
|
|
19197
19749
|
try {
|
|
19198
19750
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
19751
|
+
temporaryCreated = true;
|
|
19199
19752
|
await rename4(temporaryPath, options.output);
|
|
19200
19753
|
} catch (error3) {
|
|
19201
|
-
|
|
19202
|
-
|
|
19203
|
-
|
|
19204
|
-
|
|
19754
|
+
if (temporaryCreated || !isAlreadyExistsError3(error3)) {
|
|
19755
|
+
try {
|
|
19756
|
+
await rm(temporaryPath, { force: true });
|
|
19757
|
+
} catch (cleanupError) {
|
|
19758
|
+
void cleanupError;
|
|
19759
|
+
}
|
|
19205
19760
|
}
|
|
19206
19761
|
throw error3;
|
|
19207
19762
|
}
|
|
19208
19763
|
}
|
|
19209
19764
|
return png;
|
|
19210
19765
|
}
|
|
19766
|
+
function isAlreadyExistsError3(error3) {
|
|
19767
|
+
return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
|
|
19768
|
+
}
|
|
19211
19769
|
|
|
19212
19770
|
// src/commands/screenshot.ts
|
|
19213
19771
|
var params11 = S.Object({
|
|
@@ -19270,7 +19828,7 @@ var type = defineCommand({
|
|
|
19270
19828
|
});
|
|
19271
19829
|
|
|
19272
19830
|
// src/commands/uninstall.ts
|
|
19273
|
-
import { randomUUID as
|
|
19831
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
19274
19832
|
var params14 = S.Object({
|
|
19275
19833
|
agent: S.Enum(installableAgents, {
|
|
19276
19834
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19306,7 +19864,7 @@ var uninstall = defineCommand({
|
|
|
19306
19864
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19307
19865
|
continue;
|
|
19308
19866
|
}
|
|
19309
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19867
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID11()}`;
|
|
19310
19868
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19311
19869
|
staged.push({ ...skill, stagingPath });
|
|
19312
19870
|
}
|
|
@@ -19332,7 +19890,7 @@ async function folderExists(fs4, folderPath) {
|
|
|
19332
19890
|
await fs4.stat(folderPath);
|
|
19333
19891
|
return true;
|
|
19334
19892
|
} catch (error3) {
|
|
19335
|
-
if (
|
|
19893
|
+
if (hasOwnErrorCode(error3, "ENOENT")) {
|
|
19336
19894
|
return false;
|
|
19337
19895
|
}
|
|
19338
19896
|
throw error3;
|
|
@@ -19413,6 +19971,7 @@ function createTerminalPilotGroup() {
|
|
|
19413
19971
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19414
19972
|
|
|
19415
19973
|
// src/cli.ts
|
|
19974
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19416
19975
|
function normalizeArgv(argv) {
|
|
19417
19976
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19418
19977
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19436,8 +19995,8 @@ async function isDirectExecution(argv) {
|
|
|
19436
19995
|
try {
|
|
19437
19996
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19438
19997
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19439
|
-
|
|
19440
|
-
|
|
19998
|
+
realpath3(path23.resolve(entryPoint)),
|
|
19999
|
+
realpath3(modulePath)
|
|
19441
20000
|
]);
|
|
19442
20001
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19443
20002
|
} catch {
|