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/qa-cli.js
CHANGED
|
@@ -85,12 +85,12 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// src/cli.ts
|
|
88
|
-
import { realpath as
|
|
88
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
89
89
|
import path23 from "node:path";
|
|
90
90
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
91
91
|
|
|
92
92
|
// ../toolcraft/src/cli.ts
|
|
93
|
-
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as
|
|
93
|
+
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
94
94
|
import path14 from "node:path";
|
|
95
95
|
import {
|
|
96
96
|
Command as CommanderCommand,
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
Option
|
|
100
100
|
} from "commander";
|
|
101
101
|
|
|
102
|
-
// ../design
|
|
102
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
103
103
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
104
104
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
105
105
|
return true;
|
|
@@ -113,7 +113,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
113
113
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
// ../design
|
|
116
|
+
// ../toolcraft-design/src/components/color.ts
|
|
117
117
|
var reset = "\x1B[0m";
|
|
118
118
|
var ansiStyles = {
|
|
119
119
|
reset: { open: reset },
|
|
@@ -215,41 +215,135 @@ function createColor(styles = []) {
|
|
|
215
215
|
}
|
|
216
216
|
var color = createColor();
|
|
217
217
|
|
|
218
|
-
// ../design
|
|
219
|
-
var
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
number: (text5) => color.cyanBright(text5),
|
|
224
|
-
intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
|
|
225
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
226
|
-
errorSymbol: color.red("\u25A0"),
|
|
227
|
-
accent: (text5) => color.cyan(text5),
|
|
228
|
-
muted: (text5) => color.dim(text5),
|
|
229
|
-
success: (text5) => color.green(text5),
|
|
230
|
-
warning: (text5) => color.yellow(text5),
|
|
231
|
-
error: (text5) => color.red(text5),
|
|
232
|
-
info: (text5) => color.magenta(text5),
|
|
233
|
-
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
218
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
219
|
+
var brands = {
|
|
220
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
221
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
222
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
234
223
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
|
|
241
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
242
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
243
|
-
accent: (text5) => color.hex("#006699").bold(text5),
|
|
244
|
-
muted: (text5) => color.hex("#666666")(text5),
|
|
245
|
-
success: (text5) => color.hex("#008800")(text5),
|
|
246
|
-
warning: (text5) => color.hex("#cc6600")(text5),
|
|
247
|
-
error: (text5) => color.hex("#cc0000")(text5),
|
|
248
|
-
info: (text5) => color.hex("#a200ff")(text5),
|
|
249
|
-
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
224
|
+
|
|
225
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
226
|
+
var defaults = {
|
|
227
|
+
brand: "purple",
|
|
228
|
+
label: "Poe"
|
|
250
229
|
};
|
|
230
|
+
var config = { ...defaults };
|
|
231
|
+
var revision = 0;
|
|
232
|
+
var brandConfigured = false;
|
|
233
|
+
function configureTheme(patch) {
|
|
234
|
+
if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
|
|
235
|
+
throw new Error(`Unknown brand: ${patch.brand}`);
|
|
236
|
+
}
|
|
237
|
+
config = {
|
|
238
|
+
brand: patch.brand ?? config.brand,
|
|
239
|
+
label: patch.label ?? config.label
|
|
240
|
+
};
|
|
241
|
+
if (patch.brand !== void 0) {
|
|
242
|
+
brandConfigured = true;
|
|
243
|
+
}
|
|
244
|
+
revision += 1;
|
|
245
|
+
}
|
|
246
|
+
function getThemeConfig() {
|
|
247
|
+
return { ...config };
|
|
248
|
+
}
|
|
249
|
+
function getThemeRevision() {
|
|
250
|
+
return revision;
|
|
251
|
+
}
|
|
252
|
+
function isThemeBrandConfigured() {
|
|
253
|
+
return brandConfigured;
|
|
254
|
+
}
|
|
251
255
|
|
|
252
|
-
// ../design
|
|
256
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
257
|
+
var brand = brands.purple.primary;
|
|
258
|
+
function withStyles(palette, styles) {
|
|
259
|
+
return Object.defineProperty(palette, "styles", {
|
|
260
|
+
value: styles,
|
|
261
|
+
enumerable: false
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function brandColor(activeBrand, purple) {
|
|
265
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
266
|
+
}
|
|
267
|
+
function brandBackground(activeBrand, purple) {
|
|
268
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
269
|
+
}
|
|
270
|
+
function createPalette(activeBrand, mode) {
|
|
271
|
+
const isPurple = activeBrand.name === "purple";
|
|
272
|
+
if (mode === "light") {
|
|
273
|
+
const active2 = color.hex(activeBrand.primary);
|
|
274
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
275
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
276
|
+
return withStyles(
|
|
277
|
+
{
|
|
278
|
+
header: (text5) => active2.bold(text5),
|
|
279
|
+
divider: (text5) => color.hex("#666666")(text5),
|
|
280
|
+
prompt: (text5) => prompt2.bold(text5),
|
|
281
|
+
number: (text5) => number2.bold(text5),
|
|
282
|
+
intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
|
|
283
|
+
get resolvedSymbol() {
|
|
284
|
+
return active2("\u25C7");
|
|
285
|
+
},
|
|
286
|
+
get errorSymbol() {
|
|
287
|
+
return color.hex("#cc0000")("\u25A0");
|
|
288
|
+
},
|
|
289
|
+
accent: (text5) => prompt2.bold(text5),
|
|
290
|
+
muted: (text5) => color.hex("#666666")(text5),
|
|
291
|
+
success: (text5) => color.hex("#008800")(text5),
|
|
292
|
+
warning: (text5) => color.hex("#cc6600")(text5),
|
|
293
|
+
error: (text5) => color.hex("#cc0000")(text5),
|
|
294
|
+
info: (text5) => active2(text5),
|
|
295
|
+
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
299
|
+
muted: { fg: "#666666" },
|
|
300
|
+
success: { fg: "#008800" },
|
|
301
|
+
warning: { fg: "#cc6600" },
|
|
302
|
+
error: { fg: "#cc0000" },
|
|
303
|
+
info: { fg: activeBrand.primary }
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
308
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
309
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
310
|
+
const prompt = isPurple ? color.cyan : active;
|
|
311
|
+
const number = isPurple ? color.cyanBright : active;
|
|
312
|
+
return withStyles(
|
|
313
|
+
{
|
|
314
|
+
header: (text5) => activeBright.bold(text5),
|
|
315
|
+
divider: (text5) => color.dim(text5),
|
|
316
|
+
prompt: (text5) => prompt(text5),
|
|
317
|
+
number: (text5) => number(text5),
|
|
318
|
+
intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
|
|
319
|
+
get resolvedSymbol() {
|
|
320
|
+
return active("\u25C7");
|
|
321
|
+
},
|
|
322
|
+
get errorSymbol() {
|
|
323
|
+
return color.red("\u25A0");
|
|
324
|
+
},
|
|
325
|
+
accent: (text5) => prompt(text5),
|
|
326
|
+
muted: (text5) => color.dim(text5),
|
|
327
|
+
success: (text5) => color.green(text5),
|
|
328
|
+
warning: (text5) => color.yellow(text5),
|
|
329
|
+
error: (text5) => color.red(text5),
|
|
330
|
+
info: (text5) => active(text5),
|
|
331
|
+
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
335
|
+
muted: { dim: true },
|
|
336
|
+
success: { fg: "green" },
|
|
337
|
+
warning: { fg: "yellow" },
|
|
338
|
+
error: { fg: "red" },
|
|
339
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
var dark = createPalette(brands.purple, "dark");
|
|
344
|
+
var light = createPalette(brands.purple, "light");
|
|
345
|
+
|
|
346
|
+
// ../toolcraft-design/src/tokens/typography.ts
|
|
253
347
|
var typography = {
|
|
254
348
|
bold: (text5) => color.bold(text5),
|
|
255
349
|
dim: (text5) => color.dim(text5),
|
|
@@ -258,14 +352,14 @@ var typography = {
|
|
|
258
352
|
strikethrough: (text5) => color.strikethrough(text5)
|
|
259
353
|
};
|
|
260
354
|
|
|
261
|
-
// ../design
|
|
355
|
+
// ../toolcraft-design/src/tokens/widths.ts
|
|
262
356
|
var widths = {
|
|
263
357
|
header: 60,
|
|
264
358
|
helpColumn: 24,
|
|
265
359
|
maxLine: 80
|
|
266
360
|
};
|
|
267
361
|
|
|
268
|
-
// ../design
|
|
362
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
269
363
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
270
364
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
271
365
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -286,7 +380,7 @@ function resetOutputFormatCache() {
|
|
|
286
380
|
cached = void 0;
|
|
287
381
|
}
|
|
288
382
|
|
|
289
|
-
// ../design
|
|
383
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
290
384
|
function detectThemeFromEnv(env) {
|
|
291
385
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
292
386
|
if (typeof apple === "string") {
|
|
@@ -323,17 +417,30 @@ function resolveThemeName(env = process.env) {
|
|
|
323
417
|
}
|
|
324
418
|
return "dark";
|
|
325
419
|
}
|
|
326
|
-
var
|
|
420
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
421
|
+
var cachedRevision = -1;
|
|
327
422
|
function getTheme(env) {
|
|
423
|
+
const themeName = resolveThemeName(env);
|
|
424
|
+
const config2 = getThemeConfig();
|
|
425
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
426
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
427
|
+
const revision2 = getThemeRevision();
|
|
428
|
+
if (revision2 !== cachedRevision) {
|
|
429
|
+
themeCache.clear();
|
|
430
|
+
cachedRevision = revision2;
|
|
431
|
+
}
|
|
432
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
433
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
328
434
|
if (cachedTheme) {
|
|
329
435
|
return cachedTheme;
|
|
330
436
|
}
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
437
|
+
const activeBrand = brands[activeBrandName];
|
|
438
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
439
|
+
themeCache.set(cacheKey, theme);
|
|
440
|
+
return theme;
|
|
334
441
|
}
|
|
335
442
|
|
|
336
|
-
// ../design
|
|
443
|
+
// ../toolcraft-design/src/components/text.ts
|
|
337
444
|
function renderMarkdownInline(content) {
|
|
338
445
|
return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
339
446
|
}
|
|
@@ -449,7 +556,7 @@ var text = {
|
|
|
449
556
|
}
|
|
450
557
|
};
|
|
451
558
|
|
|
452
|
-
// ../design
|
|
559
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
453
560
|
var symbols = {
|
|
454
561
|
get info() {
|
|
455
562
|
const format = resolveOutputFormat();
|
|
@@ -503,12 +610,12 @@ var symbols = {
|
|
|
503
610
|
}
|
|
504
611
|
};
|
|
505
612
|
|
|
506
|
-
// ../design
|
|
613
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
507
614
|
function stripAnsi2(value) {
|
|
508
615
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
509
616
|
}
|
|
510
617
|
|
|
511
|
-
// ../design
|
|
618
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
512
619
|
function renderMarkdownInline2(value) {
|
|
513
620
|
return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
514
621
|
}
|
|
@@ -635,7 +742,7 @@ var log = {
|
|
|
635
742
|
error
|
|
636
743
|
};
|
|
637
744
|
|
|
638
|
-
// ../design
|
|
745
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
639
746
|
function createLogger(emitter) {
|
|
640
747
|
const emit = (level, message2) => {
|
|
641
748
|
if (emitter) {
|
|
@@ -696,7 +803,7 @@ function createLogger(emitter) {
|
|
|
696
803
|
}
|
|
697
804
|
var logger = createLogger();
|
|
698
805
|
|
|
699
|
-
// ../design
|
|
806
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
700
807
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
701
808
|
function normalizeInline(value) {
|
|
702
809
|
return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
@@ -872,7 +979,7 @@ function formatOptionList(options) {
|
|
|
872
979
|
});
|
|
873
980
|
}
|
|
874
981
|
|
|
875
|
-
// ../design
|
|
982
|
+
// ../toolcraft-design/src/components/help-formatter-plain.ts
|
|
876
983
|
var help_formatter_plain_exports = {};
|
|
877
984
|
__export(help_formatter_plain_exports, {
|
|
878
985
|
formatColumns: () => formatColumns2,
|
|
@@ -1009,7 +1116,7 @@ function formatOptionList2(options) {
|
|
|
1009
1116
|
});
|
|
1010
1117
|
}
|
|
1011
1118
|
|
|
1012
|
-
// ../design
|
|
1119
|
+
// ../toolcraft-design/src/components/table.ts
|
|
1013
1120
|
var reset2 = "\x1B[0m";
|
|
1014
1121
|
var ellipsis = "\u2026";
|
|
1015
1122
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -1293,7 +1400,7 @@ function renderTable(options) {
|
|
|
1293
1400
|
}
|
|
1294
1401
|
}
|
|
1295
1402
|
|
|
1296
|
-
// ../design
|
|
1403
|
+
// ../toolcraft-design/src/components/detail-card.ts
|
|
1297
1404
|
function wrap(value, width) {
|
|
1298
1405
|
const lines = [];
|
|
1299
1406
|
for (const paragraph of value.split("\n")) {
|
|
@@ -1356,7 +1463,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1356
1463
|
return blocks.join("\n\n");
|
|
1357
1464
|
}
|
|
1358
1465
|
|
|
1359
|
-
// ../design
|
|
1466
|
+
// ../toolcraft-design/src/components/template.ts
|
|
1360
1467
|
var MAX_PARTIAL_DEPTH = 100;
|
|
1361
1468
|
var HTML_ESCAPE = {
|
|
1362
1469
|
"&": "&",
|
|
@@ -1768,22 +1875,22 @@ function hasProperty(value, key2) {
|
|
|
1768
1875
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1769
1876
|
}
|
|
1770
1877
|
|
|
1771
|
-
// ../design
|
|
1878
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1772
1879
|
import { spawn } from "node:child_process";
|
|
1773
1880
|
import process2 from "node:process";
|
|
1774
1881
|
|
|
1775
|
-
// ../design
|
|
1882
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1776
1883
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1777
1884
|
var storage = new AsyncLocalStorage2();
|
|
1778
1885
|
|
|
1779
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1780
1887
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1781
1888
|
|
|
1782
|
-
// ../design
|
|
1889
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1783
1890
|
import readline from "node:readline";
|
|
1784
1891
|
import { PassThrough } from "node:stream";
|
|
1785
1892
|
|
|
1786
|
-
// ../design
|
|
1893
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1787
1894
|
var REGION_HEADER = 1 << 0;
|
|
1788
1895
|
var REGION_LIST = 1 << 1;
|
|
1789
1896
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1792,10 +1899,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1792
1899
|
var REGION_TOAST = 1 << 5;
|
|
1793
1900
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1794
1901
|
|
|
1795
|
-
// ../design
|
|
1902
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1796
1903
|
import * as clack from "@clack/prompts";
|
|
1797
1904
|
|
|
1798
|
-
// ../design
|
|
1905
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1799
1906
|
import { isCancel } from "@clack/prompts";
|
|
1800
1907
|
function cancel(msg = "") {
|
|
1801
1908
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1806,7 +1913,7 @@ function cancel(msg = "") {
|
|
|
1806
1913
|
`);
|
|
1807
1914
|
}
|
|
1808
1915
|
|
|
1809
|
-
// ../design
|
|
1916
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1810
1917
|
function getVisibleWidth(value) {
|
|
1811
1918
|
return stripAnsi2(value).length;
|
|
1812
1919
|
}
|
|
@@ -1855,10 +1962,10 @@ function note(message2, title) {
|
|
|
1855
1962
|
`);
|
|
1856
1963
|
}
|
|
1857
1964
|
|
|
1858
|
-
// ../design
|
|
1965
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1859
1966
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1860
1967
|
|
|
1861
|
-
// ../design
|
|
1968
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1862
1969
|
async function select2(opts) {
|
|
1863
1970
|
return clack.select(opts);
|
|
1864
1971
|
}
|
|
@@ -1901,19 +2008,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1901
2008
|
};
|
|
1902
2009
|
|
|
1903
2010
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1904
|
-
function validateHumanInLoopOnDefine(
|
|
1905
|
-
const label = Array.isArray(
|
|
1906
|
-
if (
|
|
1907
|
-
throw new Error(`${label} '${
|
|
2011
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
2012
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
2013
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
2014
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
1908
2015
|
}
|
|
1909
|
-
if (
|
|
2016
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1910
2017
|
return;
|
|
1911
2018
|
}
|
|
1912
|
-
if (
|
|
1913
|
-
throw new Error(`${label} '${
|
|
2019
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
2020
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
1914
2021
|
}
|
|
1915
|
-
if (typeof
|
|
1916
|
-
throw new Error(`${label} '${
|
|
2022
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
2023
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1917
2024
|
}
|
|
1918
2025
|
}
|
|
1919
2026
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1989,12 +2096,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1989
2096
|
}
|
|
1990
2097
|
}
|
|
1991
2098
|
}
|
|
1992
|
-
function OneOf(
|
|
1993
|
-
assertValidBranches(
|
|
2099
|
+
function OneOf(config2) {
|
|
2100
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1994
2101
|
return {
|
|
1995
2102
|
kind: "oneOf",
|
|
1996
|
-
discriminator:
|
|
1997
|
-
branches:
|
|
2103
|
+
discriminator: config2.discriminator,
|
|
2104
|
+
branches: config2.branches
|
|
1998
2105
|
};
|
|
1999
2106
|
}
|
|
2000
2107
|
|
|
@@ -2244,22 +2351,22 @@ function cloneStringArray(values) {
|
|
|
2244
2351
|
function cloneStringRecord(values) {
|
|
2245
2352
|
return values === void 0 ? void 0 : { ...values };
|
|
2246
2353
|
}
|
|
2247
|
-
function cloneMcpServerConfig(
|
|
2248
|
-
if (
|
|
2354
|
+
function cloneMcpServerConfig(config2) {
|
|
2355
|
+
if (config2 === void 0) {
|
|
2249
2356
|
return void 0;
|
|
2250
2357
|
}
|
|
2251
|
-
if (
|
|
2358
|
+
if (config2.transport === "stdio") {
|
|
2252
2359
|
return {
|
|
2253
2360
|
transport: "stdio",
|
|
2254
|
-
command:
|
|
2255
|
-
args: cloneStringArray(
|
|
2256
|
-
env: cloneStringRecord(
|
|
2361
|
+
command: config2.command,
|
|
2362
|
+
args: cloneStringArray(config2.args),
|
|
2363
|
+
env: cloneStringRecord(config2.env)
|
|
2257
2364
|
};
|
|
2258
2365
|
}
|
|
2259
2366
|
return {
|
|
2260
2367
|
transport: "http",
|
|
2261
|
-
url:
|
|
2262
|
-
headers: cloneStringRecord(
|
|
2368
|
+
url: config2.url,
|
|
2369
|
+
headers: cloneStringRecord(config2.headers)
|
|
2263
2370
|
};
|
|
2264
2371
|
}
|
|
2265
2372
|
function cloneRenameMap(rename5) {
|
|
@@ -2500,57 +2607,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2500
2607
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2501
2608
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2502
2609
|
}
|
|
2503
|
-
function createBaseCommand(
|
|
2610
|
+
function createBaseCommand(config2) {
|
|
2504
2611
|
const command = {
|
|
2505
2612
|
kind: "command",
|
|
2506
|
-
name:
|
|
2507
|
-
description:
|
|
2508
|
-
aliases: [...
|
|
2509
|
-
positional: [...
|
|
2510
|
-
params:
|
|
2511
|
-
secrets: cloneSecrets(
|
|
2512
|
-
scope: resolveCommandScope(
|
|
2513
|
-
confirm:
|
|
2514
|
-
humanInLoop:
|
|
2515
|
-
requires: cloneRequires(
|
|
2516
|
-
handler:
|
|
2517
|
-
render:
|
|
2613
|
+
name: config2.name,
|
|
2614
|
+
description: config2.description,
|
|
2615
|
+
aliases: [...config2.aliases ?? []],
|
|
2616
|
+
positional: [...config2.positional ?? []],
|
|
2617
|
+
params: config2.params,
|
|
2618
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2619
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
2620
|
+
confirm: config2.confirm ?? false,
|
|
2621
|
+
humanInLoop: config2.humanInLoop,
|
|
2622
|
+
requires: cloneRequires(config2.requires),
|
|
2623
|
+
handler: config2.handler,
|
|
2624
|
+
render: config2.render
|
|
2518
2625
|
};
|
|
2519
2626
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2520
2627
|
value: {
|
|
2521
|
-
scope: cloneScope(
|
|
2522
|
-
humanInLoop:
|
|
2523
|
-
secrets: cloneSecrets(
|
|
2524
|
-
requires: cloneRequires(
|
|
2628
|
+
scope: cloneScope(config2.scope),
|
|
2629
|
+
humanInLoop: config2.humanInLoop,
|
|
2630
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2631
|
+
requires: cloneRequires(config2.requires),
|
|
2525
2632
|
sourcePath: inferCommandSourcePath()
|
|
2526
2633
|
}
|
|
2527
2634
|
});
|
|
2528
2635
|
return command;
|
|
2529
2636
|
}
|
|
2530
|
-
function createBaseGroup(
|
|
2637
|
+
function createBaseGroup(config2) {
|
|
2531
2638
|
const group = {
|
|
2532
2639
|
kind: "group",
|
|
2533
|
-
name:
|
|
2534
|
-
description:
|
|
2535
|
-
aliases: [...
|
|
2536
|
-
scope: resolveGroupScope(
|
|
2537
|
-
humanInLoop:
|
|
2538
|
-
secrets: cloneSecrets(
|
|
2539
|
-
requires: cloneRequires(
|
|
2640
|
+
name: config2.name,
|
|
2641
|
+
description: config2.description,
|
|
2642
|
+
aliases: [...config2.aliases ?? []],
|
|
2643
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
2644
|
+
humanInLoop: config2.humanInLoop,
|
|
2645
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2646
|
+
requires: cloneRequires(config2.requires),
|
|
2540
2647
|
children: [],
|
|
2541
2648
|
default: void 0
|
|
2542
2649
|
};
|
|
2543
2650
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2544
2651
|
value: {
|
|
2545
|
-
mcp: cloneMcpServerConfig(
|
|
2546
|
-
scope: cloneScope(
|
|
2547
|
-
humanInLoop:
|
|
2548
|
-
secrets: cloneSecrets(
|
|
2549
|
-
tools: cloneStringArray(
|
|
2550
|
-
rename: cloneRenameMap(
|
|
2551
|
-
requires: cloneRequires(
|
|
2552
|
-
children: [...
|
|
2553
|
-
default:
|
|
2652
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
2653
|
+
scope: cloneScope(config2.scope),
|
|
2654
|
+
humanInLoop: config2.humanInLoop,
|
|
2655
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2656
|
+
tools: cloneStringArray(config2.tools),
|
|
2657
|
+
rename: cloneRenameMap(config2.rename),
|
|
2658
|
+
requires: cloneRequires(config2.requires),
|
|
2659
|
+
children: [...config2.children],
|
|
2660
|
+
default: config2.default
|
|
2554
2661
|
}
|
|
2555
2662
|
});
|
|
2556
2663
|
return group;
|
|
@@ -2653,10 +2760,10 @@ function materializeNode(node, inherited) {
|
|
|
2653
2760
|
}
|
|
2654
2761
|
return materializeGroup(node, inherited);
|
|
2655
2762
|
}
|
|
2656
|
-
function defineCommand(
|
|
2657
|
-
validateHumanInLoopOnDefine(
|
|
2763
|
+
function defineCommand(config2) {
|
|
2764
|
+
validateHumanInLoopOnDefine(config2);
|
|
2658
2765
|
return materializeCommand(
|
|
2659
|
-
createBaseCommand(
|
|
2766
|
+
createBaseCommand(config2),
|
|
2660
2767
|
{
|
|
2661
2768
|
scope: void 0,
|
|
2662
2769
|
humanInLoop: void 0,
|
|
@@ -2665,10 +2772,10 @@ function defineCommand(config) {
|
|
|
2665
2772
|
}
|
|
2666
2773
|
);
|
|
2667
2774
|
}
|
|
2668
|
-
function defineGroup(
|
|
2669
|
-
validateRenameMap(
|
|
2670
|
-
validateHumanInLoopOnDefine(
|
|
2671
|
-
return materializeGroup(createBaseGroup(
|
|
2775
|
+
function defineGroup(config2) {
|
|
2776
|
+
validateRenameMap(config2.rename);
|
|
2777
|
+
validateHumanInLoopOnDefine(config2);
|
|
2778
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2672
2779
|
scope: void 0,
|
|
2673
2780
|
humanInLoop: void 0,
|
|
2674
2781
|
secrets: {},
|
|
@@ -2699,27 +2806,27 @@ function validateMachine(machine) {
|
|
|
2699
2806
|
if (!isRecord(machine)) {
|
|
2700
2807
|
throw new TypeError("State machine must be an object.");
|
|
2701
2808
|
}
|
|
2702
|
-
if (!isStateList(machine.states)) {
|
|
2809
|
+
if (!hasOwnRecordField(machine, "states") || !isStateList(machine.states)) {
|
|
2703
2810
|
throw new TypeError("State machine states must be a string array.");
|
|
2704
2811
|
}
|
|
2705
2812
|
const states = new Set(machine.states);
|
|
2706
|
-
if (typeof machine.initial !== "string") {
|
|
2813
|
+
if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
|
|
2707
2814
|
throw new TypeError("State machine initial must be a string.");
|
|
2708
2815
|
}
|
|
2709
2816
|
if (!states.has(machine.initial)) {
|
|
2710
2817
|
throw new Error(`Initial state "${machine.initial}" is not declared.`);
|
|
2711
2818
|
}
|
|
2712
|
-
if (!isRecord(machine.events)) {
|
|
2819
|
+
if (!hasOwnRecordField(machine, "events") || !isRecord(machine.events)) {
|
|
2713
2820
|
throw new TypeError("State machine events must be an object.");
|
|
2714
2821
|
}
|
|
2715
2822
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
2716
2823
|
if (!isRecord(event)) {
|
|
2717
2824
|
throw new TypeError(`Event "${eventName}" must be an object.`);
|
|
2718
2825
|
}
|
|
2719
|
-
if (event.from !== "*" && !isStateList(event.from)) {
|
|
2826
|
+
if (!hasOwnRecordField(event, "from") || event.from !== "*" && !isStateList(event.from)) {
|
|
2720
2827
|
throw new TypeError(`Event "${eventName}" has an invalid "from" definition.`);
|
|
2721
2828
|
}
|
|
2722
|
-
if (typeof event.to !== "string") {
|
|
2829
|
+
if (!hasOwnRecordField(event, "to") || typeof event.to !== "string") {
|
|
2723
2830
|
throw new TypeError(`Event "${eventName}" target state must be a string.`);
|
|
2724
2831
|
}
|
|
2725
2832
|
if (!states.has(event.to)) {
|
|
@@ -2734,6 +2841,9 @@ function validateMachine(machine) {
|
|
|
2734
2841
|
}
|
|
2735
2842
|
}
|
|
2736
2843
|
}
|
|
2844
|
+
function hasOwnRecordField(record, key2) {
|
|
2845
|
+
return Object.prototype.hasOwnProperty.call(record, key2);
|
|
2846
|
+
}
|
|
2737
2847
|
function eventsFromState(machine, fromState) {
|
|
2738
2848
|
const events = [];
|
|
2739
2849
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
@@ -2837,7 +2947,7 @@ import path3 from "node:path";
|
|
|
2837
2947
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2838
2948
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2839
2949
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2840
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2950
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2841
2951
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2842
2952
|
import path5 from "node:path";
|
|
2843
2953
|
|
|
@@ -3005,6 +3115,7 @@ function resolveEndpoint(options = {}) {
|
|
|
3005
3115
|
}
|
|
3006
3116
|
|
|
3007
3117
|
// ../task-list/src/backends/utils.ts
|
|
3118
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3008
3119
|
import path6 from "node:path";
|
|
3009
3120
|
function compareCreated(left, right) {
|
|
3010
3121
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
@@ -3025,9 +3136,8 @@ function applyOrder(entries, order) {
|
|
|
3025
3136
|
}
|
|
3026
3137
|
return entries.map((entry) => entry.task);
|
|
3027
3138
|
}
|
|
3028
|
-
var tmpFileCounter = 0;
|
|
3029
3139
|
function hasErrorCode(error3, code) {
|
|
3030
|
-
return !!error3 && typeof error3 === "object" && "code"
|
|
3140
|
+
return !!error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
|
|
3031
3141
|
}
|
|
3032
3142
|
function isRecord2(value) {
|
|
3033
3143
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -3074,18 +3184,22 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
3074
3184
|
}
|
|
3075
3185
|
}
|
|
3076
3186
|
async function writeAtomically(fs4, filePath, content) {
|
|
3077
|
-
const tempPath = `${filePath}
|
|
3078
|
-
|
|
3187
|
+
const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
|
|
3188
|
+
let tempCreated = false;
|
|
3079
3189
|
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
3080
3190
|
try {
|
|
3081
3191
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
3192
|
+
tempCreated = true;
|
|
3082
3193
|
await fs4.rename(tempPath, filePath);
|
|
3194
|
+
tempCreated = false;
|
|
3083
3195
|
} catch (error3) {
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3196
|
+
if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
|
|
3197
|
+
try {
|
|
3198
|
+
await fs4.unlink(tempPath);
|
|
3199
|
+
} catch (unlinkError) {
|
|
3200
|
+
if (!hasErrorCode(unlinkError, "ENOENT")) {
|
|
3201
|
+
throw unlinkError;
|
|
3202
|
+
}
|
|
3089
3203
|
}
|
|
3090
3204
|
}
|
|
3091
3205
|
throw error3;
|
|
@@ -3099,6 +3213,7 @@ async function withFileLock(fs4, lockPath, operation) {
|
|
|
3099
3213
|
break;
|
|
3100
3214
|
} catch (error3) {
|
|
3101
3215
|
if (!hasErrorCode(error3, "EEXIST")) {
|
|
3216
|
+
await fs4.unlink(lockPath).catch(() => void 0);
|
|
3102
3217
|
throw error3;
|
|
3103
3218
|
}
|
|
3104
3219
|
if (await removeAbandonedLock(fs4, lockPath)) {
|
|
@@ -4382,27 +4497,30 @@ function readFrontmatter(frontmatterContent, filePath) {
|
|
|
4382
4497
|
return parsed;
|
|
4383
4498
|
}
|
|
4384
4499
|
function assertValidTaskRecord(frontmatter, filePath, validStates) {
|
|
4385
|
-
if ("$schema"
|
|
4500
|
+
if (hasOwnTaskField(frontmatter, "$schema") && frontmatter.$schema !== TASK_SCHEMA_ID) {
|
|
4386
4501
|
throw malformedTask(filePath, "$schema");
|
|
4387
4502
|
}
|
|
4388
|
-
if ("kind"
|
|
4503
|
+
if (hasOwnTaskField(frontmatter, "kind") && frontmatter.kind !== TASK_KIND) {
|
|
4389
4504
|
throw malformedTask(filePath, "kind");
|
|
4390
4505
|
}
|
|
4391
|
-
if ("version"
|
|
4506
|
+
if (hasOwnTaskField(frontmatter, "version")) {
|
|
4392
4507
|
if (typeof frontmatter.version !== "number" || !Number.isInteger(frontmatter.version) || frontmatter.version !== TASK_VERSION) {
|
|
4393
4508
|
throw malformedTask(filePath, "version");
|
|
4394
4509
|
}
|
|
4395
4510
|
}
|
|
4396
|
-
if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
4511
|
+
if (!hasOwnTaskField(frontmatter, "name") || typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
4397
4512
|
throw malformedTask(filePath, "name");
|
|
4398
4513
|
}
|
|
4399
|
-
if (typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
|
|
4514
|
+
if (!hasOwnTaskField(frontmatter, "state") || typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
|
|
4400
4515
|
throw malformedTask(filePath, "state");
|
|
4401
4516
|
}
|
|
4402
|
-
if ("description"
|
|
4517
|
+
if (hasOwnTaskField(frontmatter, "description") && typeof frontmatter.description !== "string") {
|
|
4403
4518
|
throw malformedTask(filePath, "description");
|
|
4404
4519
|
}
|
|
4405
4520
|
}
|
|
4521
|
+
function hasOwnTaskField(frontmatter, key2) {
|
|
4522
|
+
return Object.prototype.hasOwnProperty.call(frontmatter, key2);
|
|
4523
|
+
}
|
|
4406
4524
|
function reservedFrontmatterKeys(mode) {
|
|
4407
4525
|
return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
|
|
4408
4526
|
}
|
|
@@ -4525,7 +4643,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4525
4643
|
}
|
|
4526
4644
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4527
4645
|
}
|
|
4528
|
-
function createdFrontmatter(
|
|
4646
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4529
4647
|
const frontmatter = mode !== "passthrough" ? {
|
|
4530
4648
|
$schema: TASK_SCHEMA_ID,
|
|
4531
4649
|
kind: TASK_KIND,
|
|
@@ -4537,7 +4655,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4537
4655
|
state: initialState
|
|
4538
4656
|
};
|
|
4539
4657
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4540
|
-
for (const [key2, value] of Object.entries(
|
|
4658
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4541
4659
|
if (!reservedKeys.has(key2)) {
|
|
4542
4660
|
setOwnValue(frontmatter, key2, value);
|
|
4543
4661
|
}
|
|
@@ -5251,7 +5369,8 @@ function parseQualifiedId3(qualifiedId) {
|
|
|
5251
5369
|
};
|
|
5252
5370
|
}
|
|
5253
5371
|
function descriptionFromTaskRecord(taskRecord) {
|
|
5254
|
-
|
|
5372
|
+
const description = getOwnEntry(taskRecord, "description");
|
|
5373
|
+
return typeof description === "string" ? description : "";
|
|
5255
5374
|
}
|
|
5256
5375
|
function metadataFromTaskRecord(taskRecord) {
|
|
5257
5376
|
const metadata = /* @__PURE__ */ Object.create(null);
|
|
@@ -5267,8 +5386,8 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5267
5386
|
list,
|
|
5268
5387
|
id,
|
|
5269
5388
|
qualifiedId: `${list}/${id}`,
|
|
5270
|
-
name: taskRecord
|
|
5271
|
-
state: taskRecord
|
|
5389
|
+
name: getOwnEntry(taskRecord, "name"),
|
|
5390
|
+
state: getOwnEntry(taskRecord, "state"),
|
|
5272
5391
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5273
5392
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5274
5393
|
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
@@ -5283,13 +5402,13 @@ function matchesFilter(task, filter) {
|
|
|
5283
5402
|
}
|
|
5284
5403
|
return true;
|
|
5285
5404
|
}
|
|
5286
|
-
function createTaskRecord(
|
|
5405
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5287
5406
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5288
5407
|
name: input.name,
|
|
5289
5408
|
state: initialState,
|
|
5290
5409
|
description: input.description ?? ""
|
|
5291
5410
|
});
|
|
5292
|
-
for (const [key2, value] of Object.entries(
|
|
5411
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5293
5412
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5294
5413
|
taskRecord[key2] = value;
|
|
5295
5414
|
}
|
|
@@ -5365,16 +5484,17 @@ function assertValidStoreRecord(store, filePath) {
|
|
|
5365
5484
|
if (!isRecord2(store)) {
|
|
5366
5485
|
throw malformedStore(filePath, "store");
|
|
5367
5486
|
}
|
|
5368
|
-
if (store
|
|
5487
|
+
if (getOwnEntry(store, "$schema") !== STORE_SCHEMA_ID) {
|
|
5369
5488
|
throw malformedStore(filePath, "$schema");
|
|
5370
5489
|
}
|
|
5371
|
-
if (store
|
|
5490
|
+
if (getOwnEntry(store, "kind") !== STORE_KIND) {
|
|
5372
5491
|
throw malformedStore(filePath, "kind");
|
|
5373
5492
|
}
|
|
5374
|
-
|
|
5493
|
+
const version = getOwnEntry(store, "version");
|
|
5494
|
+
if (typeof version !== "number" || !Number.isInteger(version) || version !== STORE_VERSION) {
|
|
5375
5495
|
throw malformedStore(filePath, "version");
|
|
5376
5496
|
}
|
|
5377
|
-
if (!isRecord2(store
|
|
5497
|
+
if (!isRecord2(getOwnEntry(store, "lists"))) {
|
|
5378
5498
|
throw malformedStore(filePath, "lists");
|
|
5379
5499
|
}
|
|
5380
5500
|
}
|
|
@@ -5382,29 +5502,38 @@ function assertValidTaskRecord2(taskRecord, list, id, validStates) {
|
|
|
5382
5502
|
if (!isRecord2(taskRecord)) {
|
|
5383
5503
|
throw malformedTask2(list, id, "task");
|
|
5384
5504
|
}
|
|
5385
|
-
if ("$schema"
|
|
5505
|
+
if (hasOwnTaskField2(taskRecord, "$schema") && getOwnEntry(taskRecord, "$schema") !== TASK_SCHEMA_ID2) {
|
|
5386
5506
|
throw malformedTask2(list, id, "$schema");
|
|
5387
5507
|
}
|
|
5388
|
-
if ("kind"
|
|
5508
|
+
if (hasOwnTaskField2(taskRecord, "kind") && getOwnEntry(taskRecord, "kind") !== TASK_KIND2) {
|
|
5389
5509
|
throw malformedTask2(list, id, "kind");
|
|
5390
5510
|
}
|
|
5391
|
-
if ("version"
|
|
5392
|
-
|
|
5511
|
+
if (hasOwnTaskField2(taskRecord, "version")) {
|
|
5512
|
+
const version = getOwnEntry(taskRecord, "version");
|
|
5513
|
+
if (typeof version !== "number" || !Number.isInteger(version) || version !== TASK_VERSION2) {
|
|
5393
5514
|
throw malformedTask2(list, id, "version");
|
|
5394
5515
|
}
|
|
5395
5516
|
}
|
|
5396
|
-
|
|
5517
|
+
const name = getOwnEntry(taskRecord, "name");
|
|
5518
|
+
if (!hasOwnTaskField2(taskRecord, "name") || typeof name !== "string" || name.length === 0) {
|
|
5397
5519
|
throw malformedTask2(list, id, "name");
|
|
5398
5520
|
}
|
|
5399
|
-
|
|
5521
|
+
const state = getOwnEntry(taskRecord, "state");
|
|
5522
|
+
if (!hasOwnTaskField2(taskRecord, "state") || typeof state !== "string" || !validStates.has(state)) {
|
|
5400
5523
|
throw malformedTask2(list, id, "state");
|
|
5401
5524
|
}
|
|
5402
|
-
if ("description"
|
|
5525
|
+
if (hasOwnTaskField2(taskRecord, "description") && typeof getOwnEntry(taskRecord, "description") !== "string") {
|
|
5403
5526
|
throw malformedTask2(list, id, "description");
|
|
5404
5527
|
}
|
|
5405
5528
|
}
|
|
5529
|
+
function hasOwnTaskField2(taskRecord, key2) {
|
|
5530
|
+
return Object.prototype.hasOwnProperty.call(taskRecord, key2);
|
|
5531
|
+
}
|
|
5532
|
+
function getOwnEntry(record, key2) {
|
|
5533
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
5534
|
+
}
|
|
5406
5535
|
function validateStoreEntries(store, filePath, validStates) {
|
|
5407
|
-
const lists = store
|
|
5536
|
+
const lists = getOwnEntry(store, "lists");
|
|
5408
5537
|
if (!isRecord2(lists)) {
|
|
5409
5538
|
throw malformedStore(filePath, "lists");
|
|
5410
5539
|
}
|
|
@@ -5444,10 +5573,11 @@ async function readStore(fs4, filePath, validStates) {
|
|
|
5444
5573
|
};
|
|
5445
5574
|
}
|
|
5446
5575
|
function getListsRecord(store) {
|
|
5447
|
-
|
|
5576
|
+
const lists = getOwnEntry(store, "lists");
|
|
5577
|
+
return isRecord2(lists) ? lists : {};
|
|
5448
5578
|
}
|
|
5449
5579
|
function getListRecord(store, list) {
|
|
5450
|
-
const listRecord = getListsRecord(store)
|
|
5580
|
+
const listRecord = getOwnEntry(getListsRecord(store), list);
|
|
5451
5581
|
return isRecord2(listRecord) ? listRecord : void 0;
|
|
5452
5582
|
}
|
|
5453
5583
|
function getTaskRecord(store, list, id) {
|
|
@@ -5740,7 +5870,7 @@ async function yamlFileBackend(deps) {
|
|
|
5740
5870
|
const result = [];
|
|
5741
5871
|
const listNames = sortStrings(Object.keys(getListsRecord(store)));
|
|
5742
5872
|
for (const listName of listNames) {
|
|
5743
|
-
const listRecord = getListsRecord(store)
|
|
5873
|
+
const listRecord = getOwnEntry(getListsRecord(store), listName);
|
|
5744
5874
|
if (!isRecord2(listRecord)) continue;
|
|
5745
5875
|
const entries = Object.entries(listRecord).map(([id, taskRecord]) => ({
|
|
5746
5876
|
task: createTask2(listName, id, taskRecord, deps.path),
|
|
@@ -6374,8 +6504,8 @@ function createHandlerContext(command, params17) {
|
|
|
6374
6504
|
function createFs() {
|
|
6375
6505
|
return {
|
|
6376
6506
|
readFile: async (path25, encoding = "utf8") => readFile2(path25, { encoding }),
|
|
6377
|
-
writeFile: async (path25, contents) => {
|
|
6378
|
-
await writeFile2(path25, contents);
|
|
6507
|
+
writeFile: async (path25, contents, options) => {
|
|
6508
|
+
await writeFile2(path25, contents, options);
|
|
6379
6509
|
},
|
|
6380
6510
|
exists: async (path25) => {
|
|
6381
6511
|
try {
|
|
@@ -6663,17 +6793,17 @@ function isMissingStateError(error3) {
|
|
|
6663
6793
|
}
|
|
6664
6794
|
|
|
6665
6795
|
// ../toolcraft/src/error-report.ts
|
|
6666
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6667
|
-
import { randomUUID as
|
|
6796
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6797
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
6668
6798
|
import os from "node:os";
|
|
6669
6799
|
import path13 from "node:path";
|
|
6670
6800
|
import { CommanderError } from "commander";
|
|
6671
6801
|
|
|
6672
6802
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6673
6803
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6674
|
-
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6804
|
+
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6675
6805
|
import path12 from "node:path";
|
|
6676
|
-
import { createHash as createHash3, randomUUID as
|
|
6806
|
+
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
6677
6807
|
|
|
6678
6808
|
// ../tiny-mcp-client/src/internal.ts
|
|
6679
6809
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6684,7 +6814,7 @@ import crypto from "node:crypto";
|
|
|
6684
6814
|
import path11 from "node:path";
|
|
6685
6815
|
|
|
6686
6816
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6687
|
-
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6817
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
|
|
6688
6818
|
import { promises as fs } from "node:fs";
|
|
6689
6819
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6690
6820
|
import path10 from "node:path";
|
|
@@ -6695,7 +6825,6 @@ var ENCRYPTION_KEY_BYTES = 32;
|
|
|
6695
6825
|
var ENCRYPTION_IV_BYTES = 12;
|
|
6696
6826
|
var ENCRYPTION_AUTH_TAG_BYTES = 16;
|
|
6697
6827
|
var ENCRYPTION_FILE_MODE = 384;
|
|
6698
|
-
var temporaryFileSequence = 0;
|
|
6699
6828
|
var EncryptedFileStore = class {
|
|
6700
6829
|
fs;
|
|
6701
6830
|
filePath;
|
|
@@ -6727,7 +6856,7 @@ var EncryptedFileStore = class {
|
|
|
6727
6856
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6728
6857
|
}
|
|
6729
6858
|
async get() {
|
|
6730
|
-
await this.
|
|
6859
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6731
6860
|
let rawDocument;
|
|
6732
6861
|
try {
|
|
6733
6862
|
rawDocument = await this.fs.readFile(this.filePath, "utf8");
|
|
@@ -6758,7 +6887,7 @@ var EncryptedFileStore = class {
|
|
|
6758
6887
|
}
|
|
6759
6888
|
}
|
|
6760
6889
|
async set(value) {
|
|
6761
|
-
await this.
|
|
6890
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6762
6891
|
const key2 = await this.getEncryptionKey();
|
|
6763
6892
|
const iv = this.getRandomBytes(ENCRYPTION_IV_BYTES);
|
|
6764
6893
|
const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key2, iv);
|
|
@@ -6774,25 +6903,28 @@ var EncryptedFileStore = class {
|
|
|
6774
6903
|
ciphertext: ciphertext.toString("base64")
|
|
6775
6904
|
};
|
|
6776
6905
|
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6777
|
-
await this.
|
|
6778
|
-
const temporaryPath = `${this.filePath}.${process.pid}.${
|
|
6906
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6907
|
+
const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
6908
|
+
let temporaryCreated = false;
|
|
6779
6909
|
try {
|
|
6910
|
+
await this.assertCredentialPathHasNoSymbolicLinks(temporaryPath);
|
|
6780
6911
|
await this.fs.writeFile(temporaryPath, JSON.stringify(document), {
|
|
6781
6912
|
encoding: "utf8",
|
|
6782
6913
|
flag: "wx",
|
|
6783
6914
|
mode: ENCRYPTION_FILE_MODE
|
|
6784
6915
|
});
|
|
6916
|
+
temporaryCreated = true;
|
|
6785
6917
|
await this.fs.chmod(temporaryPath, ENCRYPTION_FILE_MODE);
|
|
6786
6918
|
await this.fs.rename(temporaryPath, this.filePath);
|
|
6787
6919
|
} catch (error3) {
|
|
6788
|
-
if (!isAlreadyExistsError(error3)) {
|
|
6920
|
+
if (temporaryCreated || !isAlreadyExistsError(error3)) {
|
|
6789
6921
|
await removeIfPresent(this.fs, temporaryPath).catch(() => void 0);
|
|
6790
6922
|
}
|
|
6791
6923
|
throw error3;
|
|
6792
6924
|
}
|
|
6793
6925
|
}
|
|
6794
6926
|
async delete() {
|
|
6795
|
-
await this.
|
|
6927
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6796
6928
|
try {
|
|
6797
6929
|
await this.fs.unlink(this.filePath);
|
|
6798
6930
|
} catch (error3) {
|
|
@@ -6801,8 +6933,8 @@ var EncryptedFileStore = class {
|
|
|
6801
6933
|
}
|
|
6802
6934
|
}
|
|
6803
6935
|
}
|
|
6804
|
-
async
|
|
6805
|
-
const resolvedPath = path10.resolve(
|
|
6936
|
+
async assertCredentialPathHasNoSymbolicLinks(targetPath) {
|
|
6937
|
+
const resolvedPath = path10.resolve(targetPath);
|
|
6806
6938
|
const protectedPaths = getProtectedCredentialPaths(
|
|
6807
6939
|
resolvedPath,
|
|
6808
6940
|
this.symbolicLinkCheckStartPath
|
|
@@ -6867,9 +6999,6 @@ async function removeIfPresent(fileSystem, filePath) {
|
|
|
6867
6999
|
}
|
|
6868
7000
|
}
|
|
6869
7001
|
}
|
|
6870
|
-
function isAlreadyExistsError(error3) {
|
|
6871
|
-
return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "EEXIST";
|
|
6872
|
-
}
|
|
6873
7002
|
function defaultMachineIdentity() {
|
|
6874
7003
|
return {
|
|
6875
7004
|
hostname: hostname(),
|
|
@@ -6907,17 +7036,21 @@ function parseEncryptedDocument(raw) {
|
|
|
6907
7036
|
if (!isRecord4(parsed)) {
|
|
6908
7037
|
return null;
|
|
6909
7038
|
}
|
|
6910
|
-
|
|
7039
|
+
const version = getOwnEntry2(parsed, "version");
|
|
7040
|
+
const iv = getOwnEntry2(parsed, "iv");
|
|
7041
|
+
const authTag = getOwnEntry2(parsed, "authTag");
|
|
7042
|
+
const ciphertext = getOwnEntry2(parsed, "ciphertext");
|
|
7043
|
+
if (version !== ENCRYPTION_VERSION) {
|
|
6911
7044
|
return null;
|
|
6912
7045
|
}
|
|
6913
|
-
if (typeof
|
|
7046
|
+
if (typeof iv !== "string" || typeof authTag !== "string" || typeof ciphertext !== "string") {
|
|
6914
7047
|
return null;
|
|
6915
7048
|
}
|
|
6916
7049
|
return {
|
|
6917
|
-
version
|
|
6918
|
-
iv
|
|
6919
|
-
authTag
|
|
6920
|
-
ciphertext
|
|
7050
|
+
version,
|
|
7051
|
+
iv,
|
|
7052
|
+
authTag,
|
|
7053
|
+
ciphertext
|
|
6921
7054
|
};
|
|
6922
7055
|
} catch {
|
|
6923
7056
|
return null;
|
|
@@ -6926,9 +7059,17 @@ function parseEncryptedDocument(raw) {
|
|
|
6926
7059
|
function isRecord4(value) {
|
|
6927
7060
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
6928
7061
|
}
|
|
7062
|
+
function getOwnEntry2(record, key2) {
|
|
7063
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7064
|
+
}
|
|
6929
7065
|
function isNotFoundError(error3) {
|
|
6930
7066
|
return Boolean(
|
|
6931
|
-
error3 && typeof error3 === "object" && "code"
|
|
7067
|
+
error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT"
|
|
7068
|
+
);
|
|
7069
|
+
}
|
|
7070
|
+
function isAlreadyExistsError(error3) {
|
|
7071
|
+
return Boolean(
|
|
7072
|
+
error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST"
|
|
6932
7073
|
);
|
|
6933
7074
|
}
|
|
6934
7075
|
|
|
@@ -6950,8 +7091,8 @@ var KeychainStore = class {
|
|
|
6950
7091
|
["find-generic-password", "-s", this.service, "-a", this.account, "-w"],
|
|
6951
7092
|
"read secret from macOS Keychain"
|
|
6952
7093
|
);
|
|
6953
|
-
if (result
|
|
6954
|
-
return stripTrailingLineBreak(result
|
|
7094
|
+
if (getCommandExitCode(result) === 0) {
|
|
7095
|
+
return stripTrailingLineBreak(getCommandOutput(result, "stdout"));
|
|
6955
7096
|
}
|
|
6956
7097
|
if (isKeychainEntryNotFound(result)) {
|
|
6957
7098
|
return null;
|
|
@@ -6975,7 +7116,7 @@ var KeychainStore = class {
|
|
|
6975
7116
|
"store secret in macOS Keychain",
|
|
6976
7117
|
{ stdin: value }
|
|
6977
7118
|
);
|
|
6978
|
-
if (result
|
|
7119
|
+
if (getCommandExitCode(result) !== 0) {
|
|
6979
7120
|
throw createSecurityCliFailure("store secret in macOS Keychain", result);
|
|
6980
7121
|
}
|
|
6981
7122
|
}
|
|
@@ -6984,7 +7125,7 @@ var KeychainStore = class {
|
|
|
6984
7125
|
["delete-generic-password", "-s", this.service, "-a", this.account],
|
|
6985
7126
|
"delete secret from macOS Keychain"
|
|
6986
7127
|
);
|
|
6987
|
-
if (result
|
|
7128
|
+
if (getCommandExitCode(result) === 0 || isKeychainEntryNotFound(result)) {
|
|
6988
7129
|
return;
|
|
6989
7130
|
}
|
|
6990
7131
|
throw createSecurityCliFailure("delete secret from macOS Keychain", result);
|
|
@@ -7063,16 +7204,28 @@ function stripTrailingLineBreak(value) {
|
|
|
7063
7204
|
return value;
|
|
7064
7205
|
}
|
|
7065
7206
|
function isKeychainEntryNotFound(result) {
|
|
7066
|
-
return result
|
|
7207
|
+
return getCommandExitCode(result) === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
|
|
7067
7208
|
}
|
|
7068
7209
|
function createSecurityCliFailure(operation, result) {
|
|
7069
|
-
const
|
|
7210
|
+
const exitCode = getCommandExitCode(result);
|
|
7211
|
+
const details = getCommandOutput(result, "stderr").trim() || getCommandOutput(result, "stdout").trim();
|
|
7070
7212
|
if (details) {
|
|
7071
7213
|
return new Error(
|
|
7072
|
-
`Failed to ${operation}: security exited with code ${
|
|
7214
|
+
`Failed to ${operation}: security exited with code ${exitCode}: ${details}`
|
|
7073
7215
|
);
|
|
7074
7216
|
}
|
|
7075
|
-
return new Error(`Failed to ${operation}: security exited with code ${
|
|
7217
|
+
return new Error(`Failed to ${operation}: security exited with code ${exitCode}`);
|
|
7218
|
+
}
|
|
7219
|
+
function getCommandExitCode(result) {
|
|
7220
|
+
const value = getOwnEntry3(result, "exitCode");
|
|
7221
|
+
return typeof value === "number" && Number.isInteger(value) ? value : 1;
|
|
7222
|
+
}
|
|
7223
|
+
function getCommandOutput(result, key2) {
|
|
7224
|
+
const value = getOwnEntry3(result, key2);
|
|
7225
|
+
return typeof value === "string" ? value : "";
|
|
7226
|
+
}
|
|
7227
|
+
function getOwnEntry3(record, key2) {
|
|
7228
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7076
7229
|
}
|
|
7077
7230
|
|
|
7078
7231
|
// ../auth-store/src/create-secret-store.ts
|
|
@@ -7105,7 +7258,7 @@ function createSecretStore(input) {
|
|
|
7105
7258
|
}
|
|
7106
7259
|
function resolveBackend(input) {
|
|
7107
7260
|
const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
|
|
7108
|
-
const configuredBackend = input.backend ?? input.env
|
|
7261
|
+
const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
|
|
7109
7262
|
if (configuredBackend === "keychain") {
|
|
7110
7263
|
return "keychain";
|
|
7111
7264
|
}
|
|
@@ -7114,6 +7267,9 @@ function resolveBackend(input) {
|
|
|
7114
7267
|
}
|
|
7115
7268
|
throw new Error(`Unsupported auth store backend: ${configuredBackend}`);
|
|
7116
7269
|
}
|
|
7270
|
+
function getOwnEnvValue(env, key2) {
|
|
7271
|
+
return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
|
|
7272
|
+
}
|
|
7117
7273
|
|
|
7118
7274
|
// ../mcp-oauth/src/resource-indicator.ts
|
|
7119
7275
|
function canonicalizeResourceIndicator(value) {
|
|
@@ -7167,8 +7323,13 @@ function createAuthStoreClientStore(options) {
|
|
|
7167
7323
|
return null;
|
|
7168
7324
|
}
|
|
7169
7325
|
const parsed = JSON.parse(value);
|
|
7170
|
-
|
|
7171
|
-
|
|
7326
|
+
const clientId = isObjectRecord(parsed) ? getOwnString(parsed, "clientId") : void 0;
|
|
7327
|
+
if (clientId !== void 0) {
|
|
7328
|
+
const client = { clientId };
|
|
7329
|
+
if (isObjectRecord(parsed) && Object.prototype.hasOwnProperty.call(parsed, "clientSecret")) {
|
|
7330
|
+
client.clientSecret = getOwnEntry4(parsed, "clientSecret");
|
|
7331
|
+
}
|
|
7332
|
+
return client;
|
|
7172
7333
|
}
|
|
7173
7334
|
throw new Error("Stored OAuth client must be a JSON object with clientId");
|
|
7174
7335
|
},
|
|
@@ -7182,19 +7343,24 @@ function createAuthStoreClientStore(options) {
|
|
|
7182
7343
|
}
|
|
7183
7344
|
};
|
|
7184
7345
|
}
|
|
7185
|
-
function createNamedSecretStore(key2, options,
|
|
7346
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
7186
7347
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
7187
|
-
const
|
|
7348
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7349
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
7188
7350
|
const fileStore = {
|
|
7189
7351
|
...options.fileStore,
|
|
7190
|
-
|
|
7191
|
-
|
|
7352
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7353
|
+
parsedFilePath.dir,
|
|
7354
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7355
|
+
),
|
|
7356
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7357
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
7192
7358
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7193
7359
|
};
|
|
7194
7360
|
const keychainStore = {
|
|
7195
7361
|
...options.keychainStore,
|
|
7196
|
-
service: options.keychainStore?.service ??
|
|
7197
|
-
account: `${options.keychainStore?.account ??
|
|
7362
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7363
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
7198
7364
|
};
|
|
7199
7365
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
7200
7366
|
}
|
|
@@ -7222,6 +7388,16 @@ function createIssuerSecretStore(issuer, options) {
|
|
|
7222
7388
|
}
|
|
7223
7389
|
);
|
|
7224
7390
|
}
|
|
7391
|
+
function isObjectRecord(value) {
|
|
7392
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7393
|
+
}
|
|
7394
|
+
function getOwnEntry4(record, key2) {
|
|
7395
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7396
|
+
}
|
|
7397
|
+
function getOwnString(record, key2) {
|
|
7398
|
+
const value = getOwnEntry4(record, key2);
|
|
7399
|
+
return typeof value === "string" ? value : void 0;
|
|
7400
|
+
}
|
|
7225
7401
|
|
|
7226
7402
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
7227
7403
|
import { URL as URL2 } from "node:url";
|
|
@@ -7247,17 +7423,30 @@ function parseAuthorizationState(value) {
|
|
|
7247
7423
|
try {
|
|
7248
7424
|
const decoded = Buffer.from(value, "base64url").toString("utf8");
|
|
7249
7425
|
const parsed = JSON.parse(decoded);
|
|
7250
|
-
if (parsed
|
|
7426
|
+
if (!isObjectRecord2(parsed)) {
|
|
7427
|
+
return null;
|
|
7428
|
+
}
|
|
7429
|
+
const version = getOwnEntry5(parsed, "v");
|
|
7430
|
+
const nonce = getOwnEntry5(parsed, "n");
|
|
7431
|
+
const issuer = getOwnEntry5(parsed, "i");
|
|
7432
|
+
const requireIssuer = getOwnEntry5(parsed, "r");
|
|
7433
|
+
if (version !== 1 || typeof nonce !== "string" || nonce.length === 0 || typeof issuer !== "string" || issuer.length === 0 || typeof requireIssuer !== "boolean") {
|
|
7251
7434
|
return null;
|
|
7252
7435
|
}
|
|
7253
7436
|
return {
|
|
7254
|
-
issuer
|
|
7255
|
-
requireIssuer
|
|
7437
|
+
issuer,
|
|
7438
|
+
requireIssuer
|
|
7256
7439
|
};
|
|
7257
7440
|
} catch {
|
|
7258
7441
|
return null;
|
|
7259
7442
|
}
|
|
7260
7443
|
}
|
|
7444
|
+
function isObjectRecord2(value) {
|
|
7445
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7446
|
+
}
|
|
7447
|
+
function getOwnEntry5(record, key2) {
|
|
7448
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7449
|
+
}
|
|
7261
7450
|
|
|
7262
7451
|
// ../mcp-oauth/src/client/loopback-authorization.ts
|
|
7263
7452
|
async function createLoopbackAuthorizationSession(options = {}) {
|
|
@@ -7534,22 +7723,26 @@ async function requestTokens(input) {
|
|
|
7534
7723
|
body: body.toString()
|
|
7535
7724
|
});
|
|
7536
7725
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
7537
|
-
|
|
7726
|
+
const accessToken = getOwnEntry6(payload, "access_token");
|
|
7727
|
+
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
7538
7728
|
throw new Error("OAuth token response missing access_token");
|
|
7539
7729
|
}
|
|
7540
|
-
const tokenType = normalizeBearerTokenType(payload
|
|
7730
|
+
const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
|
|
7541
7731
|
if (tokenType === null) {
|
|
7542
7732
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
7543
7733
|
}
|
|
7544
|
-
|
|
7734
|
+
const expiresIn = getOwnEntry6(payload, "expires_in");
|
|
7735
|
+
if (typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn < 0) {
|
|
7545
7736
|
throw new Error("OAuth token response has invalid expires_in");
|
|
7546
7737
|
}
|
|
7738
|
+
const refreshToken = getOwnEntry6(payload, "refresh_token");
|
|
7739
|
+
const scope = getOwnEntry6(payload, "scope");
|
|
7547
7740
|
return {
|
|
7548
|
-
accessToken
|
|
7549
|
-
refreshToken: typeof
|
|
7741
|
+
accessToken,
|
|
7742
|
+
refreshToken: typeof refreshToken === "string" && refreshToken.length > 0 ? refreshToken : void 0,
|
|
7550
7743
|
tokenType,
|
|
7551
|
-
expiresAt: typeof
|
|
7552
|
-
scope: typeof
|
|
7744
|
+
expiresAt: typeof expiresIn === "number" && Number.isFinite(expiresIn) ? input.now() + expiresIn * 1e3 : null,
|
|
7745
|
+
scope: typeof scope === "string" && scope.length > 0 ? scope : void 0
|
|
7553
7746
|
};
|
|
7554
7747
|
}
|
|
7555
7748
|
async function readOAuthJsonObjectResponse(response) {
|
|
@@ -7576,12 +7769,18 @@ async function readOAuthJsonObjectResponse(response) {
|
|
|
7576
7769
|
return record;
|
|
7577
7770
|
}
|
|
7578
7771
|
function readOAuthError(payload, fallbackError = "server_error") {
|
|
7772
|
+
const error3 = getOwnEntry6(payload, "error");
|
|
7773
|
+
const errorDescription = getOwnEntry6(payload, "error_description");
|
|
7774
|
+
const errorUri = getOwnEntry6(payload, "error_uri");
|
|
7579
7775
|
return {
|
|
7580
|
-
error: typeof
|
|
7581
|
-
error_description: typeof
|
|
7582
|
-
error_uri: typeof
|
|
7776
|
+
error: typeof error3 === "string" ? error3 : fallbackError,
|
|
7777
|
+
error_description: typeof errorDescription === "string" ? errorDescription : void 0,
|
|
7778
|
+
error_uri: typeof errorUri === "string" ? errorUri : void 0
|
|
7583
7779
|
};
|
|
7584
7780
|
}
|
|
7781
|
+
function getOwnEntry6(record, key2) {
|
|
7782
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7783
|
+
}
|
|
7585
7784
|
function createFallbackOAuthError(status) {
|
|
7586
7785
|
const error3 = status === 503 ? "temporarily_unavailable" : "server_error";
|
|
7587
7786
|
return new OAuthError({ error: error3 }, status);
|
|
@@ -7686,7 +7885,11 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7686
7885
|
while (true) {
|
|
7687
7886
|
try {
|
|
7688
7887
|
refreshedTokens = await refreshAccessToken({
|
|
7689
|
-
tokenEndpoint:
|
|
7888
|
+
tokenEndpoint: requireOwnString(
|
|
7889
|
+
discovery.authorizationServerMetadata,
|
|
7890
|
+
"token_endpoint",
|
|
7891
|
+
"Authorization server metadata"
|
|
7892
|
+
),
|
|
7690
7893
|
clientId: session.client.clientId,
|
|
7691
7894
|
clientSecret: session.client.clientSecret,
|
|
7692
7895
|
refreshToken: session.tokens.refreshToken,
|
|
@@ -7774,7 +7977,11 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7774
7977
|
});
|
|
7775
7978
|
const code = await loopback.waitForCode(authorizationUrl);
|
|
7776
7979
|
const tokens = await exchangeAuthorizationCode({
|
|
7777
|
-
tokenEndpoint:
|
|
7980
|
+
tokenEndpoint: requireOwnString(
|
|
7981
|
+
discovery.authorizationServerMetadata,
|
|
7982
|
+
"token_endpoint",
|
|
7983
|
+
"Authorization server metadata"
|
|
7984
|
+
),
|
|
7778
7985
|
clientId: resolvedClient.client.clientId,
|
|
7779
7986
|
clientSecret: resolvedClient.client.clientSecret,
|
|
7780
7987
|
code,
|
|
@@ -7827,7 +8034,10 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7827
8034
|
}
|
|
7828
8035
|
};
|
|
7829
8036
|
}
|
|
7830
|
-
const registrationEndpoint =
|
|
8037
|
+
const registrationEndpoint = getOwnString2(
|
|
8038
|
+
discovery.authorizationServerMetadata,
|
|
8039
|
+
"registration_endpoint"
|
|
8040
|
+
);
|
|
7831
8041
|
if (registrationEndpoint === void 0 && options.client.clientId !== void 0) {
|
|
7832
8042
|
return {
|
|
7833
8043
|
kind: "static",
|
|
@@ -7879,12 +8089,14 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7879
8089
|
body: JSON.stringify(registrationBody)
|
|
7880
8090
|
});
|
|
7881
8091
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
7882
|
-
|
|
8092
|
+
const clientId = getOwnString2(payload, "client_id");
|
|
8093
|
+
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
7883
8094
|
throw new Error("OAuth client registration response missing client_id");
|
|
7884
8095
|
}
|
|
8096
|
+
const clientSecret = getOwnString2(payload, "client_secret");
|
|
7885
8097
|
const registeredClient = {
|
|
7886
|
-
clientId
|
|
7887
|
-
clientSecret:
|
|
8098
|
+
clientId,
|
|
8099
|
+
clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
|
|
7888
8100
|
};
|
|
7889
8101
|
await saveRegisteredClient(discovery.authorizationServer, registeredClient);
|
|
7890
8102
|
return {
|
|
@@ -7910,12 +8122,13 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7910
8122
|
return null;
|
|
7911
8123
|
}
|
|
7912
8124
|
const client = await clientStore.load(issuer);
|
|
7913
|
-
|
|
8125
|
+
const normalizedClient = client === null ? null : normalizeStoredClient(client);
|
|
8126
|
+
if (client !== null && normalizedClient === null) {
|
|
7914
8127
|
await clientStore.clear(issuer);
|
|
7915
8128
|
return null;
|
|
7916
8129
|
}
|
|
7917
|
-
registeredClients.set(issuer,
|
|
7918
|
-
return
|
|
8130
|
+
registeredClients.set(issuer, normalizedClient);
|
|
8131
|
+
return normalizedClient;
|
|
7919
8132
|
}
|
|
7920
8133
|
async function saveRegisteredClient(issuer, client) {
|
|
7921
8134
|
registeredClients.set(issuer, client);
|
|
@@ -7931,7 +8144,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7931
8144
|
}
|
|
7932
8145
|
}
|
|
7933
8146
|
function isProviderOptions(options) {
|
|
7934
|
-
return "provider"
|
|
8147
|
+
return Object.prototype.hasOwnProperty.call(options, "provider");
|
|
7935
8148
|
}
|
|
7936
8149
|
function isExpired(tokens, now) {
|
|
7937
8150
|
return tokens.expiresAt !== null && tokens.expiresAt <= now();
|
|
@@ -7947,7 +8160,14 @@ function resolveDiscovery(discovery, session) {
|
|
|
7947
8160
|
return void 0;
|
|
7948
8161
|
}
|
|
7949
8162
|
const metadata = session.discovery.authorizationServerMetadata;
|
|
7950
|
-
|
|
8163
|
+
const issuer = getOwnString2(metadata, "issuer");
|
|
8164
|
+
const authorizationEndpoint = getOwnString2(metadata, "authorization_endpoint");
|
|
8165
|
+
const tokenEndpoint = getOwnString2(metadata, "token_endpoint");
|
|
8166
|
+
const codeChallengeMethodsSupported = getOwnStringArray(
|
|
8167
|
+
metadata,
|
|
8168
|
+
"code_challenge_methods_supported"
|
|
8169
|
+
);
|
|
8170
|
+
if (issuer === void 0 || authorizationEndpoint === void 0 || tokenEndpoint === void 0 || codeChallengeMethodsSupported === void 0 || !codeChallengeMethodsSupported.includes("S256")) {
|
|
7951
8171
|
return void 0;
|
|
7952
8172
|
}
|
|
7953
8173
|
return {
|
|
@@ -7971,29 +8191,94 @@ function normalizeLoadedSession(session) {
|
|
|
7971
8191
|
if (session === null) {
|
|
7972
8192
|
return null;
|
|
7973
8193
|
}
|
|
7974
|
-
|
|
8194
|
+
const client = normalizeStoredClient(getOwnEntry7(session, "client"));
|
|
8195
|
+
if (client === null) {
|
|
7975
8196
|
return { ...session, client: { clientId: "" }, tokens: void 0 };
|
|
7976
8197
|
}
|
|
7977
|
-
return
|
|
8198
|
+
return {
|
|
8199
|
+
...session,
|
|
8200
|
+
client,
|
|
8201
|
+
tokens: normalizeStoredTokens(getOwnEntry7(session, "tokens"))
|
|
8202
|
+
};
|
|
7978
8203
|
}
|
|
7979
|
-
function
|
|
7980
|
-
|
|
8204
|
+
function normalizeStoredClient(value) {
|
|
8205
|
+
if (!isObjectRecord3(value)) {
|
|
8206
|
+
return null;
|
|
8207
|
+
}
|
|
8208
|
+
const clientId = getOwnString2(value, "clientId");
|
|
8209
|
+
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
8210
|
+
return null;
|
|
8211
|
+
}
|
|
8212
|
+
const clientSecret = getOwnEntry7(value, "clientSecret");
|
|
8213
|
+
if (clientSecret === void 0) {
|
|
8214
|
+
return { clientId };
|
|
8215
|
+
}
|
|
8216
|
+
if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
|
|
8217
|
+
return null;
|
|
8218
|
+
}
|
|
8219
|
+
return { clientId, clientSecret };
|
|
7981
8220
|
}
|
|
7982
|
-
function
|
|
7983
|
-
if (
|
|
7984
|
-
return
|
|
8221
|
+
function normalizeStoredTokens(value) {
|
|
8222
|
+
if (value === void 0 || !isObjectRecord3(value)) {
|
|
8223
|
+
return void 0;
|
|
8224
|
+
}
|
|
8225
|
+
const accessToken = getOwnString2(value, "accessToken");
|
|
8226
|
+
const tokenType = getOwnString2(value, "tokenType");
|
|
8227
|
+
const expiresAt = getOwnEntry7(value, "expiresAt");
|
|
8228
|
+
const refreshToken = getOwnEntry7(value, "refreshToken");
|
|
8229
|
+
const scope = getOwnString2(value, "scope");
|
|
8230
|
+
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken : void 0;
|
|
8231
|
+
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)) {
|
|
8232
|
+
return void 0;
|
|
7985
8233
|
}
|
|
7986
|
-
return
|
|
8234
|
+
return {
|
|
8235
|
+
accessToken,
|
|
8236
|
+
tokenType,
|
|
8237
|
+
expiresAt,
|
|
8238
|
+
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
8239
|
+
...scope === void 0 || scope.length === 0 ? {} : { scope }
|
|
8240
|
+
};
|
|
7987
8241
|
}
|
|
7988
8242
|
function getClientMetadata(client) {
|
|
7989
8243
|
return client.metadata;
|
|
7990
8244
|
}
|
|
8245
|
+
function getOwnEntry7(record, key2) {
|
|
8246
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
8247
|
+
}
|
|
8248
|
+
function isObjectRecord3(value) {
|
|
8249
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8250
|
+
}
|
|
8251
|
+
function getOwnString2(record, key2) {
|
|
8252
|
+
const value = getOwnEntry7(record, key2);
|
|
8253
|
+
return typeof value === "string" ? value : void 0;
|
|
8254
|
+
}
|
|
8255
|
+
function requireOwnString(record, key2, label) {
|
|
8256
|
+
const value = getOwnString2(record, key2);
|
|
8257
|
+
if (value === void 0) {
|
|
8258
|
+
throw new Error(`${label} is missing ${key2}`);
|
|
8259
|
+
}
|
|
8260
|
+
return value;
|
|
8261
|
+
}
|
|
8262
|
+
function getOwnStringArray(record, key2) {
|
|
8263
|
+
const value = getOwnEntry7(record, key2);
|
|
8264
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
|
|
8265
|
+
}
|
|
7991
8266
|
function buildAuthorizationUrl(input) {
|
|
7992
|
-
const
|
|
8267
|
+
const authorizationEndpoint = requireOwnString(
|
|
8268
|
+
input.metadata,
|
|
8269
|
+
"authorization_endpoint",
|
|
8270
|
+
"Authorization server metadata"
|
|
8271
|
+
);
|
|
8272
|
+
const issuer = requireOwnString(
|
|
8273
|
+
input.metadata,
|
|
8274
|
+
"issuer",
|
|
8275
|
+
"Authorization server metadata"
|
|
8276
|
+
);
|
|
8277
|
+
const url = new URL2(authorizationEndpoint);
|
|
7993
8278
|
const resource = canonicalizeResourceIndicator(input.resource);
|
|
7994
8279
|
const state = createAuthorizationState({
|
|
7995
|
-
issuer
|
|
7996
|
-
requireIssuer: input.metadata
|
|
8280
|
+
issuer,
|
|
8281
|
+
requireIssuer: getOwnEntry7(input.metadata, "authorization_response_iss_parameter_supported") === true
|
|
7997
8282
|
});
|
|
7998
8283
|
url.searchParams.set("response_type", "code");
|
|
7999
8284
|
url.searchParams.set("client_id", input.clientId);
|
|
@@ -8008,7 +8293,7 @@ function buildAuthorizationUrl(input) {
|
|
|
8008
8293
|
return url.toString();
|
|
8009
8294
|
}
|
|
8010
8295
|
function assertS256PkceSupport(metadata) {
|
|
8011
|
-
if (!metadata
|
|
8296
|
+
if (!getOwnStringArray(metadata, "code_challenge_methods_supported")?.includes("S256")) {
|
|
8012
8297
|
throw new Error(
|
|
8013
8298
|
"Authorization server metadata must advertise code_challenge_methods_supported including S256"
|
|
8014
8299
|
);
|
|
@@ -8032,13 +8317,24 @@ function assertSecureUrl(value, label) {
|
|
|
8032
8317
|
throw new Error(`${label} must use https unless it targets a loopback host`);
|
|
8033
8318
|
}
|
|
8034
8319
|
function assertSecureOAuthFlowEndpoints(metadata) {
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8041
|
-
|
|
8320
|
+
const authorizationEndpoint = requireOwnString(
|
|
8321
|
+
metadata,
|
|
8322
|
+
"authorization_endpoint",
|
|
8323
|
+
"Authorization server metadata"
|
|
8324
|
+
);
|
|
8325
|
+
const tokenEndpoint = requireOwnString(
|
|
8326
|
+
metadata,
|
|
8327
|
+
"token_endpoint",
|
|
8328
|
+
"Authorization server metadata"
|
|
8329
|
+
);
|
|
8330
|
+
const registrationEndpoint = getOwnString2(metadata, "registration_endpoint");
|
|
8331
|
+
assertNoAccessTokenInUrl(authorizationEndpoint, "Authorization endpoint");
|
|
8332
|
+
assertNoAccessTokenInUrl(tokenEndpoint, "Token endpoint");
|
|
8333
|
+
assertSecureUrl(authorizationEndpoint, "Authorization endpoint");
|
|
8334
|
+
assertSecureUrl(tokenEndpoint, "Token endpoint");
|
|
8335
|
+
if (registrationEndpoint !== void 0) {
|
|
8336
|
+
assertNoAccessTokenInUrl(registrationEndpoint, "Registration endpoint");
|
|
8337
|
+
assertSecureUrl(registrationEndpoint, "Registration endpoint");
|
|
8042
8338
|
}
|
|
8043
8339
|
}
|
|
8044
8340
|
function assertNoAccessTokenInUrl(value, label) {
|
|
@@ -8061,17 +8357,21 @@ function buildClientRegistrationBody(metadata, redirectUri) {
|
|
|
8061
8357
|
response_types: ["code"],
|
|
8062
8358
|
token_endpoint_auth_method: "none"
|
|
8063
8359
|
};
|
|
8064
|
-
|
|
8065
|
-
|
|
8360
|
+
const clientName = metadata === void 0 ? void 0 : getOwnString2(metadata, "clientName");
|
|
8361
|
+
const scope = metadata === void 0 ? void 0 : getOwnString2(metadata, "scope");
|
|
8362
|
+
const softwareId = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareId");
|
|
8363
|
+
const softwareVersion = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareVersion");
|
|
8364
|
+
if (clientName !== void 0 && clientName.length > 0) {
|
|
8365
|
+
body.client_name = clientName;
|
|
8066
8366
|
}
|
|
8067
|
-
if (
|
|
8068
|
-
body.scope =
|
|
8367
|
+
if (scope !== void 0 && scope.length > 0) {
|
|
8368
|
+
body.scope = scope;
|
|
8069
8369
|
}
|
|
8070
|
-
if (
|
|
8071
|
-
body.software_id =
|
|
8370
|
+
if (softwareId !== void 0 && softwareId.length > 0) {
|
|
8371
|
+
body.software_id = softwareId;
|
|
8072
8372
|
}
|
|
8073
|
-
if (
|
|
8074
|
-
body.software_version =
|
|
8373
|
+
if (softwareVersion !== void 0 && softwareVersion.length > 0) {
|
|
8374
|
+
body.software_version = softwareVersion;
|
|
8075
8375
|
}
|
|
8076
8376
|
return body;
|
|
8077
8377
|
}
|
|
@@ -8107,7 +8407,7 @@ import {
|
|
|
8107
8407
|
function defaultOAuthMetadataFetch(input, init) {
|
|
8108
8408
|
return fetch(input, init);
|
|
8109
8409
|
}
|
|
8110
|
-
function
|
|
8410
|
+
function isObjectRecord4(value) {
|
|
8111
8411
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8112
8412
|
}
|
|
8113
8413
|
function isStringArray(value) {
|
|
@@ -8130,7 +8430,7 @@ function assertSecureUrl2(url, label) {
|
|
|
8130
8430
|
throw new Error(`${label} must use https unless it targets a loopback host`);
|
|
8131
8431
|
}
|
|
8132
8432
|
function validateProtectedResourceMetadata(value, resourceUrl) {
|
|
8133
|
-
if (!
|
|
8433
|
+
if (!isObjectRecord4(value)) {
|
|
8134
8434
|
throw new Error("Protected resource metadata must be a JSON object");
|
|
8135
8435
|
}
|
|
8136
8436
|
if (typeof value.resource !== "string" || value.resource.length === 0) {
|
|
@@ -8153,7 +8453,7 @@ function validateProtectedResourceMetadata(value, resourceUrl) {
|
|
|
8153
8453
|
};
|
|
8154
8454
|
}
|
|
8155
8455
|
function validateAuthorizationServerMetadata(value, issuer) {
|
|
8156
|
-
if (!
|
|
8456
|
+
if (!isObjectRecord4(value)) {
|
|
8157
8457
|
throw new Error("Authorization server metadata must be a JSON object");
|
|
8158
8458
|
}
|
|
8159
8459
|
if (typeof value.issuer !== "string" || value.issuer.length === 0) {
|
|
@@ -8606,7 +8906,7 @@ var McpClient = class {
|
|
|
8606
8906
|
await onPromptsChanged();
|
|
8607
8907
|
});
|
|
8608
8908
|
messageLayer.onNotification("notifications/message", async (params17) => {
|
|
8609
|
-
if (onLog === void 0 || !
|
|
8909
|
+
if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
|
|
8610
8910
|
return;
|
|
8611
8911
|
}
|
|
8612
8912
|
if (!hasOwn(params17, "data")) {
|
|
@@ -8625,7 +8925,7 @@ var McpClient = class {
|
|
|
8625
8925
|
await onLog(message2);
|
|
8626
8926
|
});
|
|
8627
8927
|
messageLayer.onNotification("notifications/progress", async (params17) => {
|
|
8628
|
-
if (onProgress === void 0 || !
|
|
8928
|
+
if (onProgress === void 0 || !isObjectRecord5(params17)) {
|
|
8629
8929
|
return;
|
|
8630
8930
|
}
|
|
8631
8931
|
const { progressToken, progress } = params17;
|
|
@@ -8794,6 +9094,9 @@ var McpClient = class {
|
|
|
8794
9094
|
const abortPromise = new Promise((_, reject) => {
|
|
8795
9095
|
const rejectWithAbortReason = () => {
|
|
8796
9096
|
sendCancellationNotification();
|
|
9097
|
+
if (requestId !== void 0) {
|
|
9098
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
9099
|
+
}
|
|
8797
9100
|
reject(signal.reason);
|
|
8798
9101
|
};
|
|
8799
9102
|
abortListener = rejectWithAbortReason;
|
|
@@ -8968,11 +9271,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8968
9271
|
const child = this.child;
|
|
8969
9272
|
this.readable = child.stdout;
|
|
8970
9273
|
this.writable = child.stdin;
|
|
9274
|
+
const stderrDecoder = new TextDecoder();
|
|
8971
9275
|
child.stderr.on("data", (chunk) => {
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
9276
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9277
|
+
this.appendStderrOutput(decoded);
|
|
9278
|
+
});
|
|
9279
|
+
child.stderr.once("end", () => {
|
|
9280
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8976
9281
|
});
|
|
8977
9282
|
this.closed = new Promise((resolve) => {
|
|
8978
9283
|
let settled = false;
|
|
@@ -9012,6 +9317,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
9012
9317
|
getStderrOutput() {
|
|
9013
9318
|
return this.stderrOutput;
|
|
9014
9319
|
}
|
|
9320
|
+
appendStderrOutput(chunk) {
|
|
9321
|
+
if (chunk.length === 0) {
|
|
9322
|
+
return;
|
|
9323
|
+
}
|
|
9324
|
+
this.stderrOutput += chunk;
|
|
9325
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9326
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9327
|
+
}
|
|
9328
|
+
}
|
|
9015
9329
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
9016
9330
|
void reason;
|
|
9017
9331
|
if (this.disposed) {
|
|
@@ -9419,15 +9733,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9419
9733
|
return `${JSON.stringify(message2)}
|
|
9420
9734
|
`;
|
|
9421
9735
|
}
|
|
9422
|
-
function chunkToString(chunk) {
|
|
9423
|
-
if (typeof chunk === "string") {
|
|
9424
|
-
return chunk;
|
|
9425
|
-
}
|
|
9426
|
-
if (chunk instanceof Uint8Array) {
|
|
9427
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9428
|
-
}
|
|
9429
|
-
return String(chunk);
|
|
9430
|
-
}
|
|
9431
9736
|
function normalizeLine(line) {
|
|
9432
9737
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9433
9738
|
}
|
|
@@ -9617,6 +9922,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9617
9922
|
}
|
|
9618
9923
|
});
|
|
9619
9924
|
}
|
|
9925
|
+
cancelRequest(requestId, reason) {
|
|
9926
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9927
|
+
if (pending === void 0) {
|
|
9928
|
+
return false;
|
|
9929
|
+
}
|
|
9930
|
+
this.pendingRequests.delete(requestId);
|
|
9931
|
+
clearTimeout(pending.timeout);
|
|
9932
|
+
pending.reject(reason);
|
|
9933
|
+
return true;
|
|
9934
|
+
}
|
|
9620
9935
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9621
9936
|
if (this.disposedError !== void 0) {
|
|
9622
9937
|
return;
|
|
@@ -9811,7 +10126,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9811
10126
|
})();
|
|
9812
10127
|
}
|
|
9813
10128
|
handleCancellationNotification(params17) {
|
|
9814
|
-
if (!
|
|
10129
|
+
if (!isObjectRecord5(params17)) {
|
|
9815
10130
|
return;
|
|
9816
10131
|
}
|
|
9817
10132
|
const requestId = params17.requestId;
|
|
@@ -9826,34 +10141,34 @@ var JsonRpcMessageLayer = class {
|
|
|
9826
10141
|
this.activeIncomingRequests.delete(requestId);
|
|
9827
10142
|
}
|
|
9828
10143
|
};
|
|
9829
|
-
function
|
|
10144
|
+
function isObjectRecord5(value) {
|
|
9830
10145
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9831
10146
|
}
|
|
9832
10147
|
function isInitializeResult(value) {
|
|
9833
|
-
if (!
|
|
10148
|
+
if (!isObjectRecord5(value) || typeof value.protocolVersion !== "string") {
|
|
9834
10149
|
return false;
|
|
9835
10150
|
}
|
|
9836
10151
|
if (!isServerCapabilities(value.capabilities)) {
|
|
9837
10152
|
return false;
|
|
9838
10153
|
}
|
|
9839
|
-
if (!
|
|
10154
|
+
if (!isObjectRecord5(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
|
|
9840
10155
|
return false;
|
|
9841
10156
|
}
|
|
9842
10157
|
return value.instructions === void 0 || typeof value.instructions === "string";
|
|
9843
10158
|
}
|
|
9844
10159
|
function isServerCapabilities(value) {
|
|
9845
|
-
if (!
|
|
10160
|
+
if (!isObjectRecord5(value)) {
|
|
9846
10161
|
return false;
|
|
9847
10162
|
}
|
|
9848
10163
|
for (const capability of ["prompts", "resources", "tools", "logging", "completions", "experimental"]) {
|
|
9849
|
-
if (value[capability] !== void 0 && !
|
|
10164
|
+
if (value[capability] !== void 0 && !isObjectRecord5(value[capability])) {
|
|
9850
10165
|
return false;
|
|
9851
10166
|
}
|
|
9852
10167
|
}
|
|
9853
10168
|
return true;
|
|
9854
10169
|
}
|
|
9855
10170
|
function isCallToolResult(value) {
|
|
9856
|
-
if (!
|
|
10171
|
+
if (!isObjectRecord5(value) || !Array.isArray(value.content)) {
|
|
9857
10172
|
return false;
|
|
9858
10173
|
}
|
|
9859
10174
|
if (value.isError !== void 0 && typeof value.isError !== "boolean") {
|
|
@@ -9862,10 +10177,10 @@ function isCallToolResult(value) {
|
|
|
9862
10177
|
return value.content.every(isContentItem);
|
|
9863
10178
|
}
|
|
9864
10179
|
function isToolsListResult(value) {
|
|
9865
|
-
return
|
|
10180
|
+
return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
9866
10181
|
}
|
|
9867
10182
|
function isContentItem(value) {
|
|
9868
|
-
if (!
|
|
10183
|
+
if (!isObjectRecord5(value)) {
|
|
9869
10184
|
return false;
|
|
9870
10185
|
}
|
|
9871
10186
|
if (value.type === "text") {
|
|
@@ -9874,7 +10189,7 @@ function isContentItem(value) {
|
|
|
9874
10189
|
if (value.type === "image" || value.type === "audio") {
|
|
9875
10190
|
return typeof value.data === "string" && typeof value.mimeType === "string";
|
|
9876
10191
|
}
|
|
9877
|
-
if (value.type !== "resource" || !
|
|
10192
|
+
if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
|
|
9878
10193
|
return false;
|
|
9879
10194
|
}
|
|
9880
10195
|
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");
|
|
@@ -9898,7 +10213,7 @@ function invalidRequest() {
|
|
|
9898
10213
|
return new McpError(ERROR_INVALID_REQUEST, "Invalid Request");
|
|
9899
10214
|
}
|
|
9900
10215
|
function isJsonRpcErrorObject(value) {
|
|
9901
|
-
if (!
|
|
10216
|
+
if (!isObjectRecord5(value)) {
|
|
9902
10217
|
return false;
|
|
9903
10218
|
}
|
|
9904
10219
|
if (typeof value.code !== "number" || typeof value.message !== "string") {
|
|
@@ -9907,7 +10222,7 @@ function isJsonRpcErrorObject(value) {
|
|
|
9907
10222
|
return value.data === void 0 || hasOwn(value, "data");
|
|
9908
10223
|
}
|
|
9909
10224
|
function parseJsonRpcPayload(parsed) {
|
|
9910
|
-
if (!
|
|
10225
|
+
if (!isObjectRecord5(parsed)) {
|
|
9911
10226
|
return {
|
|
9912
10227
|
type: "invalid",
|
|
9913
10228
|
id: null,
|
|
@@ -10234,7 +10549,11 @@ function convertObjectSchema(schema, root, options) {
|
|
|
10234
10549
|
"properties",
|
|
10235
10550
|
key2
|
|
10236
10551
|
]);
|
|
10237
|
-
|
|
10552
|
+
setOwnShapeProperty(
|
|
10553
|
+
shape,
|
|
10554
|
+
key2,
|
|
10555
|
+
requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty)
|
|
10556
|
+
);
|
|
10238
10557
|
}
|
|
10239
10558
|
return applyMetadata(
|
|
10240
10559
|
S.Object(shape, {
|
|
@@ -10246,6 +10565,14 @@ function convertObjectSchema(schema, root, options) {
|
|
|
10246
10565
|
}
|
|
10247
10566
|
);
|
|
10248
10567
|
}
|
|
10568
|
+
function setOwnShapeProperty(shape, key2, value) {
|
|
10569
|
+
Object.defineProperty(shape, key2, {
|
|
10570
|
+
configurable: true,
|
|
10571
|
+
enumerable: true,
|
|
10572
|
+
writable: true,
|
|
10573
|
+
value
|
|
10574
|
+
});
|
|
10575
|
+
}
|
|
10249
10576
|
function createCommonOptions(schema, nullable, defaultValue) {
|
|
10250
10577
|
return {
|
|
10251
10578
|
...schema.description === void 0 ? {} : { description: schema.description },
|
|
@@ -10496,6 +10823,9 @@ function resolveLocalRef(root, ref) {
|
|
|
10496
10823
|
if (!isPlainObject(current)) {
|
|
10497
10824
|
return void 0;
|
|
10498
10825
|
}
|
|
10826
|
+
if (!Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
10827
|
+
return void 0;
|
|
10828
|
+
}
|
|
10499
10829
|
current = current[segment];
|
|
10500
10830
|
}
|
|
10501
10831
|
return isPlainObject(current) ? current : void 0;
|
|
@@ -10685,10 +11015,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10685
11015
|
}
|
|
10686
11016
|
}
|
|
10687
11017
|
}
|
|
10688
|
-
function createConnection(name,
|
|
11018
|
+
function createConnection(name, config2) {
|
|
10689
11019
|
const connection = {
|
|
10690
11020
|
name,
|
|
10691
|
-
config,
|
|
11021
|
+
config: config2,
|
|
10692
11022
|
async dispose() {
|
|
10693
11023
|
shutdownDisposers.delete(connection.dispose);
|
|
10694
11024
|
connection.connecting = void 0;
|
|
@@ -10744,24 +11074,42 @@ async function readCache(cachePath) {
|
|
|
10744
11074
|
}
|
|
10745
11075
|
async function writeCache(cachePath, cache) {
|
|
10746
11076
|
const directory = path12.dirname(cachePath);
|
|
10747
|
-
const tempPath = `${cachePath}.tmp-${
|
|
11077
|
+
const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
|
|
11078
|
+
let tempCreated = false;
|
|
10748
11079
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10749
11080
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10750
11081
|
await mkdir(directory, { recursive: true });
|
|
10751
11082
|
await assertCachePathHasNoSymlinks(directory);
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
11083
|
+
try {
|
|
11084
|
+
await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
|
|
11085
|
+
`, {
|
|
11086
|
+
encoding: "utf8",
|
|
11087
|
+
flag: "wx"
|
|
11088
|
+
});
|
|
11089
|
+
tempCreated = true;
|
|
11090
|
+
await assertCachePathHasNoSymlinks(tempPath);
|
|
11091
|
+
await assertCachePathHasNoSymlinks(cachePath);
|
|
11092
|
+
await rename2(tempPath, cachePath);
|
|
11093
|
+
tempCreated = false;
|
|
11094
|
+
} catch (error3) {
|
|
11095
|
+
if (tempCreated || !isAlreadyExistsError2(error3)) {
|
|
11096
|
+
await unlink2(tempPath).catch(() => void 0);
|
|
11097
|
+
}
|
|
11098
|
+
throw error3;
|
|
11099
|
+
}
|
|
11100
|
+
}
|
|
11101
|
+
function isAlreadyExistsError2(error3) {
|
|
11102
|
+
return Boolean(
|
|
11103
|
+
error3 && typeof error3 === "object" && error3.code === "EEXIST"
|
|
11104
|
+
);
|
|
10757
11105
|
}
|
|
10758
|
-
async function fetchCache(name,
|
|
11106
|
+
async function fetchCache(name, config2) {
|
|
10759
11107
|
const logger2 = createLogger((message2) => {
|
|
10760
11108
|
process.stderr.write(`${message2}
|
|
10761
11109
|
`);
|
|
10762
11110
|
});
|
|
10763
11111
|
logger2.info(`MCP ${name}: connecting`);
|
|
10764
|
-
const client = await dialUpstream(name,
|
|
11112
|
+
const client = await dialUpstream(name, config2);
|
|
10765
11113
|
try {
|
|
10766
11114
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10767
11115
|
const tools = [];
|
|
@@ -10780,7 +11128,7 @@ async function fetchCache(name, config) {
|
|
|
10780
11128
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10781
11129
|
version: 1,
|
|
10782
11130
|
upstream,
|
|
10783
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
11131
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10784
11132
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10785
11133
|
tools
|
|
10786
11134
|
};
|
|
@@ -10850,8 +11198,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10850
11198
|
}
|
|
10851
11199
|
async function resolveSingleProxy(group, options) {
|
|
10852
11200
|
const internal = getInternalGroupConfig2(group);
|
|
10853
|
-
const
|
|
10854
|
-
if (
|
|
11201
|
+
const config2 = internal.mcp;
|
|
11202
|
+
if (config2 === void 0) {
|
|
10855
11203
|
return;
|
|
10856
11204
|
}
|
|
10857
11205
|
const name = group.name;
|
|
@@ -10861,21 +11209,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10861
11209
|
let cache;
|
|
10862
11210
|
let shouldWriteCache = false;
|
|
10863
11211
|
if (isRefreshRequested(name, refresh)) {
|
|
10864
|
-
cache = await fetchCache(name,
|
|
11212
|
+
cache = await fetchCache(name, config2);
|
|
10865
11213
|
shouldWriteCache = true;
|
|
10866
11214
|
} else {
|
|
10867
11215
|
const storedCache = await readCache(cachePath);
|
|
10868
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
11216
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10869
11217
|
cache = storedCache;
|
|
10870
11218
|
} else {
|
|
10871
|
-
cache = await fetchCache(name,
|
|
11219
|
+
cache = await fetchCache(name, config2);
|
|
10872
11220
|
shouldWriteCache = true;
|
|
10873
11221
|
}
|
|
10874
11222
|
}
|
|
10875
11223
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10876
11224
|
validateRenameMap2(name, tools, internal.rename);
|
|
10877
11225
|
const previousConnection = getProxyConnection(group);
|
|
10878
|
-
const nextConnection = createConnection(name,
|
|
11226
|
+
const nextConnection = createConnection(name, config2);
|
|
10879
11227
|
try {
|
|
10880
11228
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10881
11229
|
if (shouldWriteCache) {
|
|
@@ -10900,11 +11248,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10900
11248
|
);
|
|
10901
11249
|
}
|
|
10902
11250
|
}
|
|
10903
|
-
function cacheMatchesConfig(cache,
|
|
10904
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
11251
|
+
function cacheMatchesConfig(cache, config2) {
|
|
11252
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10905
11253
|
}
|
|
10906
|
-
function fingerprintMcpServerConfig(
|
|
10907
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
11254
|
+
function fingerprintMcpServerConfig(config2) {
|
|
11255
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10908
11256
|
}
|
|
10909
11257
|
function collectProxyGroups(root) {
|
|
10910
11258
|
const groups = [];
|
|
@@ -10982,20 +11330,20 @@ function parseRefreshEnv(value) {
|
|
|
10982
11330
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10983
11331
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10984
11332
|
}
|
|
10985
|
-
async function dialUpstream(name,
|
|
11333
|
+
async function dialUpstream(name, config2) {
|
|
10986
11334
|
const client = new McpClient({
|
|
10987
11335
|
clientInfo: {
|
|
10988
11336
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10989
11337
|
version: DEFAULT_CLIENT_INFO.version
|
|
10990
11338
|
}
|
|
10991
11339
|
});
|
|
10992
|
-
const transport =
|
|
10993
|
-
command:
|
|
10994
|
-
...
|
|
10995
|
-
...
|
|
11340
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11341
|
+
command: config2.command,
|
|
11342
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11343
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10996
11344
|
}) : new HttpTransport({
|
|
10997
|
-
url:
|
|
10998
|
-
...
|
|
11345
|
+
url: config2.url,
|
|
11346
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10999
11347
|
});
|
|
11000
11348
|
await client.connect(transport);
|
|
11001
11349
|
return client;
|
|
@@ -11005,10 +11353,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
11005
11353
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
11006
11354
|
}
|
|
11007
11355
|
|
|
11356
|
+
// ../toolcraft/src/redaction.ts
|
|
11357
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11358
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11359
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11360
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11361
|
+
function isPlainObject2(value) {
|
|
11362
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11363
|
+
}
|
|
11364
|
+
function normalizeName(name) {
|
|
11365
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11366
|
+
}
|
|
11367
|
+
function isSensitiveName(name) {
|
|
11368
|
+
const normalized = normalizeName(name);
|
|
11369
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11370
|
+
}
|
|
11371
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11372
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11373
|
+
return REDACTED_VALUE;
|
|
11374
|
+
}
|
|
11375
|
+
if (Array.isArray(value)) {
|
|
11376
|
+
if (seen.has(value)) {
|
|
11377
|
+
return "[Circular]";
|
|
11378
|
+
}
|
|
11379
|
+
seen.add(value);
|
|
11380
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11381
|
+
}
|
|
11382
|
+
if (isPlainObject2(value)) {
|
|
11383
|
+
if (seen.has(value)) {
|
|
11384
|
+
return "[Circular]";
|
|
11385
|
+
}
|
|
11386
|
+
seen.add(value);
|
|
11387
|
+
return Object.fromEntries(
|
|
11388
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11389
|
+
key2,
|
|
11390
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11391
|
+
])
|
|
11392
|
+
);
|
|
11393
|
+
}
|
|
11394
|
+
return value;
|
|
11395
|
+
}
|
|
11396
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11397
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11398
|
+
}
|
|
11399
|
+
function parseJsonObjectOrArray(value) {
|
|
11400
|
+
const trimmed = value.trim();
|
|
11401
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11402
|
+
return void 0;
|
|
11403
|
+
}
|
|
11404
|
+
try {
|
|
11405
|
+
const parsed = JSON.parse(trimmed);
|
|
11406
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11407
|
+
} catch {
|
|
11408
|
+
return void 0;
|
|
11409
|
+
}
|
|
11410
|
+
}
|
|
11411
|
+
function redactHttpBody(body) {
|
|
11412
|
+
if (typeof body === "string") {
|
|
11413
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11414
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11415
|
+
}
|
|
11416
|
+
return redactSecretLikeFields(body);
|
|
11417
|
+
}
|
|
11418
|
+
function redactHttpHeaderValue(name, value) {
|
|
11419
|
+
const normalized = normalizeName(name);
|
|
11420
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11421
|
+
return "Bearer ****";
|
|
11422
|
+
}
|
|
11423
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11424
|
+
return REDACTED_VALUE;
|
|
11425
|
+
}
|
|
11426
|
+
return value;
|
|
11427
|
+
}
|
|
11428
|
+
|
|
11008
11429
|
// ../toolcraft/src/error-report.ts
|
|
11009
11430
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
11010
|
-
|
|
11011
|
-
function isPlainObject2(value) {
|
|
11431
|
+
function isPlainObject3(value) {
|
|
11012
11432
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11013
11433
|
}
|
|
11014
11434
|
function unwrapOptional(schema) {
|
|
@@ -11018,7 +11438,7 @@ function unwrapOptional(schema) {
|
|
|
11018
11438
|
return schema;
|
|
11019
11439
|
}
|
|
11020
11440
|
function hasHttpContext(error3) {
|
|
11021
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11441
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
11022
11442
|
}
|
|
11023
11443
|
function isSkippedError(error3) {
|
|
11024
11444
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -11055,8 +11475,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
|
11055
11475
|
throw new Error("Error report directory resolves outside project root.");
|
|
11056
11476
|
}
|
|
11057
11477
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
11058
|
-
|
|
11059
|
-
|
|
11478
|
+
realpath2(projectRoot),
|
|
11479
|
+
realpath2(reportDir)
|
|
11060
11480
|
]);
|
|
11061
11481
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
11062
11482
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -11111,9 +11531,24 @@ function redactValue(value) {
|
|
|
11111
11531
|
}
|
|
11112
11532
|
return `<set, ${value.length} chars>`;
|
|
11113
11533
|
}
|
|
11114
|
-
function
|
|
11115
|
-
|
|
11116
|
-
|
|
11534
|
+
function collectStringLeaves(value, output) {
|
|
11535
|
+
if (typeof value === "string") {
|
|
11536
|
+
if (value.length > 0) {
|
|
11537
|
+
output.add(value);
|
|
11538
|
+
}
|
|
11539
|
+
return;
|
|
11540
|
+
}
|
|
11541
|
+
if (Array.isArray(value)) {
|
|
11542
|
+
for (const entry of value) {
|
|
11543
|
+
collectStringLeaves(entry, output);
|
|
11544
|
+
}
|
|
11545
|
+
return;
|
|
11546
|
+
}
|
|
11547
|
+
if (isPlainObject3(value)) {
|
|
11548
|
+
for (const entry of Object.values(value)) {
|
|
11549
|
+
collectStringLeaves(entry, output);
|
|
11550
|
+
}
|
|
11551
|
+
}
|
|
11117
11552
|
}
|
|
11118
11553
|
function schemaSecretValue(schema) {
|
|
11119
11554
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -11134,7 +11569,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
11134
11569
|
return "<redacted>";
|
|
11135
11570
|
}
|
|
11136
11571
|
const unwrapped = unwrapOptional(schema);
|
|
11137
|
-
if (unwrapped.kind === "object" &&
|
|
11572
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11138
11573
|
return Object.fromEntries(
|
|
11139
11574
|
Object.entries(value).map(([key2, childValue]) => {
|
|
11140
11575
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -11156,6 +11591,52 @@ function redactParams(params17, command) {
|
|
|
11156
11591
|
}
|
|
11157
11592
|
return redactParamsValue(params17, command.params, "");
|
|
11158
11593
|
}
|
|
11594
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11595
|
+
if (shouldRedactParam(name, schema)) {
|
|
11596
|
+
collectStringLeaves(value, output);
|
|
11597
|
+
return;
|
|
11598
|
+
}
|
|
11599
|
+
const unwrapped = unwrapOptional(schema);
|
|
11600
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11601
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11602
|
+
const childSchema = unwrapped.shape[key2];
|
|
11603
|
+
if (childSchema !== void 0) {
|
|
11604
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11605
|
+
}
|
|
11606
|
+
}
|
|
11607
|
+
return;
|
|
11608
|
+
}
|
|
11609
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11610
|
+
for (const entry of value) {
|
|
11611
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11612
|
+
}
|
|
11613
|
+
}
|
|
11614
|
+
}
|
|
11615
|
+
function createReportStringRedactor(context, env) {
|
|
11616
|
+
const values = /* @__PURE__ */ new Set();
|
|
11617
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11618
|
+
if (value !== void 0 && value.length > 0) {
|
|
11619
|
+
values.add(value);
|
|
11620
|
+
}
|
|
11621
|
+
}
|
|
11622
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11623
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11624
|
+
if (value !== void 0 && value.length > 0) {
|
|
11625
|
+
values.add(value);
|
|
11626
|
+
}
|
|
11627
|
+
}
|
|
11628
|
+
if (context.command !== void 0) {
|
|
11629
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11630
|
+
}
|
|
11631
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11632
|
+
return (value) => {
|
|
11633
|
+
let redacted = value;
|
|
11634
|
+
for (const secretValue of orderedValues) {
|
|
11635
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11636
|
+
}
|
|
11637
|
+
return redacted;
|
|
11638
|
+
};
|
|
11639
|
+
}
|
|
11159
11640
|
function commandSecretEnvNames(secrets) {
|
|
11160
11641
|
if (secrets === void 0) {
|
|
11161
11642
|
return [];
|
|
@@ -11209,28 +11690,42 @@ function redactArgv(argv, options) {
|
|
|
11209
11690
|
function stableJson(value) {
|
|
11210
11691
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
11211
11692
|
}
|
|
11212
|
-
function redactStructuredErrorField(name, value) {
|
|
11213
|
-
if (typeof value === "string"
|
|
11214
|
-
|
|
11693
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11694
|
+
if (typeof value === "string") {
|
|
11695
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11696
|
+
if (redactedHeaderValue !== value) {
|
|
11697
|
+
return redactedHeaderValue;
|
|
11698
|
+
}
|
|
11699
|
+
if (isSensitiveName(name)) {
|
|
11700
|
+
return "<redacted>";
|
|
11701
|
+
}
|
|
11702
|
+
return redactString(value);
|
|
11215
11703
|
}
|
|
11216
11704
|
if (Array.isArray(value)) {
|
|
11217
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11705
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
11218
11706
|
}
|
|
11219
|
-
if (
|
|
11707
|
+
if (isPlainObject3(value)) {
|
|
11220
11708
|
return Object.fromEntries(
|
|
11221
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11709
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11710
|
+
key2,
|
|
11711
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11712
|
+
])
|
|
11222
11713
|
);
|
|
11223
11714
|
}
|
|
11224
11715
|
return value;
|
|
11225
11716
|
}
|
|
11226
|
-
function ownStructuredFields(error3) {
|
|
11717
|
+
function ownStructuredFields(error3, redactString) {
|
|
11227
11718
|
const fields = {};
|
|
11228
11719
|
for (const key2 of Object.keys(error3)) {
|
|
11229
11720
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
11230
11721
|
continue;
|
|
11231
11722
|
}
|
|
11232
11723
|
Object.defineProperty(fields, key2, {
|
|
11233
|
-
value: redactStructuredErrorField(
|
|
11724
|
+
value: redactStructuredErrorField(
|
|
11725
|
+
key2,
|
|
11726
|
+
error3[key2],
|
|
11727
|
+
redactString
|
|
11728
|
+
),
|
|
11234
11729
|
enumerable: true,
|
|
11235
11730
|
configurable: true,
|
|
11236
11731
|
writable: true
|
|
@@ -11238,43 +11733,44 @@ function ownStructuredFields(error3) {
|
|
|
11238
11733
|
}
|
|
11239
11734
|
return fields;
|
|
11240
11735
|
}
|
|
11241
|
-
function formatStackChain(error3) {
|
|
11736
|
+
function formatStackChain(error3, redactString) {
|
|
11242
11737
|
const lines = [];
|
|
11243
11738
|
let current = error3;
|
|
11244
11739
|
let index = 0;
|
|
11245
11740
|
while (current !== void 0) {
|
|
11246
11741
|
if (current instanceof Error) {
|
|
11247
|
-
|
|
11248
|
-
|
|
11249
|
-
);
|
|
11742
|
+
const stack = current.stack ?? String(current);
|
|
11743
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
11250
11744
|
current = current.cause;
|
|
11251
11745
|
} else {
|
|
11252
|
-
|
|
11746
|
+
const message2 = String(current);
|
|
11747
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
11253
11748
|
current = void 0;
|
|
11254
11749
|
}
|
|
11255
11750
|
index += 1;
|
|
11256
11751
|
}
|
|
11257
11752
|
return lines.join("\n");
|
|
11258
11753
|
}
|
|
11259
|
-
function formatHeaderValue(name, value) {
|
|
11260
|
-
return name
|
|
11754
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11755
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
11261
11756
|
}
|
|
11262
|
-
function formatHeaders(headers) {
|
|
11263
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11757
|
+
function formatHeaders(headers, redactString) {
|
|
11758
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
11264
11759
|
}
|
|
11265
|
-
function formatBody(body) {
|
|
11266
|
-
|
|
11267
|
-
|
|
11760
|
+
function formatBody(body, redactString) {
|
|
11761
|
+
const redactedBody = redactHttpBody(body);
|
|
11762
|
+
if (typeof redactedBody === "string") {
|
|
11763
|
+
return redactString(redactedBody);
|
|
11268
11764
|
}
|
|
11269
|
-
return stableJson(
|
|
11765
|
+
return redactString(stableJson(redactedBody));
|
|
11270
11766
|
}
|
|
11271
|
-
function formatHttpTranscript(error3) {
|
|
11767
|
+
function formatHttpTranscript(error3, redactString) {
|
|
11272
11768
|
const requestLines = [
|
|
11273
11769
|
`${error3.request.method} ${error3.request.url}`,
|
|
11274
|
-
formatHeaders(error3.request.headers)
|
|
11770
|
+
formatHeaders(error3.request.headers, redactString)
|
|
11275
11771
|
].filter((line) => line.length > 0);
|
|
11276
11772
|
if (error3.request.body !== void 0) {
|
|
11277
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11773
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
11278
11774
|
}
|
|
11279
11775
|
return [
|
|
11280
11776
|
"Request:",
|
|
@@ -11282,9 +11778,9 @@ function formatHttpTranscript(error3) {
|
|
|
11282
11778
|
"",
|
|
11283
11779
|
"Response:",
|
|
11284
11780
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
11285
|
-
formatHeaders(error3.response.headers),
|
|
11781
|
+
formatHeaders(error3.response.headers, redactString),
|
|
11286
11782
|
"",
|
|
11287
|
-
formatBody(error3.response.body)
|
|
11783
|
+
formatBody(error3.response.body, redactString)
|
|
11288
11784
|
].join("\n");
|
|
11289
11785
|
}
|
|
11290
11786
|
function resolveToolcraftVersion(version) {
|
|
@@ -11293,9 +11789,10 @@ function resolveToolcraftVersion(version) {
|
|
|
11293
11789
|
function buildReport(context) {
|
|
11294
11790
|
const env = context.env ?? process.env;
|
|
11295
11791
|
const error3 = context.error;
|
|
11792
|
+
const redactString = createReportStringRedactor(context, env);
|
|
11296
11793
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11297
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11298
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11794
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11795
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11299
11796
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11300
11797
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11301
11798
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11309,7 +11806,9 @@ function buildReport(context) {
|
|
|
11309
11806
|
`platform: ${process.platform} ${process.arch}`,
|
|
11310
11807
|
"",
|
|
11311
11808
|
"Argv",
|
|
11312
|
-
|
|
11809
|
+
redactString(
|
|
11810
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11811
|
+
),
|
|
11313
11812
|
"",
|
|
11314
11813
|
"Resolved Secrets",
|
|
11315
11814
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11318,19 +11817,19 @@ function buildReport(context) {
|
|
|
11318
11817
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11319
11818
|
"",
|
|
11320
11819
|
"Parsed Params",
|
|
11321
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11820
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11322
11821
|
"",
|
|
11323
11822
|
"Error",
|
|
11324
11823
|
`name: ${errorName}`,
|
|
11325
11824
|
`message: ${errorMessage}`,
|
|
11326
11825
|
"structured fields:",
|
|
11327
|
-
stableJson(structuredFields),
|
|
11826
|
+
redactString(stableJson(structuredFields)),
|
|
11328
11827
|
"",
|
|
11329
11828
|
"Stack",
|
|
11330
|
-
formatStackChain(error3)
|
|
11829
|
+
formatStackChain(error3, redactString)
|
|
11331
11830
|
];
|
|
11332
11831
|
if (hasHttpContext(error3)) {
|
|
11333
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11832
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11334
11833
|
}
|
|
11335
11834
|
return `${lines.join("\n")}
|
|
11336
11835
|
`;
|
|
@@ -11342,7 +11841,7 @@ async function writeErrorReport(context) {
|
|
|
11342
11841
|
}
|
|
11343
11842
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11344
11843
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11345
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11844
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
|
|
11346
11845
|
const absolutePath = path13.join(reportDir, fileName);
|
|
11347
11846
|
await mkdir2(reportDir, { recursive: true });
|
|
11348
11847
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
@@ -11790,6 +12289,7 @@ ${rendered.join("\n")}`);
|
|
|
11790
12289
|
}
|
|
11791
12290
|
|
|
11792
12291
|
// ../toolcraft/src/cli.ts
|
|
12292
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11793
12293
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11794
12294
|
"params",
|
|
11795
12295
|
"secrets",
|
|
@@ -12820,10 +13320,10 @@ function renderHelpSections(sections) {
|
|
|
12820
13320
|
return sections.filter((section) => section.length > 0).join("\n\n");
|
|
12821
13321
|
}
|
|
12822
13322
|
function formatHelpCommandList(rows) {
|
|
12823
|
-
return process.stdout.isTTY
|
|
13323
|
+
return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
|
|
12824
13324
|
}
|
|
12825
13325
|
function formatHelpOptionList(rows) {
|
|
12826
|
-
return process.stdout.isTTY
|
|
13326
|
+
return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
|
|
12827
13327
|
}
|
|
12828
13328
|
function buildUsageLine(breadcrumb, rootUsageName, suffix) {
|
|
12829
13329
|
const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
|
|
@@ -13111,11 +13611,18 @@ function formatResolvedValue(value) {
|
|
|
13111
13611
|
function fieldPromptLabel(field) {
|
|
13112
13612
|
return field.positionalIndex === void 0 ? field.optionFlag : `<${field.displayPath}>`;
|
|
13113
13613
|
}
|
|
13614
|
+
function enumOptionLabel(schema, value) {
|
|
13615
|
+
const key2 = String(value);
|
|
13616
|
+
if (schema.labels === void 0 || !Object.prototype.hasOwnProperty.call(schema.labels, key2)) {
|
|
13617
|
+
return key2;
|
|
13618
|
+
}
|
|
13619
|
+
return schema.labels[key2] ?? key2;
|
|
13620
|
+
}
|
|
13114
13621
|
async function promptForField(field) {
|
|
13115
13622
|
const schema = field.schema;
|
|
13116
13623
|
if (schema.kind === "enum") {
|
|
13117
13624
|
const options = schema.loadOptions ? await schema.loadOptions() : schema.values.map((value) => ({
|
|
13118
|
-
label: schema
|
|
13625
|
+
label: enumOptionLabel(schema, value),
|
|
13119
13626
|
value
|
|
13120
13627
|
}));
|
|
13121
13628
|
const selected = await select2({
|
|
@@ -13200,8 +13707,8 @@ async function withOutputFormat2(output, fn) {
|
|
|
13200
13707
|
function createFs2() {
|
|
13201
13708
|
return {
|
|
13202
13709
|
readFile: async (path25, encoding = "utf8") => readFile4(path25, { encoding }),
|
|
13203
|
-
writeFile: async (path25, contents) => {
|
|
13204
|
-
await writeFile5(path25, contents);
|
|
13710
|
+
writeFile: async (path25, contents, options) => {
|
|
13711
|
+
await writeFile5(path25, contents, options);
|
|
13205
13712
|
},
|
|
13206
13713
|
exists: async (path25) => {
|
|
13207
13714
|
try {
|
|
@@ -13213,7 +13720,7 @@ function createFs2() {
|
|
|
13213
13720
|
},
|
|
13214
13721
|
lstat: async (path25) => lstat3(path25),
|
|
13215
13722
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
13216
|
-
unlink: async (path25) =>
|
|
13723
|
+
unlink: async (path25) => unlink3(path25)
|
|
13217
13724
|
};
|
|
13218
13725
|
}
|
|
13219
13726
|
function createEnv2(values = process.env) {
|
|
@@ -13223,7 +13730,7 @@ function createEnv2(values = process.env) {
|
|
|
13223
13730
|
}
|
|
13224
13731
|
};
|
|
13225
13732
|
}
|
|
13226
|
-
function
|
|
13733
|
+
function isPlainObject4(value) {
|
|
13227
13734
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13228
13735
|
}
|
|
13229
13736
|
function hasFieldValue(value) {
|
|
@@ -13332,7 +13839,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13332
13839
|
{ cause: error3 }
|
|
13333
13840
|
);
|
|
13334
13841
|
}
|
|
13335
|
-
if (!
|
|
13842
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13336
13843
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13337
13844
|
}
|
|
13338
13845
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
@@ -13351,7 +13858,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13351
13858
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13352
13859
|
);
|
|
13353
13860
|
}
|
|
13354
|
-
if (!
|
|
13861
|
+
if (!isPlainObject4(value)) {
|
|
13355
13862
|
throw new UserError(
|
|
13356
13863
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13357
13864
|
);
|
|
@@ -13394,8 +13901,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13394
13901
|
}
|
|
13395
13902
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13396
13903
|
}
|
|
13397
|
-
if (
|
|
13398
|
-
if (!
|
|
13904
|
+
if (isPlainObject4(expected)) {
|
|
13905
|
+
if (!isPlainObject4(actual)) {
|
|
13399
13906
|
return false;
|
|
13400
13907
|
}
|
|
13401
13908
|
return Object.entries(expected).every(
|
|
@@ -13458,9 +13965,9 @@ function createFixtureFetch(entries) {
|
|
|
13458
13965
|
};
|
|
13459
13966
|
}
|
|
13460
13967
|
function createFixtureFs(definition) {
|
|
13461
|
-
const fsDefinition =
|
|
13462
|
-
const readFileEntries =
|
|
13463
|
-
const existsEntries =
|
|
13968
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13969
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13970
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13464
13971
|
return {
|
|
13465
13972
|
readFile: async (filePath) => {
|
|
13466
13973
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13483,10 +13990,10 @@ function createFixtureFs(definition) {
|
|
|
13483
13990
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13484
13991
|
if (Array.isArray(definition)) {
|
|
13485
13992
|
for (const entry of definition) {
|
|
13486
|
-
if (!
|
|
13993
|
+
if (!isPlainObject4(entry)) {
|
|
13487
13994
|
continue;
|
|
13488
13995
|
}
|
|
13489
|
-
const explicitMatcher =
|
|
13996
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13490
13997
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13491
13998
|
Object.entries(entry).filter(
|
|
13492
13999
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13498,7 +14005,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13498
14005
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13499
14006
|
} else if (Object.keys(matcher).length === 0) {
|
|
13500
14007
|
matched = true;
|
|
13501
|
-
} else if (
|
|
14008
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13502
14009
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13503
14010
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13504
14011
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13519,7 +14026,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13519
14026
|
return Promise.resolve(null);
|
|
13520
14027
|
}
|
|
13521
14028
|
}
|
|
13522
|
-
if (
|
|
14029
|
+
if (isPlainObject4(definition)) {
|
|
13523
14030
|
const firstArg = args[0];
|
|
13524
14031
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13525
14032
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13531,7 +14038,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13531
14038
|
return Promise.resolve(null);
|
|
13532
14039
|
}
|
|
13533
14040
|
function createFixtureService(definition) {
|
|
13534
|
-
const methods =
|
|
14041
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13535
14042
|
return new Proxy(
|
|
13536
14043
|
{},
|
|
13537
14044
|
{
|
|
@@ -13629,7 +14136,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13629
14136
|
};
|
|
13630
14137
|
}
|
|
13631
14138
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13632
|
-
const scenarioServices =
|
|
14139
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13633
14140
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13634
14141
|
...Object.keys(services),
|
|
13635
14142
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13911,7 +14418,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13911
14418
|
if (itemSchema.kind !== "object") {
|
|
13912
14419
|
return value;
|
|
13913
14420
|
}
|
|
13914
|
-
if (!
|
|
14421
|
+
if (!isPlainObject4(value)) {
|
|
13915
14422
|
errors2.push({
|
|
13916
14423
|
path: displayPath,
|
|
13917
14424
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13946,7 +14453,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13946
14453
|
);
|
|
13947
14454
|
}
|
|
13948
14455
|
case "object": {
|
|
13949
|
-
if (!
|
|
14456
|
+
if (!isPlainObject4(value)) {
|
|
13950
14457
|
errors2.push({
|
|
13951
14458
|
path: displayPath,
|
|
13952
14459
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13977,7 +14484,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13977
14484
|
return result;
|
|
13978
14485
|
}
|
|
13979
14486
|
case "record": {
|
|
13980
|
-
if (!
|
|
14487
|
+
if (!isPlainObject4(value)) {
|
|
13981
14488
|
errors2.push({
|
|
13982
14489
|
path: displayPath,
|
|
13983
14490
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14403,10 +14910,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14403
14910
|
}
|
|
14404
14911
|
}
|
|
14405
14912
|
function isStringRecord(value) {
|
|
14406
|
-
return
|
|
14913
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14407
14914
|
}
|
|
14408
14915
|
function isHttpErrorLike(error3) {
|
|
14409
|
-
if (!
|
|
14916
|
+
if (!isPlainObject4(error3)) {
|
|
14410
14917
|
return false;
|
|
14411
14918
|
}
|
|
14412
14919
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14414,7 +14921,7 @@ function isHttpErrorLike(error3) {
|
|
|
14414
14921
|
}
|
|
14415
14922
|
const request = error3.request;
|
|
14416
14923
|
const response = error3.response;
|
|
14417
|
-
return
|
|
14924
|
+
return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
|
|
14418
14925
|
}
|
|
14419
14926
|
function hasTypedOptionalField(value, field, type2) {
|
|
14420
14927
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14423,7 +14930,7 @@ function isNonEmptyString(value) {
|
|
|
14423
14930
|
return typeof value === "string" && value.trim().length > 0;
|
|
14424
14931
|
}
|
|
14425
14932
|
function isProblemDetailsLike(body) {
|
|
14426
|
-
if (!
|
|
14933
|
+
if (!isPlainObject4(body)) {
|
|
14427
14934
|
return false;
|
|
14428
14935
|
}
|
|
14429
14936
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14444,11 +14951,11 @@ function isProblemDetailsLike(body) {
|
|
|
14444
14951
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14445
14952
|
}
|
|
14446
14953
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14447
|
-
if (!
|
|
14954
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14448
14955
|
return false;
|
|
14449
14956
|
}
|
|
14450
14957
|
return body.errors.every((error3) => {
|
|
14451
|
-
if (!
|
|
14958
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14452
14959
|
return false;
|
|
14453
14960
|
}
|
|
14454
14961
|
if ("path" in error3) {
|
|
@@ -14458,7 +14965,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14458
14965
|
}
|
|
14459
14966
|
}
|
|
14460
14967
|
if ("extensions" in error3) {
|
|
14461
|
-
if (!
|
|
14968
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14462
14969
|
return false;
|
|
14463
14970
|
}
|
|
14464
14971
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14469,7 +14976,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14469
14976
|
});
|
|
14470
14977
|
}
|
|
14471
14978
|
function styleHttpErrorLine(value, style) {
|
|
14472
|
-
return process.stdout.isTTY
|
|
14979
|
+
return process.stdout.isTTY !== true ? value : style(value);
|
|
14473
14980
|
}
|
|
14474
14981
|
function formatHttpErrorStatus(value) {
|
|
14475
14982
|
return styleHttpErrorLine(value, text.error);
|
|
@@ -14506,23 +15013,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14506
15013
|
}).join("\n\n");
|
|
14507
15014
|
}
|
|
14508
15015
|
function formatHttpErrorBody(body) {
|
|
14509
|
-
|
|
14510
|
-
|
|
15016
|
+
const redactedBody = redactHttpBody(body);
|
|
15017
|
+
if (typeof redactedBody === "string") {
|
|
15018
|
+
return redactedBody;
|
|
14511
15019
|
}
|
|
14512
|
-
if (isProblemDetailsLike(
|
|
14513
|
-
return formatProblemDetailsBody(
|
|
15020
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
15021
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14514
15022
|
}
|
|
14515
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14516
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
15023
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
15024
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14517
15025
|
}
|
|
14518
|
-
const serialized = JSON.stringify(
|
|
14519
|
-
return serialized === void 0 ? String(
|
|
15026
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
15027
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14520
15028
|
}
|
|
14521
15029
|
function indentHttpErrorBlock(value) {
|
|
14522
15030
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14523
15031
|
}
|
|
14524
15032
|
function formatHttpHeaderValue(name, value) {
|
|
14525
|
-
return name
|
|
15033
|
+
return redactHttpHeaderValue(name, value);
|
|
14526
15034
|
}
|
|
14527
15035
|
function formatHttpErrorHeaders(headers) {
|
|
14528
15036
|
return Object.entries(headers).map(
|
|
@@ -14540,7 +15048,11 @@ function renderHttpError(error3, options) {
|
|
|
14540
15048
|
if (detailed) {
|
|
14541
15049
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14542
15050
|
if (error3.request.body !== void 0) {
|
|
14543
|
-
lines.push(
|
|
15051
|
+
lines.push(
|
|
15052
|
+
"Request body:",
|
|
15053
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
15054
|
+
""
|
|
15055
|
+
);
|
|
14544
15056
|
}
|
|
14545
15057
|
}
|
|
14546
15058
|
lines.push(
|
|
@@ -14946,7 +15458,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14946
15458
|
}
|
|
14947
15459
|
|
|
14948
15460
|
// src/terminal-pilot.ts
|
|
14949
|
-
import { randomUUID as
|
|
15461
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
14950
15462
|
|
|
14951
15463
|
// src/terminal-session.ts
|
|
14952
15464
|
import { EventEmitter } from "node:events";
|
|
@@ -14955,6 +15467,11 @@ import { createRequire } from "node:module";
|
|
|
14955
15467
|
import { dirname, join } from "node:path";
|
|
14956
15468
|
import * as nodePty from "node-pty";
|
|
14957
15469
|
|
|
15470
|
+
// src/errors.ts
|
|
15471
|
+
function hasOwnErrorCode(error3, code) {
|
|
15472
|
+
return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
|
|
15473
|
+
}
|
|
15474
|
+
|
|
14958
15475
|
// src/terminal-buffer.ts
|
|
14959
15476
|
var RESET_SGR = "\x1B[0m";
|
|
14960
15477
|
var DEC_SPECIAL_GRAPHICS = {
|
|
@@ -16054,10 +16571,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
16054
16571
|
}
|
|
16055
16572
|
}
|
|
16056
16573
|
function isMissingFileError(error3) {
|
|
16057
|
-
|
|
16058
|
-
return false;
|
|
16059
|
-
}
|
|
16060
|
-
return "code" in error3 && error3.code === "ENOENT";
|
|
16574
|
+
return hasOwnErrorCode(error3, "ENOENT");
|
|
16061
16575
|
}
|
|
16062
16576
|
function matchPattern(buffer, pattern) {
|
|
16063
16577
|
const clean = normalizeHistoryBuffer(stripAnsi(buffer));
|
|
@@ -16148,7 +16662,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
16148
16662
|
}
|
|
16149
16663
|
async newSession(opts) {
|
|
16150
16664
|
const session = new TerminalSession({
|
|
16151
|
-
id:
|
|
16665
|
+
id: randomUUID6(),
|
|
16152
16666
|
command: opts.command,
|
|
16153
16667
|
args: opts.args,
|
|
16154
16668
|
cwd: opts.cwd,
|
|
@@ -16434,6 +16948,11 @@ var claudeCodeAgent = {
|
|
|
16434
16948
|
aliases: ["claude"],
|
|
16435
16949
|
binaryName: "claude",
|
|
16436
16950
|
apiShapes: ["anthropic-messages"],
|
|
16951
|
+
otelCapture: {
|
|
16952
|
+
env: {
|
|
16953
|
+
CLAUDE_CODE_ENABLE_TELEMETRY: "1"
|
|
16954
|
+
}
|
|
16955
|
+
},
|
|
16437
16956
|
configPath: "~/.claude/settings.json",
|
|
16438
16957
|
branding: {
|
|
16439
16958
|
colors: {
|
|
@@ -16466,6 +16985,16 @@ var codexAgent = {
|
|
|
16466
16985
|
summary: "Configure Codex to use Poe as the model provider.",
|
|
16467
16986
|
binaryName: "codex",
|
|
16468
16987
|
apiShapes: ["openai-responses"],
|
|
16988
|
+
otelCapture: {
|
|
16989
|
+
args: (endpoint, content) => [
|
|
16990
|
+
"-c",
|
|
16991
|
+
`otel.trace_exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/traces`)},protocol="json"}}`,
|
|
16992
|
+
"-c",
|
|
16993
|
+
`otel.exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/logs`)},protocol="json"}}`,
|
|
16994
|
+
"-c",
|
|
16995
|
+
`otel.log_user_prompt=${content}`
|
|
16996
|
+
]
|
|
16997
|
+
},
|
|
16469
16998
|
configPath: "~/.codex/config.toml",
|
|
16470
16999
|
branding: {
|
|
16471
17000
|
colors: {
|
|
@@ -16501,6 +17030,11 @@ var openCodeAgent = {
|
|
|
16501
17030
|
summary: "Configure OpenCode CLI to use the Poe API.",
|
|
16502
17031
|
binaryName: "opencode",
|
|
16503
17032
|
apiShapes: ["openai-chat-completions"],
|
|
17033
|
+
otelCapture: {
|
|
17034
|
+
env: {
|
|
17035
|
+
OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
|
|
17036
|
+
}
|
|
17037
|
+
},
|
|
16504
17038
|
configPath: "~/.config/opencode/config.json",
|
|
16505
17039
|
branding: {
|
|
16506
17040
|
colors: {
|
|
@@ -16536,6 +17070,7 @@ var gooseAgent = {
|
|
|
16536
17070
|
summary: "Block's open-source AI agent with ACP support.",
|
|
16537
17071
|
binaryName: "goose",
|
|
16538
17072
|
apiShapes: ["openai-chat-completions"],
|
|
17073
|
+
otelCapture: {},
|
|
16539
17074
|
configPath: "~/.config/goose/config.yaml",
|
|
16540
17075
|
branding: {
|
|
16541
17076
|
colors: {
|
|
@@ -16569,6 +17104,12 @@ function freezeAgent(agent) {
|
|
|
16569
17104
|
if (agent.apiShapes !== void 0) {
|
|
16570
17105
|
Object.freeze(agent.apiShapes);
|
|
16571
17106
|
}
|
|
17107
|
+
if (agent.otelCapture?.env !== void 0) {
|
|
17108
|
+
Object.freeze(agent.otelCapture.env);
|
|
17109
|
+
}
|
|
17110
|
+
if (agent.otelCapture !== void 0) {
|
|
17111
|
+
Object.freeze(agent.otelCapture);
|
|
17112
|
+
}
|
|
16572
17113
|
Object.freeze(agent.branding.colors);
|
|
16573
17114
|
Object.freeze(agent.branding);
|
|
16574
17115
|
return Object.freeze(agent);
|
|
@@ -16629,11 +17170,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16629
17170
|
if (!resolvedId) {
|
|
16630
17171
|
return { status: "unknown", input };
|
|
16631
17172
|
}
|
|
16632
|
-
const
|
|
16633
|
-
if (!
|
|
17173
|
+
const config2 = registry[resolvedId];
|
|
17174
|
+
if (!config2) {
|
|
16634
17175
|
return { status: "unsupported", input, id: resolvedId };
|
|
16635
17176
|
}
|
|
16636
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
17177
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16637
17178
|
}
|
|
16638
17179
|
function getAgentConfig(agentId) {
|
|
16639
17180
|
const support = resolveAgentSupport(agentId);
|
|
@@ -16732,6 +17273,7 @@ var templateMutation = {
|
|
|
16732
17273
|
};
|
|
16733
17274
|
|
|
16734
17275
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
17276
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
16735
17277
|
import path17 from "node:path";
|
|
16736
17278
|
|
|
16737
17279
|
// ../config-mutations/src/formats/json.ts
|
|
@@ -16807,7 +17349,7 @@ function merge(base, patch) {
|
|
|
16807
17349
|
if (value === void 0) {
|
|
16808
17350
|
continue;
|
|
16809
17351
|
}
|
|
16810
|
-
const existing = result[key2];
|
|
17352
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
16811
17353
|
if (isConfigObject(existing) && isConfigObject(value)) {
|
|
16812
17354
|
setConfigEntry(result, key2, merge(existing, value));
|
|
16813
17355
|
continue;
|
|
@@ -16935,7 +17477,7 @@ function merge2(base, patch) {
|
|
|
16935
17477
|
if (value === void 0) {
|
|
16936
17478
|
continue;
|
|
16937
17479
|
}
|
|
16938
|
-
const existing = result[key2];
|
|
17480
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
16939
17481
|
if (isConfigObject2(existing) && isConfigObject2(value)) {
|
|
16940
17482
|
setConfigEntry(result, key2, merge2(existing, value));
|
|
16941
17483
|
continue;
|
|
@@ -17015,7 +17557,7 @@ function merge3(base, patch) {
|
|
|
17015
17557
|
if (value === void 0) {
|
|
17016
17558
|
continue;
|
|
17017
17559
|
}
|
|
17018
|
-
const existing = result[key2];
|
|
17560
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
17019
17561
|
if (isConfigObject3(existing) && isConfigObject3(value)) {
|
|
17020
17562
|
setConfigEntry(result, key2, merge3(existing, value));
|
|
17021
17563
|
continue;
|
|
@@ -17152,7 +17694,7 @@ function resolvePath(rawPath, homeDir, pathMapper) {
|
|
|
17152
17694
|
|
|
17153
17695
|
// ../config-mutations/src/fs-utils.ts
|
|
17154
17696
|
function isNotFound(error3) {
|
|
17155
|
-
return typeof error3 === "object" && error3 !== null && "code"
|
|
17697
|
+
return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT";
|
|
17156
17698
|
}
|
|
17157
17699
|
async function readFileIfExists(fs4, target) {
|
|
17158
17700
|
try {
|
|
@@ -17201,6 +17743,7 @@ async function backupInvalidDocument(context, targetPath, content) {
|
|
|
17201
17743
|
return;
|
|
17202
17744
|
} catch (error3) {
|
|
17203
17745
|
if (!isAlreadyExists(error3)) {
|
|
17746
|
+
await context.fs.unlink(backupPath).catch(() => void 0);
|
|
17204
17747
|
throw error3;
|
|
17205
17748
|
}
|
|
17206
17749
|
attempt += 1;
|
|
@@ -17208,7 +17751,7 @@ async function backupInvalidDocument(context, targetPath, content) {
|
|
|
17208
17751
|
}
|
|
17209
17752
|
}
|
|
17210
17753
|
function isAlreadyExists(error3) {
|
|
17211
|
-
return
|
|
17754
|
+
return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
|
|
17212
17755
|
}
|
|
17213
17756
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
17214
17757
|
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
@@ -17232,28 +17775,34 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
17232
17775
|
}
|
|
17233
17776
|
async function writeAtomically2(context, targetPath, content) {
|
|
17234
17777
|
await assertRegularWriteTarget(context, targetPath);
|
|
17235
|
-
let attempt = 0;
|
|
17236
|
-
|
|
17237
|
-
|
|
17778
|
+
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
17779
|
+
const tempPath = `${targetPath}.mutation-tmp-${process.pid}-${randomUUID7()}`;
|
|
17780
|
+
let tempCreated = false;
|
|
17238
17781
|
try {
|
|
17782
|
+
await assertRegularWriteTarget(context, tempPath);
|
|
17239
17783
|
await context.fs.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
17784
|
+
tempCreated = true;
|
|
17240
17785
|
await context.fs.rename(tempPath, targetPath);
|
|
17786
|
+
tempCreated = false;
|
|
17241
17787
|
return;
|
|
17242
17788
|
} catch (error3) {
|
|
17243
|
-
|
|
17244
|
-
|
|
17245
|
-
|
|
17246
|
-
|
|
17247
|
-
|
|
17248
|
-
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
void cleanupError;
|
|
17789
|
+
const alreadyExists = isAlreadyExists(error3);
|
|
17790
|
+
if (tempCreated || !alreadyExists) {
|
|
17791
|
+
try {
|
|
17792
|
+
await context.fs.unlink(tempPath);
|
|
17793
|
+
} catch (cleanupError) {
|
|
17794
|
+
if (!isNotFound(cleanupError)) {
|
|
17795
|
+
void cleanupError;
|
|
17796
|
+
}
|
|
17252
17797
|
}
|
|
17253
17798
|
}
|
|
17799
|
+
if (alreadyExists) {
|
|
17800
|
+
continue;
|
|
17801
|
+
}
|
|
17254
17802
|
throw error3;
|
|
17255
17803
|
}
|
|
17256
17804
|
}
|
|
17805
|
+
throw new Error(`Unable to create temporary mutation file for ${targetPath}.`);
|
|
17257
17806
|
}
|
|
17258
17807
|
function describeMutation(kind, targetPath) {
|
|
17259
17808
|
const displayPath = targetPath ?? "target";
|
|
@@ -17545,6 +18094,7 @@ async function applyBackup(mutation, context, options) {
|
|
|
17545
18094
|
break;
|
|
17546
18095
|
} catch (error3) {
|
|
17547
18096
|
if (!isAlreadyExists(error3)) {
|
|
18097
|
+
await context.fs.unlink(backupPath).catch(() => void 0);
|
|
17548
18098
|
throw error3;
|
|
17549
18099
|
}
|
|
17550
18100
|
attempt += 1;
|
|
@@ -17952,7 +18502,7 @@ async function pathExists2(fs4, targetPath) {
|
|
|
17952
18502
|
await fs4.stat(targetPath);
|
|
17953
18503
|
return true;
|
|
17954
18504
|
} catch (error3) {
|
|
17955
|
-
if (
|
|
18505
|
+
if (typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT") {
|
|
17956
18506
|
return false;
|
|
17957
18507
|
}
|
|
17958
18508
|
throw error3;
|
|
@@ -17965,14 +18515,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17965
18515
|
throw new UnsupportedAgentError(agentId);
|
|
17966
18516
|
}
|
|
17967
18517
|
const scope = options.scope ?? "local";
|
|
17968
|
-
const
|
|
18518
|
+
const config2 = support.config;
|
|
17969
18519
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17970
18520
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17971
18521
|
}
|
|
17972
|
-
const skillDir = scope === "global" ?
|
|
18522
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17973
18523
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17974
18524
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17975
|
-
const displayPath = `${scope === "global" ?
|
|
18525
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17976
18526
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17977
18527
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17978
18528
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -18011,12 +18561,13 @@ import path19 from "node:path";
|
|
|
18011
18561
|
|
|
18012
18562
|
// ../agent-skill-config/src/git-exclude.ts
|
|
18013
18563
|
import { execFileSync } from "node:child_process";
|
|
18564
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
18014
18565
|
import * as fs2 from "node:fs";
|
|
18015
18566
|
import path20 from "node:path";
|
|
18016
18567
|
|
|
18017
18568
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
18018
18569
|
import * as fs3 from "node:fs";
|
|
18019
|
-
import { createHash as createHash4, randomUUID as
|
|
18570
|
+
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
18020
18571
|
import path21 from "node:path";
|
|
18021
18572
|
|
|
18022
18573
|
// src/commands/installer.ts
|
|
@@ -18029,7 +18580,7 @@ var DEFAULT_INSTALL_SCOPE = "local";
|
|
|
18029
18580
|
var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
|
|
18030
18581
|
var installableAgents = supportedAgents;
|
|
18031
18582
|
function isNotFoundError2(error3) {
|
|
18032
|
-
return
|
|
18583
|
+
return hasOwnErrorCode(error3, "ENOENT");
|
|
18033
18584
|
}
|
|
18034
18585
|
function resolveInstallerServices(installer) {
|
|
18035
18586
|
return {
|
|
@@ -18093,17 +18644,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
18093
18644
|
return targetPath;
|
|
18094
18645
|
}
|
|
18095
18646
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
18096
|
-
const
|
|
18097
|
-
if (!
|
|
18647
|
+
const config2 = getAgentConfig(agent);
|
|
18648
|
+
if (!config2) {
|
|
18098
18649
|
throwUnsupportedAgent(agent);
|
|
18099
18650
|
}
|
|
18100
18651
|
return {
|
|
18101
18652
|
displayPath: path22.join(
|
|
18102
|
-
scope === "global" ?
|
|
18653
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
18103
18654
|
TERMINAL_PILOT_SKILL_NAME
|
|
18104
18655
|
),
|
|
18105
18656
|
fullPath: path22.join(
|
|
18106
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18657
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
18107
18658
|
TERMINAL_PILOT_SKILL_NAME
|
|
18108
18659
|
)
|
|
18109
18660
|
};
|
|
@@ -18260,7 +18811,7 @@ var resize = defineCommand({
|
|
|
18260
18811
|
});
|
|
18261
18812
|
|
|
18262
18813
|
// ../terminal-png/src/index.ts
|
|
18263
|
-
import { randomUUID as
|
|
18814
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
18264
18815
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
18265
18816
|
|
|
18266
18817
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -19200,21 +19751,28 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
19200
19751
|
});
|
|
19201
19752
|
const png = renderPng(svg);
|
|
19202
19753
|
if (options.output) {
|
|
19203
|
-
const temporaryPath = `${options.output}.${
|
|
19754
|
+
const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
|
|
19755
|
+
let temporaryCreated = false;
|
|
19204
19756
|
try {
|
|
19205
19757
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
19758
|
+
temporaryCreated = true;
|
|
19206
19759
|
await rename4(temporaryPath, options.output);
|
|
19207
19760
|
} catch (error3) {
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
19211
|
-
|
|
19761
|
+
if (temporaryCreated || !isAlreadyExistsError3(error3)) {
|
|
19762
|
+
try {
|
|
19763
|
+
await rm(temporaryPath, { force: true });
|
|
19764
|
+
} catch (cleanupError) {
|
|
19765
|
+
void cleanupError;
|
|
19766
|
+
}
|
|
19212
19767
|
}
|
|
19213
19768
|
throw error3;
|
|
19214
19769
|
}
|
|
19215
19770
|
}
|
|
19216
19771
|
return png;
|
|
19217
19772
|
}
|
|
19773
|
+
function isAlreadyExistsError3(error3) {
|
|
19774
|
+
return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
|
|
19775
|
+
}
|
|
19218
19776
|
|
|
19219
19777
|
// src/commands/screenshot.ts
|
|
19220
19778
|
var params11 = S.Object({
|
|
@@ -19277,7 +19835,7 @@ var type = defineCommand({
|
|
|
19277
19835
|
});
|
|
19278
19836
|
|
|
19279
19837
|
// src/commands/uninstall.ts
|
|
19280
|
-
import { randomUUID as
|
|
19838
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
19281
19839
|
var params14 = S.Object({
|
|
19282
19840
|
agent: S.Enum(installableAgents, {
|
|
19283
19841
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19313,7 +19871,7 @@ var uninstall = defineCommand({
|
|
|
19313
19871
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19314
19872
|
continue;
|
|
19315
19873
|
}
|
|
19316
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19874
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID11()}`;
|
|
19317
19875
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19318
19876
|
staged.push({ ...skill, stagingPath });
|
|
19319
19877
|
}
|
|
@@ -19339,7 +19897,7 @@ async function folderExists(fs4, folderPath) {
|
|
|
19339
19897
|
await fs4.stat(folderPath);
|
|
19340
19898
|
return true;
|
|
19341
19899
|
} catch (error3) {
|
|
19342
|
-
if (
|
|
19900
|
+
if (hasOwnErrorCode(error3, "ENOENT")) {
|
|
19343
19901
|
return false;
|
|
19344
19902
|
}
|
|
19345
19903
|
throw error3;
|
|
@@ -19420,6 +19978,7 @@ function createTerminalPilotGroup() {
|
|
|
19420
19978
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19421
19979
|
|
|
19422
19980
|
// src/cli.ts
|
|
19981
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19423
19982
|
function normalizeArgv(argv) {
|
|
19424
19983
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19425
19984
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19443,8 +20002,8 @@ async function isDirectExecution(argv) {
|
|
|
19443
20002
|
try {
|
|
19444
20003
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19445
20004
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19446
|
-
|
|
19447
|
-
|
|
20005
|
+
realpath3(path23.resolve(entryPoint)),
|
|
20006
|
+
realpath3(modulePath)
|
|
19448
20007
|
]);
|
|
19449
20008
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19450
20009
|
} catch {
|