terminal-pilot 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1076 -496
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js.map +1 -1
- package/dist/commands/create-session.js.map +1 -1
- package/dist/commands/fill.js.map +1 -1
- package/dist/commands/get-session.js.map +1 -1
- package/dist/commands/index.js +481 -163
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +448 -130
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +154 -60
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js.map +1 -1
- package/dist/commands/press-key.js.map +1 -1
- package/dist/commands/read-history.js.map +1 -1
- package/dist/commands/read-screen.js.map +1 -1
- package/dist/commands/resize.js.map +1 -1
- package/dist/commands/runtime.js.map +1 -1
- package/dist/commands/screenshot.js.map +1 -1
- package/dist/commands/send-signal.js.map +1 -1
- package/dist/commands/type.js.map +1 -1
- package/dist/commands/uninstall.js +187 -93
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js.map +1 -1
- package/dist/commands/wait-for.js.map +1 -1
- package/dist/testing/cli-repl.js +1072 -492
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +1082 -502
- package/dist/testing/qa-cli.js.map +4 -4
- package/node_modules/@poe-code/agent-skill-config/README.md +103 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.d.ts +25 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.js +159 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +23 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +341 -0
- package/node_modules/@poe-code/agent-skill-config/dist/configs.d.ts +16 -0
- package/node_modules/@poe-code/agent-skill-config/dist/configs.js +70 -0
- package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.d.ts +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.js +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.d.ts +8 -0
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +159 -0
- package/node_modules/@poe-code/agent-skill-config/dist/index.d.ts +11 -0
- package/node_modules/@poe-code/agent-skill-config/dist/index.js +6 -0
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.d.ts +22 -0
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +87 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates/poe-generate.md +47 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates/terminal-pilot.md +45 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates.d.ts +3 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates.js +63 -0
- package/node_modules/@poe-code/agent-skill-config/dist/types.d.ts +16 -0
- package/node_modules/@poe-code/agent-skill-config/dist/types.js +1 -0
- package/node_modules/@poe-code/agent-skill-config/package.json +24 -0
- package/package.json +4 -2
package/dist/testing/cli-repl.js
CHANGED
|
@@ -78,13 +78,13 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// src/cli.ts
|
|
81
|
-
import { realpath as
|
|
82
|
-
import
|
|
81
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
82
|
+
import path23 from "node:path";
|
|
83
83
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
84
84
|
|
|
85
85
|
// ../toolcraft/src/cli.ts
|
|
86
86
|
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
|
|
87
|
-
import
|
|
87
|
+
import path14 from "node:path";
|
|
88
88
|
import {
|
|
89
89
|
Command as CommanderCommand,
|
|
90
90
|
CommanderError as CommanderError2,
|
|
@@ -92,7 +92,7 @@ import {
|
|
|
92
92
|
Option
|
|
93
93
|
} from "commander";
|
|
94
94
|
|
|
95
|
-
// ../design
|
|
95
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
96
96
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
97
97
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
98
98
|
return true;
|
|
@@ -106,7 +106,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
106
106
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// ../design
|
|
109
|
+
// ../toolcraft-design/src/components/color.ts
|
|
110
110
|
var reset = "\x1B[0m";
|
|
111
111
|
var ansiStyles = {
|
|
112
112
|
reset: { open: reset },
|
|
@@ -208,41 +208,135 @@ function createColor(styles = []) {
|
|
|
208
208
|
}
|
|
209
209
|
var color = createColor();
|
|
210
210
|
|
|
211
|
-
// ../design
|
|
212
|
-
var
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
number: (text5) => color.cyanBright(text5),
|
|
217
|
-
intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
|
|
218
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
219
|
-
errorSymbol: color.red("\u25A0"),
|
|
220
|
-
accent: (text5) => color.cyan(text5),
|
|
221
|
-
muted: (text5) => color.dim(text5),
|
|
222
|
-
success: (text5) => color.green(text5),
|
|
223
|
-
warning: (text5) => color.yellow(text5),
|
|
224
|
-
error: (text5) => color.red(text5),
|
|
225
|
-
info: (text5) => color.magenta(text5),
|
|
226
|
-
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
211
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
212
|
+
var brands = {
|
|
213
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
214
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
215
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
227
216
|
};
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
|
|
234
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
235
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
236
|
-
accent: (text5) => color.hex("#006699").bold(text5),
|
|
237
|
-
muted: (text5) => color.hex("#666666")(text5),
|
|
238
|
-
success: (text5) => color.hex("#008800")(text5),
|
|
239
|
-
warning: (text5) => color.hex("#cc6600")(text5),
|
|
240
|
-
error: (text5) => color.hex("#cc0000")(text5),
|
|
241
|
-
info: (text5) => color.hex("#a200ff")(text5),
|
|
242
|
-
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
217
|
+
|
|
218
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
219
|
+
var defaults = {
|
|
220
|
+
brand: "purple",
|
|
221
|
+
label: "Poe"
|
|
243
222
|
};
|
|
223
|
+
var config = { ...defaults };
|
|
224
|
+
var revision = 0;
|
|
225
|
+
var brandConfigured = false;
|
|
226
|
+
function configureTheme(patch) {
|
|
227
|
+
if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
|
|
228
|
+
throw new Error(`Unknown brand: ${patch.brand}`);
|
|
229
|
+
}
|
|
230
|
+
config = {
|
|
231
|
+
brand: patch.brand ?? config.brand,
|
|
232
|
+
label: patch.label ?? config.label
|
|
233
|
+
};
|
|
234
|
+
if (patch.brand !== void 0) {
|
|
235
|
+
brandConfigured = true;
|
|
236
|
+
}
|
|
237
|
+
revision += 1;
|
|
238
|
+
}
|
|
239
|
+
function getThemeConfig() {
|
|
240
|
+
return { ...config };
|
|
241
|
+
}
|
|
242
|
+
function getThemeRevision() {
|
|
243
|
+
return revision;
|
|
244
|
+
}
|
|
245
|
+
function isThemeBrandConfigured() {
|
|
246
|
+
return brandConfigured;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
250
|
+
var brand = brands.purple.primary;
|
|
251
|
+
function withStyles(palette, styles) {
|
|
252
|
+
return Object.defineProperty(palette, "styles", {
|
|
253
|
+
value: styles,
|
|
254
|
+
enumerable: false
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
function brandColor(activeBrand, purple) {
|
|
258
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
259
|
+
}
|
|
260
|
+
function brandBackground(activeBrand, purple) {
|
|
261
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
262
|
+
}
|
|
263
|
+
function createPalette(activeBrand, mode) {
|
|
264
|
+
const isPurple = activeBrand.name === "purple";
|
|
265
|
+
if (mode === "light") {
|
|
266
|
+
const active2 = color.hex(activeBrand.primary);
|
|
267
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
268
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
269
|
+
return withStyles(
|
|
270
|
+
{
|
|
271
|
+
header: (text5) => active2.bold(text5),
|
|
272
|
+
divider: (text5) => color.hex("#666666")(text5),
|
|
273
|
+
prompt: (text5) => prompt2.bold(text5),
|
|
274
|
+
number: (text5) => number2.bold(text5),
|
|
275
|
+
intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
|
|
276
|
+
get resolvedSymbol() {
|
|
277
|
+
return active2("\u25C7");
|
|
278
|
+
},
|
|
279
|
+
get errorSymbol() {
|
|
280
|
+
return color.hex("#cc0000")("\u25A0");
|
|
281
|
+
},
|
|
282
|
+
accent: (text5) => prompt2.bold(text5),
|
|
283
|
+
muted: (text5) => color.hex("#666666")(text5),
|
|
284
|
+
success: (text5) => color.hex("#008800")(text5),
|
|
285
|
+
warning: (text5) => color.hex("#cc6600")(text5),
|
|
286
|
+
error: (text5) => color.hex("#cc0000")(text5),
|
|
287
|
+
info: (text5) => active2(text5),
|
|
288
|
+
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
292
|
+
muted: { fg: "#666666" },
|
|
293
|
+
success: { fg: "#008800" },
|
|
294
|
+
warning: { fg: "#cc6600" },
|
|
295
|
+
error: { fg: "#cc0000" },
|
|
296
|
+
info: { fg: activeBrand.primary }
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
301
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
302
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
303
|
+
const prompt = isPurple ? color.cyan : active;
|
|
304
|
+
const number = isPurple ? color.cyanBright : active;
|
|
305
|
+
return withStyles(
|
|
306
|
+
{
|
|
307
|
+
header: (text5) => activeBright.bold(text5),
|
|
308
|
+
divider: (text5) => color.dim(text5),
|
|
309
|
+
prompt: (text5) => prompt(text5),
|
|
310
|
+
number: (text5) => number(text5),
|
|
311
|
+
intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
|
|
312
|
+
get resolvedSymbol() {
|
|
313
|
+
return active("\u25C7");
|
|
314
|
+
},
|
|
315
|
+
get errorSymbol() {
|
|
316
|
+
return color.red("\u25A0");
|
|
317
|
+
},
|
|
318
|
+
accent: (text5) => prompt(text5),
|
|
319
|
+
muted: (text5) => color.dim(text5),
|
|
320
|
+
success: (text5) => color.green(text5),
|
|
321
|
+
warning: (text5) => color.yellow(text5),
|
|
322
|
+
error: (text5) => color.red(text5),
|
|
323
|
+
info: (text5) => active(text5),
|
|
324
|
+
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
328
|
+
muted: { dim: true },
|
|
329
|
+
success: { fg: "green" },
|
|
330
|
+
warning: { fg: "yellow" },
|
|
331
|
+
error: { fg: "red" },
|
|
332
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
var dark = createPalette(brands.purple, "dark");
|
|
337
|
+
var light = createPalette(brands.purple, "light");
|
|
244
338
|
|
|
245
|
-
// ../design
|
|
339
|
+
// ../toolcraft-design/src/tokens/typography.ts
|
|
246
340
|
var typography = {
|
|
247
341
|
bold: (text5) => color.bold(text5),
|
|
248
342
|
dim: (text5) => color.dim(text5),
|
|
@@ -251,14 +345,14 @@ var typography = {
|
|
|
251
345
|
strikethrough: (text5) => color.strikethrough(text5)
|
|
252
346
|
};
|
|
253
347
|
|
|
254
|
-
// ../design
|
|
348
|
+
// ../toolcraft-design/src/tokens/widths.ts
|
|
255
349
|
var widths = {
|
|
256
350
|
header: 60,
|
|
257
351
|
helpColumn: 24,
|
|
258
352
|
maxLine: 80
|
|
259
353
|
};
|
|
260
354
|
|
|
261
|
-
// ../design
|
|
355
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
262
356
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
263
357
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
264
358
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -279,7 +373,7 @@ function resetOutputFormatCache() {
|
|
|
279
373
|
cached = void 0;
|
|
280
374
|
}
|
|
281
375
|
|
|
282
|
-
// ../design
|
|
376
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
283
377
|
function detectThemeFromEnv(env) {
|
|
284
378
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
285
379
|
if (typeof apple === "string") {
|
|
@@ -316,17 +410,30 @@ function resolveThemeName(env = process.env) {
|
|
|
316
410
|
}
|
|
317
411
|
return "dark";
|
|
318
412
|
}
|
|
319
|
-
var
|
|
413
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
414
|
+
var cachedRevision = -1;
|
|
320
415
|
function getTheme(env) {
|
|
416
|
+
const themeName = resolveThemeName(env);
|
|
417
|
+
const config2 = getThemeConfig();
|
|
418
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
419
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
420
|
+
const revision2 = getThemeRevision();
|
|
421
|
+
if (revision2 !== cachedRevision) {
|
|
422
|
+
themeCache.clear();
|
|
423
|
+
cachedRevision = revision2;
|
|
424
|
+
}
|
|
425
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
426
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
321
427
|
if (cachedTheme) {
|
|
322
428
|
return cachedTheme;
|
|
323
429
|
}
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
430
|
+
const activeBrand = brands[activeBrandName];
|
|
431
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
432
|
+
themeCache.set(cacheKey, theme);
|
|
433
|
+
return theme;
|
|
327
434
|
}
|
|
328
435
|
|
|
329
|
-
// ../design
|
|
436
|
+
// ../toolcraft-design/src/components/text.ts
|
|
330
437
|
function renderMarkdownInline(content) {
|
|
331
438
|
return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
332
439
|
}
|
|
@@ -442,7 +549,7 @@ var text = {
|
|
|
442
549
|
}
|
|
443
550
|
};
|
|
444
551
|
|
|
445
|
-
// ../design
|
|
552
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
446
553
|
var symbols = {
|
|
447
554
|
get info() {
|
|
448
555
|
const format = resolveOutputFormat();
|
|
@@ -496,12 +603,12 @@ var symbols = {
|
|
|
496
603
|
}
|
|
497
604
|
};
|
|
498
605
|
|
|
499
|
-
// ../design
|
|
606
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
500
607
|
function stripAnsi2(value) {
|
|
501
608
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
502
609
|
}
|
|
503
610
|
|
|
504
|
-
// ../design
|
|
611
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
505
612
|
function renderMarkdownInline2(value) {
|
|
506
613
|
return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
507
614
|
}
|
|
@@ -628,7 +735,7 @@ var log = {
|
|
|
628
735
|
error
|
|
629
736
|
};
|
|
630
737
|
|
|
631
|
-
// ../design
|
|
738
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
632
739
|
function createLogger(emitter) {
|
|
633
740
|
const emit = (level, message2) => {
|
|
634
741
|
if (emitter) {
|
|
@@ -689,7 +796,7 @@ function createLogger(emitter) {
|
|
|
689
796
|
}
|
|
690
797
|
var logger = createLogger();
|
|
691
798
|
|
|
692
|
-
// ../design
|
|
799
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
693
800
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
694
801
|
function normalizeInline(value) {
|
|
695
802
|
return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
@@ -865,7 +972,7 @@ function formatOptionList(options) {
|
|
|
865
972
|
});
|
|
866
973
|
}
|
|
867
974
|
|
|
868
|
-
// ../design
|
|
975
|
+
// ../toolcraft-design/src/components/help-formatter-plain.ts
|
|
869
976
|
var help_formatter_plain_exports = {};
|
|
870
977
|
__export(help_formatter_plain_exports, {
|
|
871
978
|
formatColumns: () => formatColumns2,
|
|
@@ -1002,7 +1109,7 @@ function formatOptionList2(options) {
|
|
|
1002
1109
|
});
|
|
1003
1110
|
}
|
|
1004
1111
|
|
|
1005
|
-
// ../design
|
|
1112
|
+
// ../toolcraft-design/src/components/table.ts
|
|
1006
1113
|
var reset2 = "\x1B[0m";
|
|
1007
1114
|
var ellipsis = "\u2026";
|
|
1008
1115
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -1286,7 +1393,7 @@ function renderTable(options) {
|
|
|
1286
1393
|
}
|
|
1287
1394
|
}
|
|
1288
1395
|
|
|
1289
|
-
// ../design
|
|
1396
|
+
// ../toolcraft-design/src/components/detail-card.ts
|
|
1290
1397
|
function wrap(value, width) {
|
|
1291
1398
|
const lines = [];
|
|
1292
1399
|
for (const paragraph of value.split("\n")) {
|
|
@@ -1349,7 +1456,8 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1349
1456
|
return blocks.join("\n\n");
|
|
1350
1457
|
}
|
|
1351
1458
|
|
|
1352
|
-
// ../design
|
|
1459
|
+
// ../toolcraft-design/src/components/template.ts
|
|
1460
|
+
var MAX_PARTIAL_DEPTH = 100;
|
|
1353
1461
|
var HTML_ESCAPE = {
|
|
1354
1462
|
"&": "&",
|
|
1355
1463
|
"<": "<",
|
|
@@ -1361,14 +1469,27 @@ var HTML_ESCAPE = {
|
|
|
1361
1469
|
"=": "="
|
|
1362
1470
|
};
|
|
1363
1471
|
function renderTemplate(template, view, options = {}) {
|
|
1364
|
-
const prepared = options.yield === void 0 ? template : template.split("{{yield}}").join(options.yield);
|
|
1472
|
+
const prepared = options.yield === void 0 ? template : resolveTemplatePartials(template, options.partials ?? {}).split("{{yield}}").join(options.yield);
|
|
1365
1473
|
const tokens = parseTemplate(prepared);
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1474
|
+
validatePartialReferences(tokens, options.partials ?? {}, []);
|
|
1475
|
+
if (options.validate === true) {
|
|
1476
|
+
const expanded = resolveTemplatePartials(prepared, options.partials ?? {});
|
|
1477
|
+
validateVariables(parseTemplate(expanded), { view });
|
|
1478
|
+
}
|
|
1479
|
+
const state = {
|
|
1480
|
+
escape: options.escape === "none" ? String : escapeHtml,
|
|
1481
|
+
partials: options.partials ?? {},
|
|
1482
|
+
partialStack: [],
|
|
1483
|
+
preserveMissing: options.yield !== void 0 && options.escape === "none",
|
|
1484
|
+
validate: options.validate === true
|
|
1485
|
+
};
|
|
1486
|
+
return renderTokens(tokens, { view }, prepared, state);
|
|
1487
|
+
}
|
|
1488
|
+
function resolveTemplatePartials(template, partials) {
|
|
1489
|
+
return expandTemplatePartials(template, partials, []);
|
|
1369
1490
|
}
|
|
1370
|
-
function renderTemplateInContext(template, context,
|
|
1371
|
-
return renderTokens(parseTemplate(template), context, template,
|
|
1491
|
+
function renderTemplateInContext(template, context, state) {
|
|
1492
|
+
return renderTokens(parseTemplate(template), context, template, state);
|
|
1372
1493
|
}
|
|
1373
1494
|
function parseTemplate(template) {
|
|
1374
1495
|
const root = [];
|
|
@@ -1391,9 +1512,6 @@ function parseTemplate(template) {
|
|
|
1391
1512
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1392
1513
|
continue;
|
|
1393
1514
|
}
|
|
1394
|
-
if (parsed.kind === "partial") {
|
|
1395
|
-
throw new Error(`Partials are not supported: "${parsed.name}"`);
|
|
1396
|
-
}
|
|
1397
1515
|
if (parsed.kind === "delimiter") {
|
|
1398
1516
|
throw new Error("Custom delimiters are not supported");
|
|
1399
1517
|
}
|
|
@@ -1411,6 +1529,15 @@ function parseTemplate(template) {
|
|
|
1411
1529
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1412
1530
|
continue;
|
|
1413
1531
|
}
|
|
1532
|
+
if (parsed.kind === "partial") {
|
|
1533
|
+
tokens.push({
|
|
1534
|
+
type: "partial",
|
|
1535
|
+
name: parsed.name,
|
|
1536
|
+
indent: standalone === void 0 ? "" : template.slice(standalone.lineStart, open)
|
|
1537
|
+
});
|
|
1538
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1414
1541
|
if (parsed.kind === "close") {
|
|
1415
1542
|
const frame2 = stack.pop();
|
|
1416
1543
|
if (frame2 === void 0) {
|
|
@@ -1481,7 +1608,7 @@ function getStandalone(template, tagStart, tagEnd, kind) {
|
|
|
1481
1608
|
}
|
|
1482
1609
|
return void 0;
|
|
1483
1610
|
}
|
|
1484
|
-
function renderTokens(tokens, context, template,
|
|
1611
|
+
function renderTokens(tokens, context, template, state) {
|
|
1485
1612
|
let output = "";
|
|
1486
1613
|
for (const token of tokens) {
|
|
1487
1614
|
switch (token.type) {
|
|
@@ -1490,32 +1617,62 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1490
1617
|
continue;
|
|
1491
1618
|
case "name":
|
|
1492
1619
|
case "unescaped": {
|
|
1493
|
-
const
|
|
1494
|
-
if (value == null) {
|
|
1495
|
-
if (
|
|
1620
|
+
const result = lookup(context, token.name);
|
|
1621
|
+
if (!result.hit || result.value == null) {
|
|
1622
|
+
if (state.validate) {
|
|
1623
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1624
|
+
}
|
|
1625
|
+
if (state.preserveMissing) {
|
|
1496
1626
|
output += token.raw;
|
|
1497
1627
|
}
|
|
1498
1628
|
continue;
|
|
1499
1629
|
}
|
|
1500
|
-
const rendered = String(value);
|
|
1501
|
-
output += token.type === "name" ? escape(rendered) : rendered;
|
|
1630
|
+
const rendered = String(result.value);
|
|
1631
|
+
output += token.type === "name" ? state.escape(rendered) : rendered;
|
|
1632
|
+
continue;
|
|
1633
|
+
}
|
|
1634
|
+
case "partial": {
|
|
1635
|
+
if (!Object.hasOwn(state.partials, token.name)) {
|
|
1636
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1637
|
+
}
|
|
1638
|
+
if (state.partialStack.includes(token.name)) {
|
|
1639
|
+
throw new Error(
|
|
1640
|
+
`Circular partial reference detected: ${[...state.partialStack, token.name].join(" -> ")}.`
|
|
1641
|
+
);
|
|
1642
|
+
}
|
|
1643
|
+
if (state.partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1644
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1645
|
+
}
|
|
1646
|
+
const partial = indentPartial(state.partials[token.name], token.indent);
|
|
1647
|
+
output += renderTokens(parseTemplate(partial), context, partial, {
|
|
1648
|
+
...state,
|
|
1649
|
+
partialStack: [...state.partialStack, token.name]
|
|
1650
|
+
});
|
|
1502
1651
|
continue;
|
|
1503
1652
|
}
|
|
1504
1653
|
case "inverted": {
|
|
1505
|
-
const
|
|
1654
|
+
const result = lookup(context, token.name);
|
|
1655
|
+
if (!result.hit && state.validate) {
|
|
1656
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1657
|
+
}
|
|
1658
|
+
const value = result.value;
|
|
1506
1659
|
if (!value || Array.isArray(value) && value.length === 0) {
|
|
1507
|
-
output += renderTokens(token.children, context, template,
|
|
1660
|
+
output += renderTokens(token.children, context, template, state);
|
|
1508
1661
|
}
|
|
1509
1662
|
continue;
|
|
1510
1663
|
}
|
|
1511
1664
|
case "section": {
|
|
1512
|
-
const
|
|
1665
|
+
const result = lookup(context, token.name);
|
|
1666
|
+
if (!result.hit && state.validate) {
|
|
1667
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1668
|
+
}
|
|
1669
|
+
const value = result.value;
|
|
1513
1670
|
if (!value) {
|
|
1514
1671
|
continue;
|
|
1515
1672
|
}
|
|
1516
1673
|
if (Array.isArray(value)) {
|
|
1517
1674
|
for (const item of value) {
|
|
1518
|
-
output += renderTokens(token.children, pushContext(context, item), template,
|
|
1675
|
+
output += renderTokens(token.children, pushContext(context, item), template, state);
|
|
1519
1676
|
}
|
|
1520
1677
|
continue;
|
|
1521
1678
|
}
|
|
@@ -1524,7 +1681,7 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1524
1681
|
const rendered = value.call(
|
|
1525
1682
|
context.view,
|
|
1526
1683
|
raw,
|
|
1527
|
-
(nextTemplate) => renderTemplateInContext(nextTemplate, context,
|
|
1684
|
+
(nextTemplate) => renderTemplateInContext(nextTemplate, context, state)
|
|
1528
1685
|
);
|
|
1529
1686
|
if (rendered != null) {
|
|
1530
1687
|
output += String(rendered);
|
|
@@ -1532,10 +1689,10 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1532
1689
|
continue;
|
|
1533
1690
|
}
|
|
1534
1691
|
if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
1535
|
-
output += renderTokens(token.children, pushContext(context, value), template,
|
|
1692
|
+
output += renderTokens(token.children, pushContext(context, value), template, state);
|
|
1536
1693
|
continue;
|
|
1537
1694
|
}
|
|
1538
|
-
output += renderTokens(token.children, context, template,
|
|
1695
|
+
output += renderTokens(token.children, context, template, state);
|
|
1539
1696
|
}
|
|
1540
1697
|
}
|
|
1541
1698
|
}
|
|
@@ -1543,17 +1700,115 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1543
1700
|
}
|
|
1544
1701
|
function lookup(context, name) {
|
|
1545
1702
|
if (name === ".") {
|
|
1546
|
-
return callLambda(context.view, context.view);
|
|
1703
|
+
return { hit: true, value: callLambda(context.view, context.view) };
|
|
1547
1704
|
}
|
|
1548
1705
|
let cursor = context;
|
|
1549
1706
|
while (cursor !== void 0) {
|
|
1550
1707
|
const result = name.includes(".") ? lookupDotted(cursor.view, name) : lookupName(cursor.view, name);
|
|
1551
1708
|
if (result.hit) {
|
|
1552
|
-
return callLambda(result.value, cursor.view);
|
|
1709
|
+
return { hit: true, value: callLambda(result.value, cursor.view) };
|
|
1553
1710
|
}
|
|
1554
1711
|
cursor = cursor.parent;
|
|
1555
1712
|
}
|
|
1556
|
-
return void 0;
|
|
1713
|
+
return { hit: false, value: void 0 };
|
|
1714
|
+
}
|
|
1715
|
+
function validateVariables(tokens, context) {
|
|
1716
|
+
for (const token of tokens) {
|
|
1717
|
+
if (token.type === "text" || token.type === "partial") {
|
|
1718
|
+
continue;
|
|
1719
|
+
}
|
|
1720
|
+
if (token.type === "name" || token.type === "unescaped") {
|
|
1721
|
+
if (!lookup(context, token.name).hit) {
|
|
1722
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1723
|
+
}
|
|
1724
|
+
continue;
|
|
1725
|
+
}
|
|
1726
|
+
if (token.type !== "section" && token.type !== "inverted") {
|
|
1727
|
+
continue;
|
|
1728
|
+
}
|
|
1729
|
+
const result = lookup(context, token.name);
|
|
1730
|
+
if (!result.hit) {
|
|
1731
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1732
|
+
}
|
|
1733
|
+
if (Array.isArray(result.value) && result.value.length > 0) {
|
|
1734
|
+
for (const item of result.value) {
|
|
1735
|
+
validateVariables(token.children, pushContext(context, item));
|
|
1736
|
+
}
|
|
1737
|
+
continue;
|
|
1738
|
+
}
|
|
1739
|
+
if (typeof result.value === "object" && result.value !== null || typeof result.value === "string" || typeof result.value === "number") {
|
|
1740
|
+
validateVariables(token.children, pushContext(context, result.value));
|
|
1741
|
+
continue;
|
|
1742
|
+
}
|
|
1743
|
+
validateVariables(token.children, context);
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
function validatePartialReferences(tokens, partials, partialStack) {
|
|
1747
|
+
for (const token of tokens) {
|
|
1748
|
+
if (token.type === "section" || token.type === "inverted") {
|
|
1749
|
+
validatePartialReferences(token.children, partials, partialStack);
|
|
1750
|
+
continue;
|
|
1751
|
+
}
|
|
1752
|
+
if (token.type !== "partial") {
|
|
1753
|
+
continue;
|
|
1754
|
+
}
|
|
1755
|
+
if (!Object.hasOwn(partials, token.name)) {
|
|
1756
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1757
|
+
}
|
|
1758
|
+
if (partialStack.includes(token.name)) {
|
|
1759
|
+
throw new Error(
|
|
1760
|
+
`Circular partial reference detected: ${[...partialStack, token.name].join(" -> ")}.`
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1763
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1764
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1765
|
+
}
|
|
1766
|
+
validatePartialReferences(parseTemplate(partials[token.name]), partials, [
|
|
1767
|
+
...partialStack,
|
|
1768
|
+
token.name
|
|
1769
|
+
]);
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
function indentPartial(partial, indent) {
|
|
1773
|
+
if (indent === "") {
|
|
1774
|
+
return partial;
|
|
1775
|
+
}
|
|
1776
|
+
return partial.split("\n").map((line) => line === "" ? "" : `${indent}${line}`).join("\n");
|
|
1777
|
+
}
|
|
1778
|
+
function expandTemplatePartials(template, partials, partialStack) {
|
|
1779
|
+
let output = "";
|
|
1780
|
+
let index = 0;
|
|
1781
|
+
while (index < template.length) {
|
|
1782
|
+
const open = template.indexOf("{{", index);
|
|
1783
|
+
if (open === -1) {
|
|
1784
|
+
output += template.slice(index);
|
|
1785
|
+
break;
|
|
1786
|
+
}
|
|
1787
|
+
const parsed = parseTag(template, open);
|
|
1788
|
+
if (parsed.kind !== "partial") {
|
|
1789
|
+
output += template.slice(index, parsed.end);
|
|
1790
|
+
index = parsed.end;
|
|
1791
|
+
continue;
|
|
1792
|
+
}
|
|
1793
|
+
if (!Object.hasOwn(partials, parsed.name)) {
|
|
1794
|
+
throw new Error(`Partial "${parsed.name}" not found.`);
|
|
1795
|
+
}
|
|
1796
|
+
if (partialStack.includes(parsed.name)) {
|
|
1797
|
+
throw new Error(
|
|
1798
|
+
`Circular partial reference detected: ${[...partialStack, parsed.name].join(" -> ")}.`
|
|
1799
|
+
);
|
|
1800
|
+
}
|
|
1801
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1802
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1803
|
+
}
|
|
1804
|
+
const standalone = getStandalone(template, open, parsed.end, parsed.kind);
|
|
1805
|
+
const beforePartial = standalone === void 0 ? template.slice(index, open) : template.slice(index, standalone.lineStart);
|
|
1806
|
+
const indent = standalone === void 0 ? "" : template.slice(standalone.lineStart, open);
|
|
1807
|
+
const partial = indentPartial(partials[parsed.name], indent);
|
|
1808
|
+
output += beforePartial + expandTemplatePartials(partial, partials, [...partialStack, parsed.name]);
|
|
1809
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1810
|
+
}
|
|
1811
|
+
return output;
|
|
1557
1812
|
}
|
|
1558
1813
|
function lookupName(view, name) {
|
|
1559
1814
|
if (!isPropertyContainer(view) || !hasProperty(view, name)) {
|
|
@@ -1613,22 +1868,22 @@ function hasProperty(value, key2) {
|
|
|
1613
1868
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1614
1869
|
}
|
|
1615
1870
|
|
|
1616
|
-
// ../design
|
|
1871
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1617
1872
|
import { spawn } from "node:child_process";
|
|
1618
1873
|
import process2 from "node:process";
|
|
1619
1874
|
|
|
1620
|
-
// ../design
|
|
1875
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1621
1876
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1622
1877
|
var storage = new AsyncLocalStorage2();
|
|
1623
1878
|
|
|
1624
|
-
// ../design
|
|
1879
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1625
1880
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1626
1881
|
|
|
1627
|
-
// ../design
|
|
1882
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1628
1883
|
import readline from "node:readline";
|
|
1629
1884
|
import { PassThrough } from "node:stream";
|
|
1630
1885
|
|
|
1631
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1632
1887
|
var REGION_HEADER = 1 << 0;
|
|
1633
1888
|
var REGION_LIST = 1 << 1;
|
|
1634
1889
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1637,10 +1892,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1637
1892
|
var REGION_TOAST = 1 << 5;
|
|
1638
1893
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1639
1894
|
|
|
1640
|
-
// ../design
|
|
1895
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1641
1896
|
import * as clack from "@clack/prompts";
|
|
1642
1897
|
|
|
1643
|
-
// ../design
|
|
1898
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1644
1899
|
import { isCancel } from "@clack/prompts";
|
|
1645
1900
|
function cancel(msg = "") {
|
|
1646
1901
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1651,7 +1906,7 @@ function cancel(msg = "") {
|
|
|
1651
1906
|
`);
|
|
1652
1907
|
}
|
|
1653
1908
|
|
|
1654
|
-
// ../design
|
|
1909
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1655
1910
|
function getVisibleWidth(value) {
|
|
1656
1911
|
return stripAnsi2(value).length;
|
|
1657
1912
|
}
|
|
@@ -1700,10 +1955,10 @@ function note(message2, title) {
|
|
|
1700
1955
|
`);
|
|
1701
1956
|
}
|
|
1702
1957
|
|
|
1703
|
-
// ../design
|
|
1958
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1704
1959
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1705
1960
|
|
|
1706
|
-
// ../design
|
|
1961
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1707
1962
|
async function select2(opts) {
|
|
1708
1963
|
return clack.select(opts);
|
|
1709
1964
|
}
|
|
@@ -1746,19 +2001,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1746
2001
|
};
|
|
1747
2002
|
|
|
1748
2003
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1749
|
-
function validateHumanInLoopOnDefine(
|
|
1750
|
-
const label = Array.isArray(
|
|
1751
|
-
if (
|
|
1752
|
-
throw new Error(`${label} '${
|
|
2004
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
2005
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
2006
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
2007
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
1753
2008
|
}
|
|
1754
|
-
if (
|
|
2009
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1755
2010
|
return;
|
|
1756
2011
|
}
|
|
1757
|
-
if (
|
|
1758
|
-
throw new Error(`${label} '${
|
|
2012
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
2013
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
1759
2014
|
}
|
|
1760
|
-
if (typeof
|
|
1761
|
-
throw new Error(`${label} '${
|
|
2015
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
2016
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1762
2017
|
}
|
|
1763
2018
|
}
|
|
1764
2019
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1834,12 +2089,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1834
2089
|
}
|
|
1835
2090
|
}
|
|
1836
2091
|
}
|
|
1837
|
-
function OneOf(
|
|
1838
|
-
assertValidBranches(
|
|
2092
|
+
function OneOf(config2) {
|
|
2093
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1839
2094
|
return {
|
|
1840
2095
|
kind: "oneOf",
|
|
1841
|
-
discriminator:
|
|
1842
|
-
branches:
|
|
2096
|
+
discriminator: config2.discriminator,
|
|
2097
|
+
branches: config2.branches
|
|
1843
2098
|
};
|
|
1844
2099
|
}
|
|
1845
2100
|
|
|
@@ -2089,22 +2344,22 @@ function cloneStringArray(values) {
|
|
|
2089
2344
|
function cloneStringRecord(values) {
|
|
2090
2345
|
return values === void 0 ? void 0 : { ...values };
|
|
2091
2346
|
}
|
|
2092
|
-
function cloneMcpServerConfig(
|
|
2093
|
-
if (
|
|
2347
|
+
function cloneMcpServerConfig(config2) {
|
|
2348
|
+
if (config2 === void 0) {
|
|
2094
2349
|
return void 0;
|
|
2095
2350
|
}
|
|
2096
|
-
if (
|
|
2351
|
+
if (config2.transport === "stdio") {
|
|
2097
2352
|
return {
|
|
2098
2353
|
transport: "stdio",
|
|
2099
|
-
command:
|
|
2100
|
-
args: cloneStringArray(
|
|
2101
|
-
env: cloneStringRecord(
|
|
2354
|
+
command: config2.command,
|
|
2355
|
+
args: cloneStringArray(config2.args),
|
|
2356
|
+
env: cloneStringRecord(config2.env)
|
|
2102
2357
|
};
|
|
2103
2358
|
}
|
|
2104
2359
|
return {
|
|
2105
2360
|
transport: "http",
|
|
2106
|
-
url:
|
|
2107
|
-
headers: cloneStringRecord(
|
|
2361
|
+
url: config2.url,
|
|
2362
|
+
headers: cloneStringRecord(config2.headers)
|
|
2108
2363
|
};
|
|
2109
2364
|
}
|
|
2110
2365
|
function cloneRenameMap(rename5) {
|
|
@@ -2345,57 +2600,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2345
2600
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2346
2601
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2347
2602
|
}
|
|
2348
|
-
function createBaseCommand(
|
|
2603
|
+
function createBaseCommand(config2) {
|
|
2349
2604
|
const command = {
|
|
2350
2605
|
kind: "command",
|
|
2351
|
-
name:
|
|
2352
|
-
description:
|
|
2353
|
-
aliases: [...
|
|
2354
|
-
positional: [...
|
|
2355
|
-
params:
|
|
2356
|
-
secrets: cloneSecrets(
|
|
2357
|
-
scope: resolveCommandScope(
|
|
2358
|
-
confirm:
|
|
2359
|
-
humanInLoop:
|
|
2360
|
-
requires: cloneRequires(
|
|
2361
|
-
handler:
|
|
2362
|
-
render:
|
|
2606
|
+
name: config2.name,
|
|
2607
|
+
description: config2.description,
|
|
2608
|
+
aliases: [...config2.aliases ?? []],
|
|
2609
|
+
positional: [...config2.positional ?? []],
|
|
2610
|
+
params: config2.params,
|
|
2611
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2612
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
2613
|
+
confirm: config2.confirm ?? false,
|
|
2614
|
+
humanInLoop: config2.humanInLoop,
|
|
2615
|
+
requires: cloneRequires(config2.requires),
|
|
2616
|
+
handler: config2.handler,
|
|
2617
|
+
render: config2.render
|
|
2363
2618
|
};
|
|
2364
2619
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2365
2620
|
value: {
|
|
2366
|
-
scope: cloneScope(
|
|
2367
|
-
humanInLoop:
|
|
2368
|
-
secrets: cloneSecrets(
|
|
2369
|
-
requires: cloneRequires(
|
|
2621
|
+
scope: cloneScope(config2.scope),
|
|
2622
|
+
humanInLoop: config2.humanInLoop,
|
|
2623
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2624
|
+
requires: cloneRequires(config2.requires),
|
|
2370
2625
|
sourcePath: inferCommandSourcePath()
|
|
2371
2626
|
}
|
|
2372
2627
|
});
|
|
2373
2628
|
return command;
|
|
2374
2629
|
}
|
|
2375
|
-
function createBaseGroup(
|
|
2630
|
+
function createBaseGroup(config2) {
|
|
2376
2631
|
const group = {
|
|
2377
2632
|
kind: "group",
|
|
2378
|
-
name:
|
|
2379
|
-
description:
|
|
2380
|
-
aliases: [...
|
|
2381
|
-
scope: resolveGroupScope(
|
|
2382
|
-
humanInLoop:
|
|
2383
|
-
secrets: cloneSecrets(
|
|
2384
|
-
requires: cloneRequires(
|
|
2633
|
+
name: config2.name,
|
|
2634
|
+
description: config2.description,
|
|
2635
|
+
aliases: [...config2.aliases ?? []],
|
|
2636
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
2637
|
+
humanInLoop: config2.humanInLoop,
|
|
2638
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2639
|
+
requires: cloneRequires(config2.requires),
|
|
2385
2640
|
children: [],
|
|
2386
2641
|
default: void 0
|
|
2387
2642
|
};
|
|
2388
2643
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2389
2644
|
value: {
|
|
2390
|
-
mcp: cloneMcpServerConfig(
|
|
2391
|
-
scope: cloneScope(
|
|
2392
|
-
humanInLoop:
|
|
2393
|
-
secrets: cloneSecrets(
|
|
2394
|
-
tools: cloneStringArray(
|
|
2395
|
-
rename: cloneRenameMap(
|
|
2396
|
-
requires: cloneRequires(
|
|
2397
|
-
children: [...
|
|
2398
|
-
default:
|
|
2645
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
2646
|
+
scope: cloneScope(config2.scope),
|
|
2647
|
+
humanInLoop: config2.humanInLoop,
|
|
2648
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2649
|
+
tools: cloneStringArray(config2.tools),
|
|
2650
|
+
rename: cloneRenameMap(config2.rename),
|
|
2651
|
+
requires: cloneRequires(config2.requires),
|
|
2652
|
+
children: [...config2.children],
|
|
2653
|
+
default: config2.default
|
|
2399
2654
|
}
|
|
2400
2655
|
});
|
|
2401
2656
|
return group;
|
|
@@ -2498,10 +2753,10 @@ function materializeNode(node, inherited) {
|
|
|
2498
2753
|
}
|
|
2499
2754
|
return materializeGroup(node, inherited);
|
|
2500
2755
|
}
|
|
2501
|
-
function defineCommand(
|
|
2502
|
-
validateHumanInLoopOnDefine(
|
|
2756
|
+
function defineCommand(config2) {
|
|
2757
|
+
validateHumanInLoopOnDefine(config2);
|
|
2503
2758
|
return materializeCommand(
|
|
2504
|
-
createBaseCommand(
|
|
2759
|
+
createBaseCommand(config2),
|
|
2505
2760
|
{
|
|
2506
2761
|
scope: void 0,
|
|
2507
2762
|
humanInLoop: void 0,
|
|
@@ -2510,10 +2765,10 @@ function defineCommand(config) {
|
|
|
2510
2765
|
}
|
|
2511
2766
|
);
|
|
2512
2767
|
}
|
|
2513
|
-
function defineGroup(
|
|
2514
|
-
validateRenameMap(
|
|
2515
|
-
validateHumanInLoopOnDefine(
|
|
2516
|
-
return materializeGroup(createBaseGroup(
|
|
2768
|
+
function defineGroup(config2) {
|
|
2769
|
+
validateRenameMap(config2.rename);
|
|
2770
|
+
validateHumanInLoopOnDefine(config2);
|
|
2771
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2517
2772
|
scope: void 0,
|
|
2518
2773
|
humanInLoop: void 0,
|
|
2519
2774
|
secrets: {},
|
|
@@ -2674,17 +2929,22 @@ import { randomBytes } from "node:crypto";
|
|
|
2674
2929
|
// ../process-runner/src/docker/args.ts
|
|
2675
2930
|
import path2 from "node:path";
|
|
2676
2931
|
|
|
2932
|
+
// ../process-runner/src/docker/env-file.ts
|
|
2933
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2934
|
+
import { tmpdir } from "node:os";
|
|
2935
|
+
import path3 from "node:path";
|
|
2936
|
+
|
|
2677
2937
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2678
2938
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2679
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
2680
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2681
|
-
import { tmpdir } from "node:os";
|
|
2682
|
-
import
|
|
2939
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2940
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2941
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
2942
|
+
import path5 from "node:path";
|
|
2683
2943
|
|
|
2684
2944
|
// ../process-runner/src/host/host-runner.ts
|
|
2685
2945
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
2686
2946
|
function createHostRunner(options = {}) {
|
|
2687
|
-
const
|
|
2947
|
+
const detachedByDefault = options.detached === true;
|
|
2688
2948
|
return {
|
|
2689
2949
|
name: "host",
|
|
2690
2950
|
exec(spec) {
|
|
@@ -2702,18 +2962,19 @@ function createHostRunner(options = {}) {
|
|
|
2702
2962
|
const stdinMode = spec.stdin ?? "ignore";
|
|
2703
2963
|
const stdoutMode = spec.stdout ?? "pipe";
|
|
2704
2964
|
const stderrMode = spec.stderr ?? "pipe";
|
|
2965
|
+
const killProcessGroup = detachedByDefault || spec.killProcessGroup === true;
|
|
2705
2966
|
const stdio = stdinMode === "inherit" && stdoutMode === "inherit" && stderrMode === "inherit" ? "inherit" : [stdinMode, stdoutMode, stderrMode];
|
|
2706
2967
|
const child = spawnChildProcess(spec.command, spec.args ?? [], {
|
|
2707
2968
|
cwd: spec.cwd,
|
|
2708
2969
|
env: spec.env,
|
|
2709
2970
|
stdio,
|
|
2710
|
-
...
|
|
2971
|
+
...killProcessGroup ? { detached: true } : {}
|
|
2711
2972
|
});
|
|
2712
|
-
if (
|
|
2973
|
+
if (killProcessGroup) {
|
|
2713
2974
|
child.unref();
|
|
2714
2975
|
}
|
|
2715
2976
|
const kill = (signal) => {
|
|
2716
|
-
if (
|
|
2977
|
+
if (killProcessGroup && process.platform !== "win32" && child.pid !== void 0) {
|
|
2717
2978
|
process.kill(-child.pid, signal);
|
|
2718
2979
|
return;
|
|
2719
2980
|
}
|
|
@@ -2771,9 +3032,9 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
2771
3032
|
}
|
|
2772
3033
|
|
|
2773
3034
|
// ../process-runner/src/workspace-transfer.ts
|
|
2774
|
-
import { createHash } from "node:crypto";
|
|
3035
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2775
3036
|
import { promises as nodeFs } from "node:fs";
|
|
2776
|
-
import
|
|
3037
|
+
import path4 from "node:path";
|
|
2777
3038
|
|
|
2778
3039
|
// ../process-runner/src/testing/mock-runner.ts
|
|
2779
3040
|
import { Readable, Writable } from "node:stream";
|
|
@@ -2844,7 +3105,7 @@ function resolveEndpoint(options = {}) {
|
|
|
2844
3105
|
}
|
|
2845
3106
|
|
|
2846
3107
|
// ../task-list/src/backends/utils.ts
|
|
2847
|
-
import
|
|
3108
|
+
import path6 from "node:path";
|
|
2848
3109
|
function compareCreated(left, right) {
|
|
2849
3110
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
2850
3111
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -2894,12 +3155,12 @@ async function statIfExists(fs4, filePath) {
|
|
|
2894
3155
|
}
|
|
2895
3156
|
}
|
|
2896
3157
|
async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
2897
|
-
const resolvedPath =
|
|
2898
|
-
const rootPath =
|
|
2899
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
3158
|
+
const resolvedPath = path6.resolve(filePath);
|
|
3159
|
+
const rootPath = path6.parse(resolvedPath).root;
|
|
3160
|
+
const components = resolvedPath.slice(rootPath.length).split(path6.sep).filter(Boolean);
|
|
2900
3161
|
let currentPath = rootPath;
|
|
2901
3162
|
for (const component of components) {
|
|
2902
|
-
currentPath =
|
|
3163
|
+
currentPath = path6.join(currentPath, component);
|
|
2903
3164
|
try {
|
|
2904
3165
|
if ((await fs4.lstat(currentPath)).isSymbolicLink()) {
|
|
2905
3166
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
@@ -2915,7 +3176,7 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
2915
3176
|
async function writeAtomically(fs4, filePath, content) {
|
|
2916
3177
|
const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
|
|
2917
3178
|
tmpFileCounter += 1;
|
|
2918
|
-
await fs4.mkdir(
|
|
3179
|
+
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
2919
3180
|
try {
|
|
2920
3181
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
2921
3182
|
await fs4.rename(tempPath, filePath);
|
|
@@ -2931,7 +3192,7 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
2931
3192
|
}
|
|
2932
3193
|
}
|
|
2933
3194
|
async function withFileLock(fs4, lockPath, operation) {
|
|
2934
|
-
await fs4.mkdir(
|
|
3195
|
+
await fs4.mkdir(path6.dirname(lockPath), { recursive: true });
|
|
2935
3196
|
for (; ; ) {
|
|
2936
3197
|
try {
|
|
2937
3198
|
await fs4.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
@@ -4018,7 +4279,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
4018
4279
|
}
|
|
4019
4280
|
|
|
4020
4281
|
// ../task-list/src/backends/markdown-dir.ts
|
|
4021
|
-
import
|
|
4282
|
+
import path7 from "node:path";
|
|
4022
4283
|
import { parseDocument, stringify } from "yaml";
|
|
4023
4284
|
|
|
4024
4285
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -4137,16 +4398,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
4137
4398
|
};
|
|
4138
4399
|
}
|
|
4139
4400
|
function listPath(rootPath, layout, list) {
|
|
4140
|
-
return layout.kind === "single" ? rootPath :
|
|
4401
|
+
return layout.kind === "single" ? rootPath : path7.join(rootPath, list);
|
|
4141
4402
|
}
|
|
4142
4403
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
4143
|
-
return layout.kind === "single" ?
|
|
4404
|
+
return layout.kind === "single" ? path7.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path7.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
4144
4405
|
}
|
|
4145
4406
|
function activeTaskFilename(id, order, width) {
|
|
4146
4407
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
4147
4408
|
}
|
|
4148
4409
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
4149
|
-
return
|
|
4410
|
+
return path7.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
4150
4411
|
}
|
|
4151
4412
|
function isMarkdownFile(entryName) {
|
|
4152
4413
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -4272,7 +4533,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
4272
4533
|
state: frontmatter.state,
|
|
4273
4534
|
description: body,
|
|
4274
4535
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
4275
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
4536
|
+
...sourcePath !== void 0 && { sourcePath: path7.resolve(sourcePath) }
|
|
4276
4537
|
};
|
|
4277
4538
|
}
|
|
4278
4539
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -4312,7 +4573,7 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
4312
4573
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
4313
4574
|
};
|
|
4314
4575
|
}
|
|
4315
|
-
const parsedFilename = parseActiveFilename(
|
|
4576
|
+
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
4316
4577
|
const defaultName = parsedFilename?.id ?? id;
|
|
4317
4578
|
const effectiveFrontmatter = {
|
|
4318
4579
|
...frontmatter,
|
|
@@ -4341,7 +4602,7 @@ async function findTaskLocation(fs4, rootPath, layout, list, id) {
|
|
|
4341
4602
|
await rejectSymbolicLinkComponents(fs4, listDirectoryPath);
|
|
4342
4603
|
const activeName = await findActiveTaskFilename(fs4, listDirectoryPath, id);
|
|
4343
4604
|
if (activeName) {
|
|
4344
|
-
const activePath =
|
|
4605
|
+
const activePath = path7.join(listDirectoryPath, activeName);
|
|
4345
4606
|
await rejectSymbolicLinkComponents(fs4, activePath);
|
|
4346
4607
|
const activeStat = await statIfExists(fs4, activePath);
|
|
4347
4608
|
if (activeStat?.isFile()) {
|
|
@@ -4364,7 +4625,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4364
4625
|
}
|
|
4365
4626
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4366
4627
|
}
|
|
4367
|
-
function createdFrontmatter(
|
|
4628
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4368
4629
|
const frontmatter = mode !== "passthrough" ? {
|
|
4369
4630
|
$schema: TASK_SCHEMA_ID,
|
|
4370
4631
|
kind: TASK_KIND,
|
|
@@ -4376,7 +4637,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4376
4637
|
state: initialState
|
|
4377
4638
|
};
|
|
4378
4639
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4379
|
-
for (const [key2, value] of Object.entries(
|
|
4640
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4380
4641
|
if (!reservedKeys.has(key2)) {
|
|
4381
4642
|
setOwnValue(frontmatter, key2, value);
|
|
4382
4643
|
}
|
|
@@ -4463,7 +4724,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4463
4724
|
if (isHiddenEntry(entryName)) continue;
|
|
4464
4725
|
const parsed = parseActiveFilename(entryName);
|
|
4465
4726
|
if (!parsed) continue;
|
|
4466
|
-
const entryPath =
|
|
4727
|
+
const entryPath = path7.join(listDirectoryPath, entryName);
|
|
4467
4728
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4468
4729
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4469
4730
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4481,7 +4742,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4481
4742
|
const entries = await readActiveEntries();
|
|
4482
4743
|
const tasks = /* @__PURE__ */ new Map();
|
|
4483
4744
|
for (const entry of entries) {
|
|
4484
|
-
const filePath =
|
|
4745
|
+
const filePath = path7.join(listDirectoryPath, entry.filename);
|
|
4485
4746
|
const file = await readTaskFile(
|
|
4486
4747
|
deps.fs,
|
|
4487
4748
|
list,
|
|
@@ -4502,7 +4763,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4502
4763
|
const result = [];
|
|
4503
4764
|
for (const entryName of entries) {
|
|
4504
4765
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
4505
|
-
const entryPath =
|
|
4766
|
+
const entryPath = path7.join(archivePath, entryName);
|
|
4506
4767
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4507
4768
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4508
4769
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4532,12 +4793,12 @@ function createTasksView2(deps, layout, list) {
|
|
|
4532
4793
|
if (desiredOrder === void 0) continue;
|
|
4533
4794
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
4534
4795
|
if (entry.filename !== desiredFilename) {
|
|
4535
|
-
const fromPath =
|
|
4536
|
-
const stagingPath =
|
|
4796
|
+
const fromPath = path7.join(listDirectoryPath, entry.filename);
|
|
4797
|
+
const stagingPath = path7.join(
|
|
4537
4798
|
listDirectoryPath,
|
|
4538
4799
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
4539
4800
|
);
|
|
4540
|
-
const targetPath =
|
|
4801
|
+
const targetPath = path7.join(listDirectoryPath, desiredFilename);
|
|
4541
4802
|
try {
|
|
4542
4803
|
await deps.fs.rename(fromPath, stagingPath);
|
|
4543
4804
|
staged.push({ original: fromPath, staging: stagingPath, target: targetPath, finalized: false });
|
|
@@ -4686,7 +4947,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4686
4947
|
assertCreateHasId(input);
|
|
4687
4948
|
validateTaskId(input.id);
|
|
4688
4949
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
4689
|
-
return withFileLock(deps.fs,
|
|
4950
|
+
return withFileLock(deps.fs, path7.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
4690
4951
|
const existing = await findTaskLocation(deps.fs, deps.path, layout, list, input.id);
|
|
4691
4952
|
if (existing) {
|
|
4692
4953
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -4699,7 +4960,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4699
4960
|
const nextOrder = maxOrder + 1;
|
|
4700
4961
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
4701
4962
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
4702
|
-
const targetPath =
|
|
4963
|
+
const targetPath = path7.join(listDirectoryPath, filename);
|
|
4703
4964
|
const frontmatter = createdFrontmatter(
|
|
4704
4965
|
deps.defaults,
|
|
4705
4966
|
input,
|
|
@@ -4807,7 +5068,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4807
5068
|
validateTaskId(id);
|
|
4808
5069
|
const { event, nextTask } = await withFileLock(
|
|
4809
5070
|
deps.fs,
|
|
4810
|
-
|
|
5071
|
+
path7.join(listDirectoryPath, ".transition.lock"),
|
|
4811
5072
|
fireTask
|
|
4812
5073
|
);
|
|
4813
5074
|
await event.onEnter?.(nextTask);
|
|
@@ -4900,7 +5161,7 @@ async function markdownDirBackend(deps) {
|
|
|
4900
5161
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
4901
5162
|
continue;
|
|
4902
5163
|
}
|
|
4903
|
-
const entryPath =
|
|
5164
|
+
const entryPath = path7.join(deps.path, entryName);
|
|
4904
5165
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4905
5166
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4906
5167
|
if (entryStat?.isDirectory()) {
|
|
@@ -4942,7 +5203,7 @@ async function markdownDirBackend(deps) {
|
|
|
4942
5203
|
}
|
|
4943
5204
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
4944
5205
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
4945
|
-
return withFileLock(deps.fs,
|
|
5206
|
+
return withFileLock(deps.fs, path7.join(targetListDir, ".transition.lock"), async () => {
|
|
4946
5207
|
const targetExisting = await findTaskLocation(deps.fs, deps.path, layout, targetListName, id);
|
|
4947
5208
|
if (targetExisting) {
|
|
4948
5209
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
@@ -4992,7 +5253,7 @@ async function markdownDirBackend(deps) {
|
|
|
4992
5253
|
);
|
|
4993
5254
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
4994
5255
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
4995
|
-
const targetPath =
|
|
5256
|
+
const targetPath = path7.join(targetListDir, targetFilename);
|
|
4996
5257
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
4997
5258
|
return createTask(
|
|
4998
5259
|
targetListName,
|
|
@@ -5014,7 +5275,7 @@ async function markdownDirBackend(deps) {
|
|
|
5014
5275
|
}
|
|
5015
5276
|
|
|
5016
5277
|
// ../task-list/src/backends/yaml-file.ts
|
|
5017
|
-
import
|
|
5278
|
+
import path8 from "node:path";
|
|
5018
5279
|
import { isMap, parseDocument as parseDocument2 } from "yaml";
|
|
5019
5280
|
|
|
5020
5281
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -5110,7 +5371,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5110
5371
|
state: taskRecord.state,
|
|
5111
5372
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5112
5373
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5113
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5374
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5114
5375
|
};
|
|
5115
5376
|
}
|
|
5116
5377
|
function matchesFilter(task, filter) {
|
|
@@ -5122,13 +5383,13 @@ function matchesFilter(task, filter) {
|
|
|
5122
5383
|
}
|
|
5123
5384
|
return true;
|
|
5124
5385
|
}
|
|
5125
|
-
function createTaskRecord(
|
|
5386
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5126
5387
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5127
5388
|
name: input.name,
|
|
5128
5389
|
state: initialState,
|
|
5129
5390
|
description: input.description ?? ""
|
|
5130
5391
|
});
|
|
5131
|
-
for (const [key2, value] of Object.entries(
|
|
5392
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5132
5393
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5133
5394
|
taskRecord[key2] = value;
|
|
5134
5395
|
}
|
|
@@ -5675,7 +5936,7 @@ async function openGhIssuesBackend(options) {
|
|
|
5675
5936
|
|
|
5676
5937
|
// ../task-list/src/move.ts
|
|
5677
5938
|
import * as fsPromises2 from "node:fs/promises";
|
|
5678
|
-
import
|
|
5939
|
+
import path9 from "node:path";
|
|
5679
5940
|
|
|
5680
5941
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
5681
5942
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6171,13 +6432,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
6171
6432
|
}
|
|
6172
6433
|
function enumerateApprovalCommandPaths(root) {
|
|
6173
6434
|
const paths = [];
|
|
6174
|
-
const visit = (node,
|
|
6435
|
+
const visit = (node, path24) => {
|
|
6175
6436
|
if (node.kind === "command") {
|
|
6176
|
-
paths.push(
|
|
6437
|
+
paths.push(path24.join("."));
|
|
6177
6438
|
return;
|
|
6178
6439
|
}
|
|
6179
6440
|
for (const child of getVisibleCliChildren(node)) {
|
|
6180
|
-
visit(child, [...
|
|
6441
|
+
visit(child, [...path24, child.name]);
|
|
6181
6442
|
}
|
|
6182
6443
|
};
|
|
6183
6444
|
if (root.kind === "command") {
|
|
@@ -6212,21 +6473,21 @@ function createHandlerContext(command, params17) {
|
|
|
6212
6473
|
}
|
|
6213
6474
|
function createFs() {
|
|
6214
6475
|
return {
|
|
6215
|
-
readFile: async (
|
|
6216
|
-
writeFile: async (
|
|
6217
|
-
await writeFile2(
|
|
6476
|
+
readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
|
|
6477
|
+
writeFile: async (path24, contents) => {
|
|
6478
|
+
await writeFile2(path24, contents);
|
|
6218
6479
|
},
|
|
6219
|
-
exists: async (
|
|
6480
|
+
exists: async (path24) => {
|
|
6220
6481
|
try {
|
|
6221
|
-
await access(
|
|
6482
|
+
await access(path24);
|
|
6222
6483
|
return true;
|
|
6223
6484
|
} catch {
|
|
6224
6485
|
return false;
|
|
6225
6486
|
}
|
|
6226
6487
|
},
|
|
6227
|
-
lstat: async (
|
|
6488
|
+
lstat: async (path24) => lstat(path24),
|
|
6228
6489
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
6229
|
-
unlink: async (
|
|
6490
|
+
unlink: async (path24) => unlink(path24)
|
|
6230
6491
|
};
|
|
6231
6492
|
}
|
|
6232
6493
|
function createEnv(values = process.env) {
|
|
@@ -6502,17 +6763,17 @@ function isMissingStateError(error3) {
|
|
|
6502
6763
|
}
|
|
6503
6764
|
|
|
6504
6765
|
// ../toolcraft/src/error-report.ts
|
|
6505
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6506
|
-
import { randomUUID as
|
|
6766
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6767
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6507
6768
|
import os from "node:os";
|
|
6508
|
-
import
|
|
6769
|
+
import path13 from "node:path";
|
|
6509
6770
|
import { CommanderError } from "commander";
|
|
6510
6771
|
|
|
6511
6772
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6512
6773
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6513
6774
|
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6514
|
-
import
|
|
6515
|
-
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
6775
|
+
import path12 from "node:path";
|
|
6776
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
6516
6777
|
|
|
6517
6778
|
// ../tiny-mcp-client/src/internal.ts
|
|
6518
6779
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6520,13 +6781,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
6520
6781
|
|
|
6521
6782
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
6522
6783
|
import crypto from "node:crypto";
|
|
6523
|
-
import
|
|
6784
|
+
import path11 from "node:path";
|
|
6524
6785
|
|
|
6525
6786
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6526
6787
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6527
6788
|
import { promises as fs } from "node:fs";
|
|
6528
6789
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6529
|
-
import
|
|
6790
|
+
import path10 from "node:path";
|
|
6530
6791
|
var derivedKeyCache = /* @__PURE__ */ new Map();
|
|
6531
6792
|
var ENCRYPTION_ALGORITHM = "aes-256-gcm";
|
|
6532
6793
|
var ENCRYPTION_VERSION = 1;
|
|
@@ -6538,6 +6799,7 @@ var temporaryFileSequence = 0;
|
|
|
6538
6799
|
var EncryptedFileStore = class {
|
|
6539
6800
|
fs;
|
|
6540
6801
|
filePath;
|
|
6802
|
+
symbolicLinkCheckStartPath;
|
|
6541
6803
|
salt;
|
|
6542
6804
|
getMachineIdentity;
|
|
6543
6805
|
getRandomBytes;
|
|
@@ -6545,11 +6807,22 @@ var EncryptedFileStore = class {
|
|
|
6545
6807
|
constructor(input) {
|
|
6546
6808
|
this.fs = input.fs ?? fs;
|
|
6547
6809
|
this.salt = input.salt;
|
|
6548
|
-
|
|
6549
|
-
(input.getHomeDirectory ?? homedir)()
|
|
6550
|
-
input.defaultDirectory ?? ".auth-store"
|
|
6551
|
-
|
|
6552
|
-
|
|
6810
|
+
if (input.filePath === void 0) {
|
|
6811
|
+
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
6812
|
+
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
6813
|
+
this.filePath = path10.join(
|
|
6814
|
+
homeDirectory,
|
|
6815
|
+
defaultDirectory,
|
|
6816
|
+
input.defaultFileName ?? "credentials.enc"
|
|
6817
|
+
);
|
|
6818
|
+
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
6819
|
+
homeDirectory,
|
|
6820
|
+
defaultDirectory
|
|
6821
|
+
);
|
|
6822
|
+
} else {
|
|
6823
|
+
this.filePath = input.filePath;
|
|
6824
|
+
this.symbolicLinkCheckStartPath = null;
|
|
6825
|
+
}
|
|
6553
6826
|
this.getMachineIdentity = input.getMachineIdentity ?? defaultMachineIdentity;
|
|
6554
6827
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6555
6828
|
}
|
|
@@ -6600,7 +6873,7 @@ var EncryptedFileStore = class {
|
|
|
6600
6873
|
authTag: authTag.toString("base64"),
|
|
6601
6874
|
ciphertext: ciphertext.toString("base64")
|
|
6602
6875
|
};
|
|
6603
|
-
await this.fs.mkdir(
|
|
6876
|
+
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6604
6877
|
await this.assertRegularCredentialPath();
|
|
6605
6878
|
const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
|
|
6606
6879
|
try {
|
|
@@ -6629,8 +6902,11 @@ var EncryptedFileStore = class {
|
|
|
6629
6902
|
}
|
|
6630
6903
|
}
|
|
6631
6904
|
async assertRegularCredentialPath() {
|
|
6632
|
-
const resolvedPath =
|
|
6633
|
-
const protectedPaths =
|
|
6905
|
+
const resolvedPath = path10.resolve(this.filePath);
|
|
6906
|
+
const protectedPaths = getProtectedCredentialPaths(
|
|
6907
|
+
resolvedPath,
|
|
6908
|
+
this.symbolicLinkCheckStartPath
|
|
6909
|
+
);
|
|
6634
6910
|
for (const currentPath of protectedPaths) {
|
|
6635
6911
|
try {
|
|
6636
6912
|
const stats = await this.fs.lstat(currentPath);
|
|
@@ -6658,6 +6934,30 @@ var EncryptedFileStore = class {
|
|
|
6658
6934
|
return this.keyPromise;
|
|
6659
6935
|
}
|
|
6660
6936
|
};
|
|
6937
|
+
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
6938
|
+
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
6939
|
+
return path10.resolve(homeDirectory, firstSegment ?? ".");
|
|
6940
|
+
}
|
|
6941
|
+
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
6942
|
+
if (symbolicLinkCheckStartPath === null) {
|
|
6943
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6944
|
+
}
|
|
6945
|
+
const resolvedStartPath = path10.resolve(symbolicLinkCheckStartPath);
|
|
6946
|
+
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
6947
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6948
|
+
}
|
|
6949
|
+
const protectedPaths = [resolvedStartPath];
|
|
6950
|
+
let currentPath = resolvedStartPath;
|
|
6951
|
+
for (const segment of path10.relative(resolvedStartPath, resolvedPath).split(path10.sep).filter(Boolean)) {
|
|
6952
|
+
currentPath = path10.join(currentPath, segment);
|
|
6953
|
+
protectedPaths.push(currentPath);
|
|
6954
|
+
}
|
|
6955
|
+
return protectedPaths;
|
|
6956
|
+
}
|
|
6957
|
+
function isPathInsideOrEqual(childPath, parentPath) {
|
|
6958
|
+
const relativePath = path10.relative(parentPath, childPath);
|
|
6959
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
|
|
6960
|
+
}
|
|
6661
6961
|
async function removeIfPresent(fileSystem, filePath) {
|
|
6662
6962
|
try {
|
|
6663
6963
|
await fileSystem.unlink(filePath);
|
|
@@ -6808,6 +7108,17 @@ function runSecurityCommand(command, args, options) {
|
|
|
6808
7108
|
});
|
|
6809
7109
|
let stdout = "";
|
|
6810
7110
|
let stderr = "";
|
|
7111
|
+
let stdinErrorMessage;
|
|
7112
|
+
const appendStderr = (message2) => {
|
|
7113
|
+
stderr = stderr.length === 0 ? message2 : `${stderr}${stderr.endsWith("\n") ? "" : "\n"}${message2}`;
|
|
7114
|
+
};
|
|
7115
|
+
const appendStdinError = () => {
|
|
7116
|
+
if (stdinErrorMessage === void 0) {
|
|
7117
|
+
return;
|
|
7118
|
+
}
|
|
7119
|
+
appendStderr(stdinErrorMessage);
|
|
7120
|
+
stdinErrorMessage = void 0;
|
|
7121
|
+
};
|
|
6811
7122
|
child.stdout?.setEncoding("utf8");
|
|
6812
7123
|
child.stdout?.on("data", (chunk) => {
|
|
6813
7124
|
stdout += chunk.toString();
|
|
@@ -6817,17 +7128,23 @@ function runSecurityCommand(command, args, options) {
|
|
|
6817
7128
|
stderr += chunk.toString();
|
|
6818
7129
|
});
|
|
6819
7130
|
if (options?.stdin !== void 0) {
|
|
7131
|
+
child.stdin?.once("error", (error3) => {
|
|
7132
|
+
stdinErrorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
7133
|
+
});
|
|
6820
7134
|
child.stdin?.end(options.stdin);
|
|
6821
7135
|
}
|
|
6822
7136
|
child.on("error", (error3) => {
|
|
6823
7137
|
const message2 = error3 instanceof Error ? error3.message : String(error3 ?? "Unknown error");
|
|
7138
|
+
appendStdinError();
|
|
7139
|
+
appendStderr(message2);
|
|
6824
7140
|
resolve({
|
|
6825
7141
|
stdout,
|
|
6826
|
-
stderr
|
|
7142
|
+
stderr,
|
|
6827
7143
|
exitCode: 127
|
|
6828
7144
|
});
|
|
6829
7145
|
});
|
|
6830
7146
|
child.on("close", (code) => {
|
|
7147
|
+
appendStdinError();
|
|
6831
7148
|
resolve({
|
|
6832
7149
|
stdout,
|
|
6833
7150
|
stderr,
|
|
@@ -6965,19 +7282,24 @@ function createAuthStoreClientStore(options) {
|
|
|
6965
7282
|
}
|
|
6966
7283
|
};
|
|
6967
7284
|
}
|
|
6968
|
-
function createNamedSecretStore(key2, options,
|
|
7285
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
6969
7286
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
6970
|
-
const
|
|
7287
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7288
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
6971
7289
|
const fileStore = {
|
|
6972
7290
|
...options.fileStore,
|
|
6973
|
-
|
|
6974
|
-
|
|
7291
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7292
|
+
parsedFilePath.dir,
|
|
7293
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7294
|
+
),
|
|
7295
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7296
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
6975
7297
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
6976
7298
|
};
|
|
6977
7299
|
const keychainStore = {
|
|
6978
7300
|
...options.keychainStore,
|
|
6979
|
-
service: options.keychainStore?.service ??
|
|
6980
|
-
account: `${options.keychainStore?.account ??
|
|
7301
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7302
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
6981
7303
|
};
|
|
6982
7304
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
6983
7305
|
}
|
|
@@ -8550,10 +8872,19 @@ var McpClient = class {
|
|
|
8550
8872
|
}
|
|
8551
8873
|
try {
|
|
8552
8874
|
let requestId;
|
|
8875
|
+
let cancellationSent = false;
|
|
8876
|
+
const sendCancellationNotification = () => {
|
|
8877
|
+
if (requestId === void 0 || cancellationSent) {
|
|
8878
|
+
return;
|
|
8879
|
+
}
|
|
8880
|
+
cancellationSent = true;
|
|
8881
|
+
messageLayer.sendNotification("notifications/cancelled", { requestId });
|
|
8882
|
+
};
|
|
8553
8883
|
const requestPromise = messageLayer.sendRequest("tools/call", requestParams, {
|
|
8554
8884
|
onRequestId: (nextRequestId) => {
|
|
8555
8885
|
requestId = nextRequestId;
|
|
8556
|
-
}
|
|
8886
|
+
},
|
|
8887
|
+
onTimeout: sendCancellationNotification
|
|
8557
8888
|
}).then((result) => {
|
|
8558
8889
|
if (!isCallToolResult(result)) {
|
|
8559
8890
|
throw new McpError(ERROR_INVALID_REQUEST, "Invalid tool result");
|
|
@@ -8567,8 +8898,9 @@ var McpClient = class {
|
|
|
8567
8898
|
let abortListener;
|
|
8568
8899
|
const abortPromise = new Promise((_, reject) => {
|
|
8569
8900
|
const rejectWithAbortReason = () => {
|
|
8901
|
+
sendCancellationNotification();
|
|
8570
8902
|
if (requestId !== void 0) {
|
|
8571
|
-
messageLayer.
|
|
8903
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
8572
8904
|
}
|
|
8573
8905
|
reject(signal.reason);
|
|
8574
8906
|
};
|
|
@@ -8744,11 +9076,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8744
9076
|
const child = this.child;
|
|
8745
9077
|
this.readable = child.stdout;
|
|
8746
9078
|
this.writable = child.stdin;
|
|
9079
|
+
const stderrDecoder = new TextDecoder();
|
|
8747
9080
|
child.stderr.on("data", (chunk) => {
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
9081
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9082
|
+
this.appendStderrOutput(decoded);
|
|
9083
|
+
});
|
|
9084
|
+
child.stderr.once("end", () => {
|
|
9085
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8752
9086
|
});
|
|
8753
9087
|
this.closed = new Promise((resolve) => {
|
|
8754
9088
|
let settled = false;
|
|
@@ -8788,6 +9122,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
8788
9122
|
getStderrOutput() {
|
|
8789
9123
|
return this.stderrOutput;
|
|
8790
9124
|
}
|
|
9125
|
+
appendStderrOutput(chunk) {
|
|
9126
|
+
if (chunk.length === 0) {
|
|
9127
|
+
return;
|
|
9128
|
+
}
|
|
9129
|
+
this.stderrOutput += chunk;
|
|
9130
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9131
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9132
|
+
}
|
|
9133
|
+
}
|
|
8791
9134
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
8792
9135
|
void reason;
|
|
8793
9136
|
if (this.disposed) {
|
|
@@ -9195,15 +9538,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9195
9538
|
return `${JSON.stringify(message2)}
|
|
9196
9539
|
`;
|
|
9197
9540
|
}
|
|
9198
|
-
function chunkToString(chunk) {
|
|
9199
|
-
if (typeof chunk === "string") {
|
|
9200
|
-
return chunk;
|
|
9201
|
-
}
|
|
9202
|
-
if (chunk instanceof Uint8Array) {
|
|
9203
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9204
|
-
}
|
|
9205
|
-
return String(chunk);
|
|
9206
|
-
}
|
|
9207
9541
|
function normalizeLine(line) {
|
|
9208
9542
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9209
9543
|
}
|
|
@@ -9380,6 +9714,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9380
9714
|
return new Promise((resolve, reject) => {
|
|
9381
9715
|
const timeout = setTimeout(() => {
|
|
9382
9716
|
this.pendingRequests.delete(id);
|
|
9717
|
+
options.onTimeout?.(id);
|
|
9383
9718
|
reject(new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`));
|
|
9384
9719
|
}, timeoutMs);
|
|
9385
9720
|
this.pendingRequests.set(id, { resolve, reject, timeout });
|
|
@@ -9392,6 +9727,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9392
9727
|
}
|
|
9393
9728
|
});
|
|
9394
9729
|
}
|
|
9730
|
+
cancelRequest(requestId, reason) {
|
|
9731
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9732
|
+
if (pending === void 0) {
|
|
9733
|
+
return false;
|
|
9734
|
+
}
|
|
9735
|
+
this.pendingRequests.delete(requestId);
|
|
9736
|
+
clearTimeout(pending.timeout);
|
|
9737
|
+
pending.reject(reason);
|
|
9738
|
+
return true;
|
|
9739
|
+
}
|
|
9395
9740
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9396
9741
|
if (this.disposedError !== void 0) {
|
|
9397
9742
|
return;
|
|
@@ -9792,13 +10137,13 @@ function convertJsonSchema(schema) {
|
|
|
9792
10137
|
}
|
|
9793
10138
|
return convertSchema(schema, schema, []);
|
|
9794
10139
|
}
|
|
9795
|
-
function convertSchema(schema, root,
|
|
9796
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
10140
|
+
function convertSchema(schema, root, path24) {
|
|
10141
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path24);
|
|
9797
10142
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
9798
10143
|
const composition = getComposition(normalizedSchema.schema);
|
|
9799
10144
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
9800
10145
|
throw new Error(
|
|
9801
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10146
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
|
|
9802
10147
|
normalizedSchema.schema.type
|
|
9803
10148
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9804
10149
|
);
|
|
@@ -9810,13 +10155,13 @@ function convertSchema(schema, root, path23) {
|
|
|
9810
10155
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
9811
10156
|
}
|
|
9812
10157
|
if (composition !== void 0) {
|
|
9813
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
10158
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path24);
|
|
9814
10159
|
}
|
|
9815
10160
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
9816
10161
|
return applyMetadata(
|
|
9817
10162
|
S.Record(
|
|
9818
10163
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
9819
|
-
...
|
|
10164
|
+
...path24,
|
|
9820
10165
|
"additionalProperties"
|
|
9821
10166
|
])
|
|
9822
10167
|
),
|
|
@@ -9865,12 +10210,12 @@ function convertSchema(schema, root, path23) {
|
|
|
9865
10210
|
if (normalizedSchema.schema.items === void 0) {
|
|
9866
10211
|
throw new Error(
|
|
9867
10212
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9868
|
-
|
|
10213
|
+
path24
|
|
9869
10214
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
9870
10215
|
);
|
|
9871
10216
|
}
|
|
9872
10217
|
return S.Array(
|
|
9873
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
10218
|
+
convertSchema(normalizedSchema.schema.items, root, [...path24, "items"]),
|
|
9874
10219
|
createCommonOptions(
|
|
9875
10220
|
normalizedSchema.schema,
|
|
9876
10221
|
normalizedSchema.nullable,
|
|
@@ -9880,7 +10225,7 @@ function convertSchema(schema, root, path23) {
|
|
|
9880
10225
|
case "object":
|
|
9881
10226
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
9882
10227
|
nullable: normalizedSchema.nullable,
|
|
9883
|
-
path:
|
|
10228
|
+
path: path24
|
|
9884
10229
|
});
|
|
9885
10230
|
case "null":
|
|
9886
10231
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -9895,12 +10240,12 @@ function convertSchema(schema, root, path23) {
|
|
|
9895
10240
|
}
|
|
9896
10241
|
throw new Error(
|
|
9897
10242
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9898
|
-
|
|
10243
|
+
path24
|
|
9899
10244
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
9900
10245
|
);
|
|
9901
10246
|
}
|
|
9902
10247
|
throw new Error(
|
|
9903
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10248
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
|
|
9904
10249
|
normalizedSchema.schema.type
|
|
9905
10250
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9906
10251
|
);
|
|
@@ -9944,21 +10289,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
9944
10289
|
)
|
|
9945
10290
|
});
|
|
9946
10291
|
}
|
|
9947
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
10292
|
+
function convertCompositionSchema(schema, root, nullable, path24) {
|
|
9948
10293
|
const composition = getComposition(schema);
|
|
9949
10294
|
const branchSchemas = composition?.branches ?? [];
|
|
9950
10295
|
const keyword = composition?.keyword ?? "oneOf";
|
|
9951
10296
|
const branches = branchSchemas.map(
|
|
9952
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
10297
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path24, keyword, String(index)])
|
|
9953
10298
|
);
|
|
9954
|
-
const discriminator = findDiscriminator(branches, root,
|
|
10299
|
+
const discriminator = findDiscriminator(branches, root, path24);
|
|
9955
10300
|
if (discriminator !== void 0) {
|
|
9956
10301
|
const convertedBranches = Object.fromEntries(
|
|
9957
10302
|
branches.map((branch, index) => [
|
|
9958
10303
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
9959
10304
|
convertObjectSchema(branch, root, {
|
|
9960
10305
|
omitProperty: discriminator,
|
|
9961
|
-
path: [...
|
|
10306
|
+
path: [...path24, keyword, String(index)]
|
|
9962
10307
|
})
|
|
9963
10308
|
])
|
|
9964
10309
|
);
|
|
@@ -9977,7 +10322,7 @@ function convertCompositionSchema(schema, root, nullable, path23) {
|
|
|
9977
10322
|
S.Union(
|
|
9978
10323
|
branches.map(
|
|
9979
10324
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
9980
|
-
path: [...
|
|
10325
|
+
path: [...path24, keyword, String(index)]
|
|
9981
10326
|
})
|
|
9982
10327
|
)
|
|
9983
10328
|
),
|
|
@@ -10079,11 +10424,11 @@ function getComposition(schema) {
|
|
|
10079
10424
|
}
|
|
10080
10425
|
return void 0;
|
|
10081
10426
|
}
|
|
10082
|
-
function formatJsonSchemaPath(
|
|
10083
|
-
if (
|
|
10427
|
+
function formatJsonSchemaPath(path24) {
|
|
10428
|
+
if (path24.length === 0) {
|
|
10084
10429
|
return "#";
|
|
10085
10430
|
}
|
|
10086
|
-
return `#/${
|
|
10431
|
+
return `#/${path24.map(escapeJsonPointerSegment).join("/")}`;
|
|
10087
10432
|
}
|
|
10088
10433
|
function formatJsonSchemaType(type2) {
|
|
10089
10434
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -10099,11 +10444,11 @@ function isRecordSchema(schema) {
|
|
|
10099
10444
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
10100
10445
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
10101
10446
|
}
|
|
10102
|
-
function findDiscriminator(branches, root,
|
|
10447
|
+
function findDiscriminator(branches, root, path24) {
|
|
10103
10448
|
const [firstBranch] = branches;
|
|
10104
10449
|
if (firstBranch === void 0) {
|
|
10105
10450
|
throw new Error(
|
|
10106
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10451
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
10107
10452
|
);
|
|
10108
10453
|
}
|
|
10109
10454
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -10143,19 +10488,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
10143
10488
|
}
|
|
10144
10489
|
return void 0;
|
|
10145
10490
|
}
|
|
10146
|
-
function resolveReferencedSchema(schema, root,
|
|
10491
|
+
function resolveReferencedSchema(schema, root, path24) {
|
|
10147
10492
|
if (schema.$ref === void 0) {
|
|
10148
10493
|
return schema;
|
|
10149
10494
|
}
|
|
10150
10495
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
10151
10496
|
if (resolvedTarget === void 0) {
|
|
10152
10497
|
throw new Error(
|
|
10153
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10498
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
10154
10499
|
);
|
|
10155
10500
|
}
|
|
10156
10501
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
10157
10502
|
void ignoredRef;
|
|
10158
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
10503
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path24);
|
|
10159
10504
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
10160
10505
|
return resolvedSchema;
|
|
10161
10506
|
}
|
|
@@ -10179,9 +10524,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
10179
10524
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
10180
10525
|
};
|
|
10181
10526
|
}
|
|
10182
|
-
function hasSelfReferencingRef(schema, root,
|
|
10527
|
+
function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
10183
10528
|
const nextActivePaths = new Set(activePaths);
|
|
10184
|
-
nextActivePaths.add(
|
|
10529
|
+
nextActivePaths.add(path24);
|
|
10185
10530
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
10186
10531
|
if (localRefPath !== void 0) {
|
|
10187
10532
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -10192,13 +10537,13 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10192
10537
|
return true;
|
|
10193
10538
|
}
|
|
10194
10539
|
}
|
|
10195
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
10540
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path24}/items`, nextActivePaths)) {
|
|
10196
10541
|
return true;
|
|
10197
10542
|
}
|
|
10198
10543
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
10199
10544
|
schema.additionalProperties,
|
|
10200
10545
|
root,
|
|
10201
|
-
`${
|
|
10546
|
+
`${path24}/additionalProperties`,
|
|
10202
10547
|
nextActivePaths
|
|
10203
10548
|
)) {
|
|
10204
10549
|
return true;
|
|
@@ -10207,7 +10552,7 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10207
10552
|
if (hasSelfReferencingRef(
|
|
10208
10553
|
childSchema,
|
|
10209
10554
|
root,
|
|
10210
|
-
`${
|
|
10555
|
+
`${path24}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
10211
10556
|
nextActivePaths
|
|
10212
10557
|
)) {
|
|
10213
10558
|
return true;
|
|
@@ -10217,24 +10562,24 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10217
10562
|
if (hasSelfReferencingRef(
|
|
10218
10563
|
childSchema,
|
|
10219
10564
|
root,
|
|
10220
|
-
`${
|
|
10565
|
+
`${path24}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
10221
10566
|
nextActivePaths
|
|
10222
10567
|
)) {
|
|
10223
10568
|
return true;
|
|
10224
10569
|
}
|
|
10225
10570
|
}
|
|
10226
10571
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
10227
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10572
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/oneOf/${index}`, nextActivePaths)) {
|
|
10228
10573
|
return true;
|
|
10229
10574
|
}
|
|
10230
10575
|
}
|
|
10231
10576
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
10232
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10577
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/anyOf/${index}`, nextActivePaths)) {
|
|
10233
10578
|
return true;
|
|
10234
10579
|
}
|
|
10235
10580
|
}
|
|
10236
10581
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
10237
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10582
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/allOf/${index}`, nextActivePaths)) {
|
|
10238
10583
|
return true;
|
|
10239
10584
|
}
|
|
10240
10585
|
}
|
|
@@ -10250,14 +10595,14 @@ function getLocalRefPath(ref) {
|
|
|
10250
10595
|
return ref.startsWith("#/") ? ref : void 0;
|
|
10251
10596
|
}
|
|
10252
10597
|
function resolveLocalRef(root, ref) {
|
|
10253
|
-
const
|
|
10254
|
-
if (
|
|
10598
|
+
const path24 = getLocalRefPath(ref);
|
|
10599
|
+
if (path24 === void 0) {
|
|
10255
10600
|
return void 0;
|
|
10256
10601
|
}
|
|
10257
|
-
if (
|
|
10602
|
+
if (path24 === "#") {
|
|
10258
10603
|
return root;
|
|
10259
10604
|
}
|
|
10260
|
-
const segments =
|
|
10605
|
+
const segments = path24.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
10261
10606
|
let current = root;
|
|
10262
10607
|
for (const segment of segments) {
|
|
10263
10608
|
if (Array.isArray(current)) {
|
|
@@ -10460,10 +10805,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10460
10805
|
}
|
|
10461
10806
|
}
|
|
10462
10807
|
}
|
|
10463
|
-
function createConnection(name,
|
|
10808
|
+
function createConnection(name, config2) {
|
|
10464
10809
|
const connection = {
|
|
10465
10810
|
name,
|
|
10466
|
-
config,
|
|
10811
|
+
config: config2,
|
|
10467
10812
|
async dispose() {
|
|
10468
10813
|
shutdownDisposers.delete(connection.dispose);
|
|
10469
10814
|
connection.connecting = void 0;
|
|
@@ -10518,8 +10863,8 @@ async function readCache(cachePath) {
|
|
|
10518
10863
|
}
|
|
10519
10864
|
}
|
|
10520
10865
|
async function writeCache(cachePath, cache) {
|
|
10521
|
-
const directory =
|
|
10522
|
-
const tempPath = `${cachePath}.tmp-${
|
|
10866
|
+
const directory = path12.dirname(cachePath);
|
|
10867
|
+
const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
|
|
10523
10868
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10524
10869
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10525
10870
|
await mkdir(directory, { recursive: true });
|
|
@@ -10530,13 +10875,13 @@ async function writeCache(cachePath, cache) {
|
|
|
10530
10875
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10531
10876
|
await rename2(tempPath, cachePath);
|
|
10532
10877
|
}
|
|
10533
|
-
async function fetchCache(name,
|
|
10878
|
+
async function fetchCache(name, config2) {
|
|
10534
10879
|
const logger2 = createLogger((message2) => {
|
|
10535
10880
|
process.stderr.write(`${message2}
|
|
10536
10881
|
`);
|
|
10537
10882
|
});
|
|
10538
10883
|
logger2.info(`MCP ${name}: connecting`);
|
|
10539
|
-
const client = await dialUpstream(name,
|
|
10884
|
+
const client = await dialUpstream(name, config2);
|
|
10540
10885
|
try {
|
|
10541
10886
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10542
10887
|
const tools = [];
|
|
@@ -10555,7 +10900,7 @@ async function fetchCache(name, config) {
|
|
|
10555
10900
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10556
10901
|
version: 1,
|
|
10557
10902
|
upstream,
|
|
10558
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
10903
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10559
10904
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10560
10905
|
tools
|
|
10561
10906
|
};
|
|
@@ -10625,8 +10970,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10625
10970
|
}
|
|
10626
10971
|
async function resolveSingleProxy(group, options) {
|
|
10627
10972
|
const internal = getInternalGroupConfig2(group);
|
|
10628
|
-
const
|
|
10629
|
-
if (
|
|
10973
|
+
const config2 = internal.mcp;
|
|
10974
|
+
if (config2 === void 0) {
|
|
10630
10975
|
return;
|
|
10631
10976
|
}
|
|
10632
10977
|
const name = group.name;
|
|
@@ -10636,21 +10981,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10636
10981
|
let cache;
|
|
10637
10982
|
let shouldWriteCache = false;
|
|
10638
10983
|
if (isRefreshRequested(name, refresh)) {
|
|
10639
|
-
cache = await fetchCache(name,
|
|
10984
|
+
cache = await fetchCache(name, config2);
|
|
10640
10985
|
shouldWriteCache = true;
|
|
10641
10986
|
} else {
|
|
10642
10987
|
const storedCache = await readCache(cachePath);
|
|
10643
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
10988
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10644
10989
|
cache = storedCache;
|
|
10645
10990
|
} else {
|
|
10646
|
-
cache = await fetchCache(name,
|
|
10991
|
+
cache = await fetchCache(name, config2);
|
|
10647
10992
|
shouldWriteCache = true;
|
|
10648
10993
|
}
|
|
10649
10994
|
}
|
|
10650
10995
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10651
10996
|
validateRenameMap2(name, tools, internal.rename);
|
|
10652
10997
|
const previousConnection = getProxyConnection(group);
|
|
10653
|
-
const nextConnection = createConnection(name,
|
|
10998
|
+
const nextConnection = createConnection(name, config2);
|
|
10654
10999
|
try {
|
|
10655
11000
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10656
11001
|
if (shouldWriteCache) {
|
|
@@ -10675,11 +11020,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10675
11020
|
);
|
|
10676
11021
|
}
|
|
10677
11022
|
}
|
|
10678
|
-
function cacheMatchesConfig(cache,
|
|
10679
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
11023
|
+
function cacheMatchesConfig(cache, config2) {
|
|
11024
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10680
11025
|
}
|
|
10681
|
-
function fingerprintMcpServerConfig(
|
|
10682
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
11026
|
+
function fingerprintMcpServerConfig(config2) {
|
|
11027
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10683
11028
|
}
|
|
10684
11029
|
function collectProxyGroups(root) {
|
|
10685
11030
|
const groups = [];
|
|
@@ -10699,13 +11044,13 @@ function collectProxyGroups(root) {
|
|
|
10699
11044
|
function findProjectRoot(from = process.cwd()) {
|
|
10700
11045
|
let current = process.cwd();
|
|
10701
11046
|
if (from !== current) {
|
|
10702
|
-
current =
|
|
11047
|
+
current = path12.resolve(from);
|
|
10703
11048
|
}
|
|
10704
11049
|
while (true) {
|
|
10705
|
-
if (existsSync2(
|
|
11050
|
+
if (existsSync2(path12.join(current, "package.json"))) {
|
|
10706
11051
|
return current;
|
|
10707
11052
|
}
|
|
10708
|
-
const parent =
|
|
11053
|
+
const parent = path12.dirname(current);
|
|
10709
11054
|
if (parent === current) {
|
|
10710
11055
|
return void 0;
|
|
10711
11056
|
}
|
|
@@ -10722,7 +11067,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
10722
11067
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
10723
11068
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
10724
11069
|
}
|
|
10725
|
-
return
|
|
11070
|
+
return path12.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
10726
11071
|
}
|
|
10727
11072
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
10728
11073
|
let currentPath = filePath;
|
|
@@ -10736,10 +11081,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
10736
11081
|
throw error3;
|
|
10737
11082
|
}
|
|
10738
11083
|
}
|
|
10739
|
-
if (
|
|
11084
|
+
if (path12.basename(currentPath) === ".toolcraft") {
|
|
10740
11085
|
return;
|
|
10741
11086
|
}
|
|
10742
|
-
const parentPath =
|
|
11087
|
+
const parentPath = path12.dirname(currentPath);
|
|
10743
11088
|
if (parentPath === currentPath) {
|
|
10744
11089
|
return;
|
|
10745
11090
|
}
|
|
@@ -10757,20 +11102,20 @@ function parseRefreshEnv(value) {
|
|
|
10757
11102
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10758
11103
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10759
11104
|
}
|
|
10760
|
-
async function dialUpstream(name,
|
|
11105
|
+
async function dialUpstream(name, config2) {
|
|
10761
11106
|
const client = new McpClient({
|
|
10762
11107
|
clientInfo: {
|
|
10763
11108
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10764
11109
|
version: DEFAULT_CLIENT_INFO.version
|
|
10765
11110
|
}
|
|
10766
11111
|
});
|
|
10767
|
-
const transport =
|
|
10768
|
-
command:
|
|
10769
|
-
...
|
|
10770
|
-
...
|
|
11112
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11113
|
+
command: config2.command,
|
|
11114
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11115
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10771
11116
|
}) : new HttpTransport({
|
|
10772
|
-
url:
|
|
10773
|
-
...
|
|
11117
|
+
url: config2.url,
|
|
11118
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10774
11119
|
});
|
|
10775
11120
|
await client.connect(transport);
|
|
10776
11121
|
return client;
|
|
@@ -10780,10 +11125,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
10780
11125
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
10781
11126
|
}
|
|
10782
11127
|
|
|
11128
|
+
// ../toolcraft/src/redaction.ts
|
|
11129
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11130
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11131
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11132
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11133
|
+
function isPlainObject2(value) {
|
|
11134
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11135
|
+
}
|
|
11136
|
+
function normalizeName(name) {
|
|
11137
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11138
|
+
}
|
|
11139
|
+
function isSensitiveName(name) {
|
|
11140
|
+
const normalized = normalizeName(name);
|
|
11141
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11142
|
+
}
|
|
11143
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11144
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11145
|
+
return REDACTED_VALUE;
|
|
11146
|
+
}
|
|
11147
|
+
if (Array.isArray(value)) {
|
|
11148
|
+
if (seen.has(value)) {
|
|
11149
|
+
return "[Circular]";
|
|
11150
|
+
}
|
|
11151
|
+
seen.add(value);
|
|
11152
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11153
|
+
}
|
|
11154
|
+
if (isPlainObject2(value)) {
|
|
11155
|
+
if (seen.has(value)) {
|
|
11156
|
+
return "[Circular]";
|
|
11157
|
+
}
|
|
11158
|
+
seen.add(value);
|
|
11159
|
+
return Object.fromEntries(
|
|
11160
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11161
|
+
key2,
|
|
11162
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11163
|
+
])
|
|
11164
|
+
);
|
|
11165
|
+
}
|
|
11166
|
+
return value;
|
|
11167
|
+
}
|
|
11168
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11169
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11170
|
+
}
|
|
11171
|
+
function parseJsonObjectOrArray(value) {
|
|
11172
|
+
const trimmed = value.trim();
|
|
11173
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11174
|
+
return void 0;
|
|
11175
|
+
}
|
|
11176
|
+
try {
|
|
11177
|
+
const parsed = JSON.parse(trimmed);
|
|
11178
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11179
|
+
} catch {
|
|
11180
|
+
return void 0;
|
|
11181
|
+
}
|
|
11182
|
+
}
|
|
11183
|
+
function redactHttpBody(body) {
|
|
11184
|
+
if (typeof body === "string") {
|
|
11185
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11186
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11187
|
+
}
|
|
11188
|
+
return redactSecretLikeFields(body);
|
|
11189
|
+
}
|
|
11190
|
+
function redactHttpHeaderValue(name, value) {
|
|
11191
|
+
const normalized = normalizeName(name);
|
|
11192
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11193
|
+
return "Bearer ****";
|
|
11194
|
+
}
|
|
11195
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11196
|
+
return REDACTED_VALUE;
|
|
11197
|
+
}
|
|
11198
|
+
return value;
|
|
11199
|
+
}
|
|
11200
|
+
|
|
10783
11201
|
// ../toolcraft/src/error-report.ts
|
|
10784
11202
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
10785
|
-
|
|
10786
|
-
function isPlainObject2(value) {
|
|
11203
|
+
function isPlainObject3(value) {
|
|
10787
11204
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10788
11205
|
}
|
|
10789
11206
|
function unwrapOptional(schema) {
|
|
@@ -10793,7 +11210,7 @@ function unwrapOptional(schema) {
|
|
|
10793
11210
|
return schema;
|
|
10794
11211
|
}
|
|
10795
11212
|
function hasHttpContext(error3) {
|
|
10796
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11213
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
10797
11214
|
}
|
|
10798
11215
|
function isSkippedError(error3) {
|
|
10799
11216
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -10813,25 +11230,25 @@ function reportsEnabled(option, env) {
|
|
|
10813
11230
|
function resolveReportDir(option, projectRoot) {
|
|
10814
11231
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10815
11232
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
10816
|
-
return
|
|
11233
|
+
return path13.join(projectRoot, ".toolcraft", "errors");
|
|
10817
11234
|
}
|
|
10818
|
-
return
|
|
11235
|
+
return path13.isAbsolute(configuredDir) ? configuredDir : path13.join(projectRoot, configuredDir);
|
|
10819
11236
|
}
|
|
10820
11237
|
function reportDirMustStayWithinProject(option) {
|
|
10821
11238
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10822
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
11239
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path13.isAbsolute(configuredDir);
|
|
10823
11240
|
}
|
|
10824
11241
|
function isWithinDirectory(parent, child) {
|
|
10825
|
-
const relative =
|
|
10826
|
-
return relative === "" || !
|
|
11242
|
+
const relative = path13.relative(parent, child);
|
|
11243
|
+
return relative === "" || !path13.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path13.sep}`);
|
|
10827
11244
|
}
|
|
10828
11245
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
10829
|
-
if (!isWithinDirectory(
|
|
11246
|
+
if (!isWithinDirectory(path13.resolve(projectRoot), path13.resolve(reportDir))) {
|
|
10830
11247
|
throw new Error("Error report directory resolves outside project root.");
|
|
10831
11248
|
}
|
|
10832
11249
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
10833
|
-
|
|
10834
|
-
|
|
11250
|
+
realpath2(projectRoot),
|
|
11251
|
+
realpath2(reportDir)
|
|
10835
11252
|
]);
|
|
10836
11253
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
10837
11254
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -10877,7 +11294,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
10877
11294
|
return output.length === 0 ? "root" : output;
|
|
10878
11295
|
}
|
|
10879
11296
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
10880
|
-
const relative =
|
|
11297
|
+
const relative = path13.relative(projectRoot, absolutePath);
|
|
10881
11298
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
10882
11299
|
}
|
|
10883
11300
|
function redactValue(value) {
|
|
@@ -10886,9 +11303,24 @@ function redactValue(value) {
|
|
|
10886
11303
|
}
|
|
10887
11304
|
return `<set, ${value.length} chars>`;
|
|
10888
11305
|
}
|
|
10889
|
-
function
|
|
10890
|
-
|
|
10891
|
-
|
|
11306
|
+
function collectStringLeaves(value, output) {
|
|
11307
|
+
if (typeof value === "string") {
|
|
11308
|
+
if (value.length > 0) {
|
|
11309
|
+
output.add(value);
|
|
11310
|
+
}
|
|
11311
|
+
return;
|
|
11312
|
+
}
|
|
11313
|
+
if (Array.isArray(value)) {
|
|
11314
|
+
for (const entry of value) {
|
|
11315
|
+
collectStringLeaves(entry, output);
|
|
11316
|
+
}
|
|
11317
|
+
return;
|
|
11318
|
+
}
|
|
11319
|
+
if (isPlainObject3(value)) {
|
|
11320
|
+
for (const entry of Object.values(value)) {
|
|
11321
|
+
collectStringLeaves(entry, output);
|
|
11322
|
+
}
|
|
11323
|
+
}
|
|
10892
11324
|
}
|
|
10893
11325
|
function schemaSecretValue(schema) {
|
|
10894
11326
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -10909,7 +11341,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
10909
11341
|
return "<redacted>";
|
|
10910
11342
|
}
|
|
10911
11343
|
const unwrapped = unwrapOptional(schema);
|
|
10912
|
-
if (unwrapped.kind === "object" &&
|
|
11344
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
10913
11345
|
return Object.fromEntries(
|
|
10914
11346
|
Object.entries(value).map(([key2, childValue]) => {
|
|
10915
11347
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -10931,6 +11363,52 @@ function redactParams(params17, command) {
|
|
|
10931
11363
|
}
|
|
10932
11364
|
return redactParamsValue(params17, command.params, "");
|
|
10933
11365
|
}
|
|
11366
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11367
|
+
if (shouldRedactParam(name, schema)) {
|
|
11368
|
+
collectStringLeaves(value, output);
|
|
11369
|
+
return;
|
|
11370
|
+
}
|
|
11371
|
+
const unwrapped = unwrapOptional(schema);
|
|
11372
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11373
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11374
|
+
const childSchema = unwrapped.shape[key2];
|
|
11375
|
+
if (childSchema !== void 0) {
|
|
11376
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11377
|
+
}
|
|
11378
|
+
}
|
|
11379
|
+
return;
|
|
11380
|
+
}
|
|
11381
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11382
|
+
for (const entry of value) {
|
|
11383
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11384
|
+
}
|
|
11385
|
+
}
|
|
11386
|
+
}
|
|
11387
|
+
function createReportStringRedactor(context, env) {
|
|
11388
|
+
const values = /* @__PURE__ */ new Set();
|
|
11389
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11390
|
+
if (value !== void 0 && value.length > 0) {
|
|
11391
|
+
values.add(value);
|
|
11392
|
+
}
|
|
11393
|
+
}
|
|
11394
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11395
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11396
|
+
if (value !== void 0 && value.length > 0) {
|
|
11397
|
+
values.add(value);
|
|
11398
|
+
}
|
|
11399
|
+
}
|
|
11400
|
+
if (context.command !== void 0) {
|
|
11401
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11402
|
+
}
|
|
11403
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11404
|
+
return (value) => {
|
|
11405
|
+
let redacted = value;
|
|
11406
|
+
for (const secretValue of orderedValues) {
|
|
11407
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11408
|
+
}
|
|
11409
|
+
return redacted;
|
|
11410
|
+
};
|
|
11411
|
+
}
|
|
10934
11412
|
function commandSecretEnvNames(secrets) {
|
|
10935
11413
|
if (secrets === void 0) {
|
|
10936
11414
|
return [];
|
|
@@ -10984,28 +11462,42 @@ function redactArgv(argv, options) {
|
|
|
10984
11462
|
function stableJson(value) {
|
|
10985
11463
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
10986
11464
|
}
|
|
10987
|
-
function redactStructuredErrorField(name, value) {
|
|
10988
|
-
if (typeof value === "string"
|
|
10989
|
-
|
|
11465
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11466
|
+
if (typeof value === "string") {
|
|
11467
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11468
|
+
if (redactedHeaderValue !== value) {
|
|
11469
|
+
return redactedHeaderValue;
|
|
11470
|
+
}
|
|
11471
|
+
if (isSensitiveName(name)) {
|
|
11472
|
+
return "<redacted>";
|
|
11473
|
+
}
|
|
11474
|
+
return redactString(value);
|
|
10990
11475
|
}
|
|
10991
11476
|
if (Array.isArray(value)) {
|
|
10992
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11477
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
10993
11478
|
}
|
|
10994
|
-
if (
|
|
11479
|
+
if (isPlainObject3(value)) {
|
|
10995
11480
|
return Object.fromEntries(
|
|
10996
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11481
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11482
|
+
key2,
|
|
11483
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11484
|
+
])
|
|
10997
11485
|
);
|
|
10998
11486
|
}
|
|
10999
11487
|
return value;
|
|
11000
11488
|
}
|
|
11001
|
-
function ownStructuredFields(error3) {
|
|
11489
|
+
function ownStructuredFields(error3, redactString) {
|
|
11002
11490
|
const fields = {};
|
|
11003
11491
|
for (const key2 of Object.keys(error3)) {
|
|
11004
11492
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
11005
11493
|
continue;
|
|
11006
11494
|
}
|
|
11007
11495
|
Object.defineProperty(fields, key2, {
|
|
11008
|
-
value: redactStructuredErrorField(
|
|
11496
|
+
value: redactStructuredErrorField(
|
|
11497
|
+
key2,
|
|
11498
|
+
error3[key2],
|
|
11499
|
+
redactString
|
|
11500
|
+
),
|
|
11009
11501
|
enumerable: true,
|
|
11010
11502
|
configurable: true,
|
|
11011
11503
|
writable: true
|
|
@@ -11013,43 +11505,44 @@ function ownStructuredFields(error3) {
|
|
|
11013
11505
|
}
|
|
11014
11506
|
return fields;
|
|
11015
11507
|
}
|
|
11016
|
-
function formatStackChain(error3) {
|
|
11508
|
+
function formatStackChain(error3, redactString) {
|
|
11017
11509
|
const lines = [];
|
|
11018
11510
|
let current = error3;
|
|
11019
11511
|
let index = 0;
|
|
11020
11512
|
while (current !== void 0) {
|
|
11021
11513
|
if (current instanceof Error) {
|
|
11022
|
-
|
|
11023
|
-
|
|
11024
|
-
);
|
|
11514
|
+
const stack = current.stack ?? String(current);
|
|
11515
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
11025
11516
|
current = current.cause;
|
|
11026
11517
|
} else {
|
|
11027
|
-
|
|
11518
|
+
const message2 = String(current);
|
|
11519
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
11028
11520
|
current = void 0;
|
|
11029
11521
|
}
|
|
11030
11522
|
index += 1;
|
|
11031
11523
|
}
|
|
11032
11524
|
return lines.join("\n");
|
|
11033
11525
|
}
|
|
11034
|
-
function formatHeaderValue(name, value) {
|
|
11035
|
-
return name
|
|
11526
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11527
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
11036
11528
|
}
|
|
11037
|
-
function formatHeaders(headers) {
|
|
11038
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11529
|
+
function formatHeaders(headers, redactString) {
|
|
11530
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
11039
11531
|
}
|
|
11040
|
-
function formatBody(body) {
|
|
11041
|
-
|
|
11042
|
-
|
|
11532
|
+
function formatBody(body, redactString) {
|
|
11533
|
+
const redactedBody = redactHttpBody(body);
|
|
11534
|
+
if (typeof redactedBody === "string") {
|
|
11535
|
+
return redactString(redactedBody);
|
|
11043
11536
|
}
|
|
11044
|
-
return stableJson(
|
|
11537
|
+
return redactString(stableJson(redactedBody));
|
|
11045
11538
|
}
|
|
11046
|
-
function formatHttpTranscript(error3) {
|
|
11539
|
+
function formatHttpTranscript(error3, redactString) {
|
|
11047
11540
|
const requestLines = [
|
|
11048
11541
|
`${error3.request.method} ${error3.request.url}`,
|
|
11049
|
-
formatHeaders(error3.request.headers)
|
|
11542
|
+
formatHeaders(error3.request.headers, redactString)
|
|
11050
11543
|
].filter((line) => line.length > 0);
|
|
11051
11544
|
if (error3.request.body !== void 0) {
|
|
11052
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11545
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
11053
11546
|
}
|
|
11054
11547
|
return [
|
|
11055
11548
|
"Request:",
|
|
@@ -11057,9 +11550,9 @@ function formatHttpTranscript(error3) {
|
|
|
11057
11550
|
"",
|
|
11058
11551
|
"Response:",
|
|
11059
11552
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
11060
|
-
formatHeaders(error3.response.headers),
|
|
11553
|
+
formatHeaders(error3.response.headers, redactString),
|
|
11061
11554
|
"",
|
|
11062
|
-
formatBody(error3.response.body)
|
|
11555
|
+
formatBody(error3.response.body, redactString)
|
|
11063
11556
|
].join("\n");
|
|
11064
11557
|
}
|
|
11065
11558
|
function resolveToolcraftVersion(version) {
|
|
@@ -11068,9 +11561,10 @@ function resolveToolcraftVersion(version) {
|
|
|
11068
11561
|
function buildReport(context) {
|
|
11069
11562
|
const env = context.env ?? process.env;
|
|
11070
11563
|
const error3 = context.error;
|
|
11564
|
+
const redactString = createReportStringRedactor(context, env);
|
|
11071
11565
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11072
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11073
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11566
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11567
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11074
11568
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11075
11569
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11076
11570
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11084,7 +11578,9 @@ function buildReport(context) {
|
|
|
11084
11578
|
`platform: ${process.platform} ${process.arch}`,
|
|
11085
11579
|
"",
|
|
11086
11580
|
"Argv",
|
|
11087
|
-
|
|
11581
|
+
redactString(
|
|
11582
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11583
|
+
),
|
|
11088
11584
|
"",
|
|
11089
11585
|
"Resolved Secrets",
|
|
11090
11586
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11093,19 +11589,19 @@ function buildReport(context) {
|
|
|
11093
11589
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11094
11590
|
"",
|
|
11095
11591
|
"Parsed Params",
|
|
11096
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11592
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11097
11593
|
"",
|
|
11098
11594
|
"Error",
|
|
11099
11595
|
`name: ${errorName}`,
|
|
11100
11596
|
`message: ${errorMessage}`,
|
|
11101
11597
|
"structured fields:",
|
|
11102
|
-
stableJson(structuredFields),
|
|
11598
|
+
redactString(stableJson(structuredFields)),
|
|
11103
11599
|
"",
|
|
11104
11600
|
"Stack",
|
|
11105
|
-
formatStackChain(error3)
|
|
11601
|
+
formatStackChain(error3, redactString)
|
|
11106
11602
|
];
|
|
11107
11603
|
if (hasHttpContext(error3)) {
|
|
11108
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11604
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11109
11605
|
}
|
|
11110
11606
|
return `${lines.join("\n")}
|
|
11111
11607
|
`;
|
|
@@ -11117,8 +11613,8 @@ async function writeErrorReport(context) {
|
|
|
11117
11613
|
}
|
|
11118
11614
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11119
11615
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11120
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11121
|
-
const absolutePath =
|
|
11616
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
|
|
11617
|
+
const absolutePath = path13.join(reportDir, fileName);
|
|
11122
11618
|
await mkdir2(reportDir, { recursive: true });
|
|
11123
11619
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
11124
11620
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -11565,6 +12061,7 @@ ${rendered.join("\n")}`);
|
|
|
11565
12061
|
}
|
|
11566
12062
|
|
|
11567
12063
|
// ../toolcraft/src/cli.ts
|
|
12064
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11568
12065
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11569
12066
|
"params",
|
|
11570
12067
|
"secrets",
|
|
@@ -11582,7 +12079,7 @@ function inferProgramName(argv) {
|
|
|
11582
12079
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
11583
12080
|
return "toolcraft";
|
|
11584
12081
|
}
|
|
11585
|
-
const parsed =
|
|
12082
|
+
const parsed = path14.parse(entrypoint);
|
|
11586
12083
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
11587
12084
|
}
|
|
11588
12085
|
function normalizeRoots(roots, argv) {
|
|
@@ -11640,11 +12137,11 @@ function formatSegment(segment, casing) {
|
|
|
11640
12137
|
const separator = casing === "snake" ? "_" : "-";
|
|
11641
12138
|
return splitWords3(segment).join(separator);
|
|
11642
12139
|
}
|
|
11643
|
-
function toOptionFlag(
|
|
11644
|
-
return `--${
|
|
12140
|
+
function toOptionFlag(path24, casing) {
|
|
12141
|
+
return `--${path24.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
11645
12142
|
}
|
|
11646
|
-
function toOptionAttribute(
|
|
11647
|
-
return
|
|
12143
|
+
function toOptionAttribute(path24, casing) {
|
|
12144
|
+
return path24.map((segment) => {
|
|
11648
12145
|
const formatted = formatSegment(segment, casing);
|
|
11649
12146
|
if (casing === "snake") {
|
|
11650
12147
|
return formatted;
|
|
@@ -11655,23 +12152,23 @@ function toOptionAttribute(path23, casing) {
|
|
|
11655
12152
|
).join("");
|
|
11656
12153
|
}).join(".");
|
|
11657
12154
|
}
|
|
11658
|
-
function toDisplayPath(
|
|
11659
|
-
return
|
|
12155
|
+
function toDisplayPath(path24) {
|
|
12156
|
+
return path24.join(".");
|
|
11660
12157
|
}
|
|
11661
|
-
function toUnionKindControlPath(
|
|
11662
|
-
if (
|
|
12158
|
+
function toUnionKindControlPath(path24) {
|
|
12159
|
+
if (path24.length === 0) {
|
|
11663
12160
|
return ["kind"];
|
|
11664
12161
|
}
|
|
11665
|
-
const head =
|
|
11666
|
-
const tail =
|
|
12162
|
+
const head = path24.slice(0, -1);
|
|
12163
|
+
const tail = path24[path24.length - 1] ?? "";
|
|
11667
12164
|
return [...head, `${tail}Kind`];
|
|
11668
12165
|
}
|
|
11669
|
-
function toUnionKindDisplayPath(
|
|
11670
|
-
if (
|
|
12166
|
+
function toUnionKindDisplayPath(path24) {
|
|
12167
|
+
if (path24.length === 0) {
|
|
11671
12168
|
return "kind";
|
|
11672
12169
|
}
|
|
11673
|
-
const head =
|
|
11674
|
-
const tail =
|
|
12170
|
+
const head = path24.slice(0, -1);
|
|
12171
|
+
const tail = path24[path24.length - 1] ?? "";
|
|
11675
12172
|
return [...head, `${tail}-kind`].join(".");
|
|
11676
12173
|
}
|
|
11677
12174
|
function createSyntheticEnumSchema(values) {
|
|
@@ -11687,14 +12184,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
11687
12184
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
11688
12185
|
return requiredKeys.join("+");
|
|
11689
12186
|
}
|
|
11690
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
12187
|
+
function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inheritedOptional = false, variantContext) {
|
|
11691
12188
|
const collected = {
|
|
11692
12189
|
dynamicFields: [],
|
|
11693
12190
|
fields: [],
|
|
11694
12191
|
variants: []
|
|
11695
12192
|
};
|
|
11696
12193
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
11697
|
-
const nextPath = [...
|
|
12194
|
+
const nextPath = [...path24, key2];
|
|
11698
12195
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
11699
12196
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
11700
12197
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -11875,9 +12372,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path23 = [], inher
|
|
|
11875
12372
|
}
|
|
11876
12373
|
return collected;
|
|
11877
12374
|
}
|
|
11878
|
-
function toCommanderOptionAttribute(
|
|
11879
|
-
const optionAttribute = toOptionAttribute(
|
|
11880
|
-
const optionFlag = toOptionFlag(
|
|
12375
|
+
function toCommanderOptionAttribute(path24, casing, globalLongOptionFlags) {
|
|
12376
|
+
const optionAttribute = toOptionAttribute(path24, casing);
|
|
12377
|
+
const optionFlag = toOptionFlag(path24, casing);
|
|
11881
12378
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
11882
12379
|
return optionAttribute;
|
|
11883
12380
|
}
|
|
@@ -12846,10 +13343,10 @@ function parseDebugStackMode(value) {
|
|
|
12846
13343
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
12847
13344
|
);
|
|
12848
13345
|
}
|
|
12849
|
-
function setNestedValue(target,
|
|
13346
|
+
function setNestedValue(target, path24, value) {
|
|
12850
13347
|
let cursor = target;
|
|
12851
|
-
for (let index = 0; index <
|
|
12852
|
-
const segment =
|
|
13348
|
+
for (let index = 0; index < path24.length - 1; index += 1) {
|
|
13349
|
+
const segment = path24[index] ?? "";
|
|
12853
13350
|
const existing = Object.prototype.hasOwnProperty.call(cursor, segment) ? cursor[segment] : void 0;
|
|
12854
13351
|
if (typeof existing === "object" && existing !== null) {
|
|
12855
13352
|
cursor = existing;
|
|
@@ -12864,7 +13361,7 @@ function setNestedValue(target, path23, value) {
|
|
|
12864
13361
|
});
|
|
12865
13362
|
cursor = next;
|
|
12866
13363
|
}
|
|
12867
|
-
const leaf =
|
|
13364
|
+
const leaf = path24[path24.length - 1];
|
|
12868
13365
|
if (leaf !== void 0) {
|
|
12869
13366
|
Object.defineProperty(cursor, leaf, {
|
|
12870
13367
|
value,
|
|
@@ -12974,21 +13471,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
12974
13471
|
}
|
|
12975
13472
|
function createFs2() {
|
|
12976
13473
|
return {
|
|
12977
|
-
readFile: async (
|
|
12978
|
-
writeFile: async (
|
|
12979
|
-
await writeFile5(
|
|
13474
|
+
readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
|
|
13475
|
+
writeFile: async (path24, contents) => {
|
|
13476
|
+
await writeFile5(path24, contents);
|
|
12980
13477
|
},
|
|
12981
|
-
exists: async (
|
|
13478
|
+
exists: async (path24) => {
|
|
12982
13479
|
try {
|
|
12983
|
-
await access2(
|
|
13480
|
+
await access2(path24);
|
|
12984
13481
|
return true;
|
|
12985
13482
|
} catch {
|
|
12986
13483
|
return false;
|
|
12987
13484
|
}
|
|
12988
13485
|
},
|
|
12989
|
-
lstat: async (
|
|
13486
|
+
lstat: async (path24) => lstat3(path24),
|
|
12990
13487
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
12991
|
-
unlink: async (
|
|
13488
|
+
unlink: async (path24) => unlink2(path24)
|
|
12992
13489
|
};
|
|
12993
13490
|
}
|
|
12994
13491
|
function createEnv2(values = process.env) {
|
|
@@ -12998,15 +13495,15 @@ function createEnv2(values = process.env) {
|
|
|
12998
13495
|
}
|
|
12999
13496
|
};
|
|
13000
13497
|
}
|
|
13001
|
-
function
|
|
13498
|
+
function isPlainObject4(value) {
|
|
13002
13499
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13003
13500
|
}
|
|
13004
13501
|
function hasFieldValue(value) {
|
|
13005
13502
|
return value !== void 0;
|
|
13006
13503
|
}
|
|
13007
|
-
function hasNestedField(fields,
|
|
13504
|
+
function hasNestedField(fields, path24) {
|
|
13008
13505
|
return fields.some(
|
|
13009
|
-
(field) =>
|
|
13506
|
+
(field) => path24.length < field.path.length && path24.every((segment, index) => field.path[index] === segment)
|
|
13010
13507
|
);
|
|
13011
13508
|
}
|
|
13012
13509
|
function describeExpectedPresetValue(schema) {
|
|
@@ -13107,14 +13604,14 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13107
13604
|
{ cause: error3 }
|
|
13108
13605
|
);
|
|
13109
13606
|
}
|
|
13110
|
-
if (!
|
|
13607
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13111
13608
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13112
13609
|
}
|
|
13113
13610
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
13114
13611
|
const presetValues = {};
|
|
13115
|
-
function visitObject(current,
|
|
13612
|
+
function visitObject(current, path24) {
|
|
13116
13613
|
for (const [key2, value] of Object.entries(current)) {
|
|
13117
|
-
const nextPath = [...
|
|
13614
|
+
const nextPath = [...path24, key2];
|
|
13118
13615
|
const displayPath = toDisplayPath(nextPath);
|
|
13119
13616
|
const field = fieldByPath.get(displayPath);
|
|
13120
13617
|
if (field !== void 0) {
|
|
@@ -13126,7 +13623,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13126
13623
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13127
13624
|
);
|
|
13128
13625
|
}
|
|
13129
|
-
if (!
|
|
13626
|
+
if (!isPlainObject4(value)) {
|
|
13130
13627
|
throw new UserError(
|
|
13131
13628
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13132
13629
|
);
|
|
@@ -13169,8 +13666,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13169
13666
|
}
|
|
13170
13667
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13171
13668
|
}
|
|
13172
|
-
if (
|
|
13173
|
-
if (!
|
|
13669
|
+
if (isPlainObject4(expected)) {
|
|
13670
|
+
if (!isPlainObject4(actual)) {
|
|
13174
13671
|
return false;
|
|
13175
13672
|
}
|
|
13176
13673
|
return Object.entries(expected).every(
|
|
@@ -13233,9 +13730,9 @@ function createFixtureFetch(entries) {
|
|
|
13233
13730
|
};
|
|
13234
13731
|
}
|
|
13235
13732
|
function createFixtureFs(definition) {
|
|
13236
|
-
const fsDefinition =
|
|
13237
|
-
const readFileEntries =
|
|
13238
|
-
const existsEntries =
|
|
13733
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13734
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13735
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13239
13736
|
return {
|
|
13240
13737
|
readFile: async (filePath) => {
|
|
13241
13738
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13258,10 +13755,10 @@ function createFixtureFs(definition) {
|
|
|
13258
13755
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13259
13756
|
if (Array.isArray(definition)) {
|
|
13260
13757
|
for (const entry of definition) {
|
|
13261
|
-
if (!
|
|
13758
|
+
if (!isPlainObject4(entry)) {
|
|
13262
13759
|
continue;
|
|
13263
13760
|
}
|
|
13264
|
-
const explicitMatcher =
|
|
13761
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13265
13762
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13266
13763
|
Object.entries(entry).filter(
|
|
13267
13764
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13273,7 +13770,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13273
13770
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13274
13771
|
} else if (Object.keys(matcher).length === 0) {
|
|
13275
13772
|
matched = true;
|
|
13276
|
-
} else if (
|
|
13773
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13277
13774
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13278
13775
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13279
13776
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13294,7 +13791,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13294
13791
|
return Promise.resolve(null);
|
|
13295
13792
|
}
|
|
13296
13793
|
}
|
|
13297
|
-
if (
|
|
13794
|
+
if (isPlainObject4(definition)) {
|
|
13298
13795
|
const firstArg = args[0];
|
|
13299
13796
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13300
13797
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13306,7 +13803,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13306
13803
|
return Promise.resolve(null);
|
|
13307
13804
|
}
|
|
13308
13805
|
function createFixtureService(definition) {
|
|
13309
|
-
const methods =
|
|
13806
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13310
13807
|
return new Proxy(
|
|
13311
13808
|
{},
|
|
13312
13809
|
{
|
|
@@ -13321,8 +13818,8 @@ function createFixtureService(definition) {
|
|
|
13321
13818
|
);
|
|
13322
13819
|
}
|
|
13323
13820
|
function resolveFixturePath(commandPath) {
|
|
13324
|
-
const parsed =
|
|
13325
|
-
return
|
|
13821
|
+
const parsed = path14.parse(commandPath);
|
|
13822
|
+
return path14.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
13326
13823
|
}
|
|
13327
13824
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
13328
13825
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -13404,7 +13901,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13404
13901
|
};
|
|
13405
13902
|
}
|
|
13406
13903
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13407
|
-
const scenarioServices =
|
|
13904
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13408
13905
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13409
13906
|
...Object.keys(services),
|
|
13410
13907
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13456,8 +13953,8 @@ function validateServices(services) {
|
|
|
13456
13953
|
}
|
|
13457
13954
|
}
|
|
13458
13955
|
}
|
|
13459
|
-
function getNestedValue(target,
|
|
13460
|
-
return
|
|
13956
|
+
function getNestedValue(target, path24) {
|
|
13957
|
+
return path24.reduce(
|
|
13461
13958
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
13462
13959
|
target
|
|
13463
13960
|
);
|
|
@@ -13686,7 +14183,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13686
14183
|
if (itemSchema.kind !== "object") {
|
|
13687
14184
|
return value;
|
|
13688
14185
|
}
|
|
13689
|
-
if (!
|
|
14186
|
+
if (!isPlainObject4(value)) {
|
|
13690
14187
|
errors2.push({
|
|
13691
14188
|
path: displayPath,
|
|
13692
14189
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13721,7 +14218,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13721
14218
|
);
|
|
13722
14219
|
}
|
|
13723
14220
|
case "object": {
|
|
13724
|
-
if (!
|
|
14221
|
+
if (!isPlainObject4(value)) {
|
|
13725
14222
|
errors2.push({
|
|
13726
14223
|
path: displayPath,
|
|
13727
14224
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13752,7 +14249,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13752
14249
|
return result;
|
|
13753
14250
|
}
|
|
13754
14251
|
case "record": {
|
|
13755
|
-
if (!
|
|
14252
|
+
if (!isPlainObject4(value)) {
|
|
13756
14253
|
errors2.push({
|
|
13757
14254
|
path: displayPath,
|
|
13758
14255
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14178,10 +14675,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14178
14675
|
}
|
|
14179
14676
|
}
|
|
14180
14677
|
function isStringRecord(value) {
|
|
14181
|
-
return
|
|
14678
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14182
14679
|
}
|
|
14183
14680
|
function isHttpErrorLike(error3) {
|
|
14184
|
-
if (!
|
|
14681
|
+
if (!isPlainObject4(error3)) {
|
|
14185
14682
|
return false;
|
|
14186
14683
|
}
|
|
14187
14684
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14189,7 +14686,7 @@ function isHttpErrorLike(error3) {
|
|
|
14189
14686
|
}
|
|
14190
14687
|
const request = error3.request;
|
|
14191
14688
|
const response = error3.response;
|
|
14192
|
-
return
|
|
14689
|
+
return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
|
|
14193
14690
|
}
|
|
14194
14691
|
function hasTypedOptionalField(value, field, type2) {
|
|
14195
14692
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14198,7 +14695,7 @@ function isNonEmptyString(value) {
|
|
|
14198
14695
|
return typeof value === "string" && value.trim().length > 0;
|
|
14199
14696
|
}
|
|
14200
14697
|
function isProblemDetailsLike(body) {
|
|
14201
|
-
if (!
|
|
14698
|
+
if (!isPlainObject4(body)) {
|
|
14202
14699
|
return false;
|
|
14203
14700
|
}
|
|
14204
14701
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14219,11 +14716,11 @@ function isProblemDetailsLike(body) {
|
|
|
14219
14716
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14220
14717
|
}
|
|
14221
14718
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14222
|
-
if (!
|
|
14719
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14223
14720
|
return false;
|
|
14224
14721
|
}
|
|
14225
14722
|
return body.errors.every((error3) => {
|
|
14226
|
-
if (!
|
|
14723
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14227
14724
|
return false;
|
|
14228
14725
|
}
|
|
14229
14726
|
if ("path" in error3) {
|
|
@@ -14233,7 +14730,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14233
14730
|
}
|
|
14234
14731
|
}
|
|
14235
14732
|
if ("extensions" in error3) {
|
|
14236
|
-
if (!
|
|
14733
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14237
14734
|
return false;
|
|
14238
14735
|
}
|
|
14239
14736
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14281,23 +14778,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14281
14778
|
}).join("\n\n");
|
|
14282
14779
|
}
|
|
14283
14780
|
function formatHttpErrorBody(body) {
|
|
14284
|
-
|
|
14285
|
-
|
|
14781
|
+
const redactedBody = redactHttpBody(body);
|
|
14782
|
+
if (typeof redactedBody === "string") {
|
|
14783
|
+
return redactedBody;
|
|
14286
14784
|
}
|
|
14287
|
-
if (isProblemDetailsLike(
|
|
14288
|
-
return formatProblemDetailsBody(
|
|
14785
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
14786
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14289
14787
|
}
|
|
14290
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14291
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
14788
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
14789
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14292
14790
|
}
|
|
14293
|
-
const serialized = JSON.stringify(
|
|
14294
|
-
return serialized === void 0 ? String(
|
|
14791
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
14792
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14295
14793
|
}
|
|
14296
14794
|
function indentHttpErrorBlock(value) {
|
|
14297
14795
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14298
14796
|
}
|
|
14299
14797
|
function formatHttpHeaderValue(name, value) {
|
|
14300
|
-
return name
|
|
14798
|
+
return redactHttpHeaderValue(name, value);
|
|
14301
14799
|
}
|
|
14302
14800
|
function formatHttpErrorHeaders(headers) {
|
|
14303
14801
|
return Object.entries(headers).map(
|
|
@@ -14315,7 +14813,11 @@ function renderHttpError(error3, options) {
|
|
|
14315
14813
|
if (detailed) {
|
|
14316
14814
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14317
14815
|
if (error3.request.body !== void 0) {
|
|
14318
|
-
lines.push(
|
|
14816
|
+
lines.push(
|
|
14817
|
+
"Request body:",
|
|
14818
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
14819
|
+
""
|
|
14820
|
+
);
|
|
14319
14821
|
}
|
|
14320
14822
|
}
|
|
14321
14823
|
lines.push(
|
|
@@ -14608,7 +15110,8 @@ function configureCommanderSuggestionOutput(command) {
|
|
|
14608
15110
|
}
|
|
14609
15111
|
async function runCLI(roots, options = {}) {
|
|
14610
15112
|
enableSourceMaps();
|
|
14611
|
-
const
|
|
15113
|
+
const normalizedRoot = normalizeRoots(roots, process.argv);
|
|
15114
|
+
const root = options.approvals === false ? normalizedRoot : mergeApprovalsGroup(normalizedRoot);
|
|
14612
15115
|
await resolveMcpProxies(root, { projectRoot: options.projectRoot });
|
|
14613
15116
|
const casing = options.casing ?? "kebab";
|
|
14614
15117
|
const services = options.services ?? {};
|
|
@@ -14720,7 +15223,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14720
15223
|
}
|
|
14721
15224
|
|
|
14722
15225
|
// src/terminal-pilot.ts
|
|
14723
|
-
import { randomUUID as
|
|
15226
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
14724
15227
|
|
|
14725
15228
|
// src/terminal-session.ts
|
|
14726
15229
|
import { EventEmitter } from "node:events";
|
|
@@ -15922,7 +16425,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
15922
16425
|
}
|
|
15923
16426
|
async newSession(opts) {
|
|
15924
16427
|
const session = new TerminalSession({
|
|
15925
|
-
id:
|
|
16428
|
+
id: randomUUID4(),
|
|
15926
16429
|
command: opts.command,
|
|
15927
16430
|
args: opts.args,
|
|
15928
16431
|
cwd: opts.cwd,
|
|
@@ -16197,7 +16700,7 @@ var getSession = defineCommand({
|
|
|
16197
16700
|
|
|
16198
16701
|
// ../agent-skill-config/src/configs.ts
|
|
16199
16702
|
import os2 from "node:os";
|
|
16200
|
-
import
|
|
16703
|
+
import path15 from "node:path";
|
|
16201
16704
|
|
|
16202
16705
|
// ../agent-defs/src/agents/claude-code.ts
|
|
16203
16706
|
var claudeCodeAgent = {
|
|
@@ -16403,11 +16906,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16403
16906
|
if (!resolvedId) {
|
|
16404
16907
|
return { status: "unknown", input };
|
|
16405
16908
|
}
|
|
16406
|
-
const
|
|
16407
|
-
if (!
|
|
16909
|
+
const config2 = registry[resolvedId];
|
|
16910
|
+
if (!config2) {
|
|
16408
16911
|
return { status: "unsupported", input, id: resolvedId };
|
|
16409
16912
|
}
|
|
16410
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
16913
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16411
16914
|
}
|
|
16412
16915
|
function getAgentConfig(agentId) {
|
|
16413
16916
|
const support = resolveAgentSupport(agentId);
|
|
@@ -16506,7 +17009,7 @@ var templateMutation = {
|
|
|
16506
17009
|
};
|
|
16507
17010
|
|
|
16508
17011
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
16509
|
-
import
|
|
17012
|
+
import path17 from "node:path";
|
|
16510
17013
|
|
|
16511
17014
|
// ../config-mutations/src/formats/json.ts
|
|
16512
17015
|
import * as jsonc from "jsonc-parser";
|
|
@@ -16544,6 +17047,13 @@ function cloneConfigValue(value) {
|
|
|
16544
17047
|
function isConfigObject(value) {
|
|
16545
17048
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16546
17049
|
}
|
|
17050
|
+
function detectIndent(content) {
|
|
17051
|
+
const match = content.match(/^[\t ]+/m);
|
|
17052
|
+
if (match) {
|
|
17053
|
+
return match[0];
|
|
17054
|
+
}
|
|
17055
|
+
return " ";
|
|
17056
|
+
}
|
|
16547
17057
|
function parse3(content) {
|
|
16548
17058
|
if (!content || content.trim() === "") {
|
|
16549
17059
|
return {};
|
|
@@ -16583,6 +17093,9 @@ function merge(base, patch) {
|
|
|
16583
17093
|
}
|
|
16584
17094
|
return result;
|
|
16585
17095
|
}
|
|
17096
|
+
function configValuesEqual(left, right) {
|
|
17097
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
17098
|
+
}
|
|
16586
17099
|
function prune(obj, shape) {
|
|
16587
17100
|
let changed = false;
|
|
16588
17101
|
const result = cloneConfigObject(obj);
|
|
@@ -16619,9 +17132,56 @@ function prune(obj, shape) {
|
|
|
16619
17132
|
}
|
|
16620
17133
|
return { changed, result };
|
|
16621
17134
|
}
|
|
17135
|
+
function modifyAtPath(content, path24, value) {
|
|
17136
|
+
const indent = detectIndent(content);
|
|
17137
|
+
const formattingOptions = {
|
|
17138
|
+
tabSize: indent === " " ? 1 : indent.length,
|
|
17139
|
+
insertSpaces: indent !== " ",
|
|
17140
|
+
eol: "\n"
|
|
17141
|
+
};
|
|
17142
|
+
const edits = jsonc.modify(content, path24, value, { formattingOptions });
|
|
17143
|
+
let result = jsonc.applyEdits(content, edits);
|
|
17144
|
+
if (!result.endsWith("\n")) {
|
|
17145
|
+
result += "\n";
|
|
17146
|
+
}
|
|
17147
|
+
return result;
|
|
17148
|
+
}
|
|
17149
|
+
function removeAtPath(content, path24) {
|
|
17150
|
+
return modifyAtPath(content, path24, void 0);
|
|
17151
|
+
}
|
|
17152
|
+
function serializeUpdate(content, current, next) {
|
|
17153
|
+
let result = content || "{}";
|
|
17154
|
+
result = applyObjectUpdate(result, [], current, next);
|
|
17155
|
+
if (!result.endsWith("\n")) {
|
|
17156
|
+
result += "\n";
|
|
17157
|
+
}
|
|
17158
|
+
return result;
|
|
17159
|
+
}
|
|
17160
|
+
function applyObjectUpdate(content, path24, current, next) {
|
|
17161
|
+
let result = content;
|
|
17162
|
+
for (const key2 of Object.keys(current)) {
|
|
17163
|
+
if (!hasConfigEntry(next, key2)) {
|
|
17164
|
+
result = removeAtPath(result, [...path24, key2]);
|
|
17165
|
+
}
|
|
17166
|
+
}
|
|
17167
|
+
for (const [key2, nextValue] of Object.entries(next)) {
|
|
17168
|
+
const nextPath = [...path24, key2];
|
|
17169
|
+
const hasCurrent = hasConfigEntry(current, key2);
|
|
17170
|
+
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
17171
|
+
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
17172
|
+
result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
|
|
17173
|
+
continue;
|
|
17174
|
+
}
|
|
17175
|
+
if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
|
|
17176
|
+
result = modifyAtPath(result, nextPath, nextValue);
|
|
17177
|
+
}
|
|
17178
|
+
}
|
|
17179
|
+
return result;
|
|
17180
|
+
}
|
|
16622
17181
|
var jsonFormat = {
|
|
16623
17182
|
parse: parse3,
|
|
16624
17183
|
serialize,
|
|
17184
|
+
serializeUpdate,
|
|
16625
17185
|
merge,
|
|
16626
17186
|
prune
|
|
16627
17187
|
};
|
|
@@ -16805,20 +17365,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
16805
17365
|
}
|
|
16806
17366
|
return formatRegistry[formatName];
|
|
16807
17367
|
}
|
|
16808
|
-
function detectFormat(
|
|
16809
|
-
const ext = getExtension(
|
|
17368
|
+
function detectFormat(path24) {
|
|
17369
|
+
const ext = getExtension(path24);
|
|
16810
17370
|
return extensionMap[ext];
|
|
16811
17371
|
}
|
|
16812
|
-
function getExtension(
|
|
16813
|
-
const lastDot =
|
|
17372
|
+
function getExtension(path24) {
|
|
17373
|
+
const lastDot = path24.lastIndexOf(".");
|
|
16814
17374
|
if (lastDot === -1) {
|
|
16815
17375
|
return "";
|
|
16816
17376
|
}
|
|
16817
|
-
return
|
|
17377
|
+
return path24.slice(lastDot).toLowerCase();
|
|
16818
17378
|
}
|
|
16819
17379
|
|
|
16820
17380
|
// ../config-mutations/src/execution/path-utils.ts
|
|
16821
|
-
import
|
|
17381
|
+
import path16 from "node:path";
|
|
16822
17382
|
function expandHome(targetPath, homeDir) {
|
|
16823
17383
|
if (!targetPath?.startsWith("~")) {
|
|
16824
17384
|
return targetPath;
|
|
@@ -16835,7 +17395,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
16835
17395
|
remainder = remainder.slice(1);
|
|
16836
17396
|
}
|
|
16837
17397
|
}
|
|
16838
|
-
return remainder.length === 0 ? homeDir :
|
|
17398
|
+
return remainder.length === 0 ? homeDir : path16.join(homeDir, remainder);
|
|
16839
17399
|
}
|
|
16840
17400
|
function validateHomePath(targetPath) {
|
|
16841
17401
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -16850,21 +17410,21 @@ function validateHomePath(targetPath) {
|
|
|
16850
17410
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
16851
17411
|
validateHomePath(rawPath);
|
|
16852
17412
|
const expanded = expandHome(rawPath, homeDir);
|
|
16853
|
-
const canonicalHome =
|
|
16854
|
-
const canonicalExpanded =
|
|
16855
|
-
const relative =
|
|
16856
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
17413
|
+
const canonicalHome = path16.resolve(homeDir);
|
|
17414
|
+
const canonicalExpanded = path16.resolve(expanded);
|
|
17415
|
+
const relative = path16.relative(canonicalHome, canonicalExpanded);
|
|
17416
|
+
if (relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
|
|
16857
17417
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
16858
17418
|
}
|
|
16859
17419
|
if (!pathMapper) {
|
|
16860
17420
|
return canonicalExpanded;
|
|
16861
17421
|
}
|
|
16862
|
-
const rawDirectory =
|
|
17422
|
+
const rawDirectory = path16.dirname(expanded);
|
|
16863
17423
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
16864
17424
|
targetDirectory: rawDirectory
|
|
16865
17425
|
});
|
|
16866
|
-
const filename =
|
|
16867
|
-
return filename.length === 0 ? mappedDirectory :
|
|
17426
|
+
const filename = path16.basename(expanded);
|
|
17427
|
+
return filename.length === 0 ? mappedDirectory : path16.join(mappedDirectory, filename);
|
|
16868
17428
|
}
|
|
16869
17429
|
|
|
16870
17430
|
// ../config-mutations/src/fs-utils.ts
|
|
@@ -16928,8 +17488,8 @@ function isAlreadyExists(error3) {
|
|
|
16928
17488
|
return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
|
|
16929
17489
|
}
|
|
16930
17490
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
16931
|
-
const boundary =
|
|
16932
|
-
let currentPath =
|
|
17491
|
+
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
17492
|
+
let currentPath = path17.resolve(targetPath);
|
|
16933
17493
|
while (currentPath !== boundary) {
|
|
16934
17494
|
try {
|
|
16935
17495
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -16940,7 +17500,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
16940
17500
|
throw error3;
|
|
16941
17501
|
}
|
|
16942
17502
|
}
|
|
16943
|
-
const parentPath =
|
|
17503
|
+
const parentPath = path17.dirname(currentPath);
|
|
16944
17504
|
if (parentPath === currentPath) {
|
|
16945
17505
|
return;
|
|
16946
17506
|
}
|
|
@@ -17003,7 +17563,7 @@ function pruneKeysByPrefix(table, prefix) {
|
|
|
17003
17563
|
const result = {};
|
|
17004
17564
|
for (const [key2, value] of Object.entries(table)) {
|
|
17005
17565
|
if (!key2.startsWith(prefix)) {
|
|
17006
|
-
result
|
|
17566
|
+
setConfigEntry(result, key2, value);
|
|
17007
17567
|
}
|
|
17008
17568
|
}
|
|
17009
17569
|
return result;
|
|
@@ -17012,28 +17572,43 @@ function isConfigObject4(value) {
|
|
|
17012
17572
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17013
17573
|
}
|
|
17014
17574
|
function mergeWithPruneByPrefix(base, patch, pruneByPrefix) {
|
|
17015
|
-
const result =
|
|
17575
|
+
const result = cloneConfigObject(base);
|
|
17016
17576
|
const prefixMap = pruneByPrefix ?? {};
|
|
17017
17577
|
for (const [key2, value] of Object.entries(patch)) {
|
|
17578
|
+
if (value === void 0) {
|
|
17579
|
+
continue;
|
|
17580
|
+
}
|
|
17018
17581
|
const current = result[key2];
|
|
17019
17582
|
const prefix = prefixMap[key2];
|
|
17020
17583
|
if (isConfigObject4(current) && isConfigObject4(value)) {
|
|
17021
17584
|
if (prefix) {
|
|
17022
17585
|
const pruned = pruneKeysByPrefix(current, prefix);
|
|
17023
|
-
result
|
|
17586
|
+
setConfigEntry(result, key2, mergePrunedConfigObject(pruned, value));
|
|
17024
17587
|
} else {
|
|
17025
|
-
result
|
|
17026
|
-
current,
|
|
17027
|
-
value,
|
|
17028
|
-
prefixMap
|
|
17029
|
-
);
|
|
17588
|
+
setConfigEntry(result, key2, mergeWithPruneByPrefix(current, value, prefixMap));
|
|
17030
17589
|
}
|
|
17031
17590
|
continue;
|
|
17032
17591
|
}
|
|
17033
|
-
result
|
|
17592
|
+
setConfigEntry(result, key2, value);
|
|
17034
17593
|
}
|
|
17035
17594
|
return result;
|
|
17036
17595
|
}
|
|
17596
|
+
function mergePrunedConfigObject(base, patch) {
|
|
17597
|
+
const result = cloneConfigObject(base);
|
|
17598
|
+
for (const [key2, value] of Object.entries(patch)) {
|
|
17599
|
+
if (value === void 0) {
|
|
17600
|
+
continue;
|
|
17601
|
+
}
|
|
17602
|
+
setConfigEntry(result, key2, value);
|
|
17603
|
+
}
|
|
17604
|
+
return result;
|
|
17605
|
+
}
|
|
17606
|
+
function serializeConfigUpdate(format, rawContent, current, next) {
|
|
17607
|
+
if (rawContent !== null && format.serializeUpdate) {
|
|
17608
|
+
return format.serializeUpdate(rawContent, current, next);
|
|
17609
|
+
}
|
|
17610
|
+
return format.serialize(next);
|
|
17611
|
+
}
|
|
17037
17612
|
async function applyMutation(mutation, context, options) {
|
|
17038
17613
|
switch (mutation.kind) {
|
|
17039
17614
|
case "ensureDirectory":
|
|
@@ -17346,6 +17921,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17346
17921
|
}
|
|
17347
17922
|
const format = getConfigFormat(formatName);
|
|
17348
17923
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
17924
|
+
let preserveContent = rawContent;
|
|
17349
17925
|
let current;
|
|
17350
17926
|
try {
|
|
17351
17927
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17354,6 +17930,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17354
17930
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17355
17931
|
}
|
|
17356
17932
|
current = {};
|
|
17933
|
+
preserveContent = null;
|
|
17357
17934
|
}
|
|
17358
17935
|
const value = resolveValue(mutation.value, options);
|
|
17359
17936
|
let merged;
|
|
@@ -17362,7 +17939,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17362
17939
|
} else {
|
|
17363
17940
|
merged = format.merge(current, value);
|
|
17364
17941
|
}
|
|
17365
|
-
const serialized = format
|
|
17942
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, merged);
|
|
17366
17943
|
const changed = serialized !== rawContent;
|
|
17367
17944
|
if (changed && !context.dryRun) {
|
|
17368
17945
|
await writeAtomically2(context, targetPath, serialized);
|
|
@@ -17430,7 +18007,7 @@ async function applyConfigPrune(mutation, context, options) {
|
|
|
17430
18007
|
details
|
|
17431
18008
|
};
|
|
17432
18009
|
}
|
|
17433
|
-
const serialized = format
|
|
18010
|
+
const serialized = serializeConfigUpdate(format, rawContent, current, result);
|
|
17434
18011
|
if (!context.dryRun) {
|
|
17435
18012
|
await writeAtomically2(context, targetPath, serialized);
|
|
17436
18013
|
}
|
|
@@ -17455,6 +18032,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17455
18032
|
}
|
|
17456
18033
|
const format = getConfigFormat(formatName);
|
|
17457
18034
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
18035
|
+
let preserveContent = rawContent;
|
|
17458
18036
|
let current;
|
|
17459
18037
|
try {
|
|
17460
18038
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17463,6 +18041,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17463
18041
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17464
18042
|
}
|
|
17465
18043
|
current = {};
|
|
18044
|
+
preserveContent = null;
|
|
17466
18045
|
}
|
|
17467
18046
|
const { content: transformed, changed } = mutation.transform(current, options);
|
|
17468
18047
|
if (!changed) {
|
|
@@ -17486,7 +18065,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17486
18065
|
details
|
|
17487
18066
|
};
|
|
17488
18067
|
}
|
|
17489
|
-
const serialized = format
|
|
18068
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
17490
18069
|
if (!context.dryRun) {
|
|
17491
18070
|
await writeAtomically2(context, targetPath, serialized);
|
|
17492
18071
|
}
|
|
@@ -17628,7 +18207,7 @@ async function executeMutation(mutation, context, options) {
|
|
|
17628
18207
|
|
|
17629
18208
|
// ../agent-skill-config/src/templates.ts
|
|
17630
18209
|
import { readFile as readFile5, stat } from "node:fs/promises";
|
|
17631
|
-
import
|
|
18210
|
+
import path18 from "node:path";
|
|
17632
18211
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17633
18212
|
|
|
17634
18213
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -17663,14 +18242,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17663
18242
|
throw new UnsupportedAgentError(agentId);
|
|
17664
18243
|
}
|
|
17665
18244
|
const scope = options.scope ?? "local";
|
|
17666
|
-
const
|
|
18245
|
+
const config2 = support.config;
|
|
17667
18246
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17668
18247
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17669
18248
|
}
|
|
17670
|
-
const skillDir = scope === "global" ?
|
|
18249
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17671
18250
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17672
18251
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17673
|
-
const displayPath = `${scope === "global" ?
|
|
18252
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17674
18253
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17675
18254
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17676
18255
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -17705,21 +18284,21 @@ async function installSkill(agentId, skill, options) {
|
|
|
17705
18284
|
|
|
17706
18285
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
17707
18286
|
import { statSync as statSync2 } from "node:fs";
|
|
17708
|
-
import
|
|
18287
|
+
import path19 from "node:path";
|
|
17709
18288
|
|
|
17710
18289
|
// ../agent-skill-config/src/git-exclude.ts
|
|
17711
18290
|
import { execFileSync } from "node:child_process";
|
|
17712
18291
|
import * as fs2 from "node:fs";
|
|
17713
|
-
import
|
|
18292
|
+
import path20 from "node:path";
|
|
17714
18293
|
|
|
17715
18294
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
17716
18295
|
import * as fs3 from "node:fs";
|
|
17717
|
-
import { createHash as createHash4, randomUUID as
|
|
17718
|
-
import
|
|
18296
|
+
import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
|
|
18297
|
+
import path21 from "node:path";
|
|
17719
18298
|
|
|
17720
18299
|
// src/commands/installer.ts
|
|
17721
18300
|
import os3 from "node:os";
|
|
17722
|
-
import
|
|
18301
|
+
import path22 from "node:path";
|
|
17723
18302
|
import * as nodeFs2 from "node:fs/promises";
|
|
17724
18303
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
17725
18304
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
@@ -17786,28 +18365,28 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
17786
18365
|
return homeDir;
|
|
17787
18366
|
}
|
|
17788
18367
|
if (targetPath.startsWith("~/")) {
|
|
17789
|
-
return
|
|
18368
|
+
return path22.join(homeDir, targetPath.slice(2));
|
|
17790
18369
|
}
|
|
17791
18370
|
return targetPath;
|
|
17792
18371
|
}
|
|
17793
18372
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
17794
|
-
const
|
|
17795
|
-
if (!
|
|
18373
|
+
const config2 = getAgentConfig(agent);
|
|
18374
|
+
if (!config2) {
|
|
17796
18375
|
throwUnsupportedAgent(agent);
|
|
17797
18376
|
}
|
|
17798
18377
|
return {
|
|
17799
|
-
displayPath:
|
|
17800
|
-
scope === "global" ?
|
|
18378
|
+
displayPath: path22.join(
|
|
18379
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
17801
18380
|
TERMINAL_PILOT_SKILL_NAME
|
|
17802
18381
|
),
|
|
17803
|
-
fullPath:
|
|
17804
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18382
|
+
fullPath: path22.join(
|
|
18383
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
17805
18384
|
TERMINAL_PILOT_SKILL_NAME
|
|
17806
18385
|
)
|
|
17807
18386
|
};
|
|
17808
18387
|
}
|
|
17809
18388
|
async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
17810
|
-
const rootPath =
|
|
18389
|
+
const rootPath = path22.parse(targetPath).root;
|
|
17811
18390
|
let currentPath = targetPath;
|
|
17812
18391
|
while (currentPath !== rootPath) {
|
|
17813
18392
|
try {
|
|
@@ -17819,7 +18398,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
17819
18398
|
throw error3;
|
|
17820
18399
|
}
|
|
17821
18400
|
}
|
|
17822
|
-
currentPath =
|
|
18401
|
+
currentPath = path22.dirname(currentPath);
|
|
17823
18402
|
}
|
|
17824
18403
|
}
|
|
17825
18404
|
|
|
@@ -17958,7 +18537,7 @@ var resize = defineCommand({
|
|
|
17958
18537
|
});
|
|
17959
18538
|
|
|
17960
18539
|
// ../terminal-png/src/index.ts
|
|
17961
|
-
import { randomUUID as
|
|
18540
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17962
18541
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
17963
18542
|
|
|
17964
18543
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -18898,7 +19477,7 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
18898
19477
|
});
|
|
18899
19478
|
const png = renderPng(svg);
|
|
18900
19479
|
if (options.output) {
|
|
18901
|
-
const temporaryPath = `${options.output}.${
|
|
19480
|
+
const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
|
|
18902
19481
|
try {
|
|
18903
19482
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
18904
19483
|
await rename4(temporaryPath, options.output);
|
|
@@ -18975,7 +19554,7 @@ var type = defineCommand({
|
|
|
18975
19554
|
});
|
|
18976
19555
|
|
|
18977
19556
|
// src/commands/uninstall.ts
|
|
18978
|
-
import { randomUUID as
|
|
19557
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18979
19558
|
var params14 = S.Object({
|
|
18980
19559
|
agent: S.Enum(installableAgents, {
|
|
18981
19560
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19011,7 +19590,7 @@ var uninstall = defineCommand({
|
|
|
19011
19590
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19012
19591
|
continue;
|
|
19013
19592
|
}
|
|
19014
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19593
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
|
|
19015
19594
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19016
19595
|
staged.push({ ...skill, stagingPath });
|
|
19017
19596
|
}
|
|
@@ -19118,6 +19697,7 @@ function createTerminalPilotGroup() {
|
|
|
19118
19697
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19119
19698
|
|
|
19120
19699
|
// src/cli.ts
|
|
19700
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19121
19701
|
function normalizeArgv(argv) {
|
|
19122
19702
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19123
19703
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19141,8 +19721,8 @@ async function isDirectExecution(argv) {
|
|
|
19141
19721
|
try {
|
|
19142
19722
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19143
19723
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19144
|
-
|
|
19145
|
-
|
|
19724
|
+
realpath3(path23.resolve(entryPoint)),
|
|
19725
|
+
realpath3(modulePath)
|
|
19146
19726
|
]);
|
|
19147
19727
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19148
19728
|
} catch {
|