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/qa-cli.js
CHANGED
|
@@ -8,7 +8,7 @@ var __export = (target, all) => {
|
|
|
8
8
|
import assert from "node:assert/strict";
|
|
9
9
|
import { rm as rm2 } from "node:fs/promises";
|
|
10
10
|
import os4 from "node:os";
|
|
11
|
-
import
|
|
11
|
+
import path24 from "node:path";
|
|
12
12
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
13
13
|
|
|
14
14
|
// src/ansi.ts
|
|
@@ -85,13 +85,13 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// src/cli.ts
|
|
88
|
-
import { realpath as
|
|
89
|
-
import
|
|
88
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
89
|
+
import path23 from "node:path";
|
|
90
90
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
91
91
|
|
|
92
92
|
// ../toolcraft/src/cli.ts
|
|
93
93
|
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
|
|
94
|
-
import
|
|
94
|
+
import path14 from "node:path";
|
|
95
95
|
import {
|
|
96
96
|
Command as CommanderCommand,
|
|
97
97
|
CommanderError as CommanderError2,
|
|
@@ -99,7 +99,7 @@ import {
|
|
|
99
99
|
Option
|
|
100
100
|
} from "commander";
|
|
101
101
|
|
|
102
|
-
// ../design
|
|
102
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
103
103
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
104
104
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
105
105
|
return true;
|
|
@@ -113,7 +113,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
113
113
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
// ../design
|
|
116
|
+
// ../toolcraft-design/src/components/color.ts
|
|
117
117
|
var reset = "\x1B[0m";
|
|
118
118
|
var ansiStyles = {
|
|
119
119
|
reset: { open: reset },
|
|
@@ -215,41 +215,135 @@ function createColor(styles = []) {
|
|
|
215
215
|
}
|
|
216
216
|
var color = createColor();
|
|
217
217
|
|
|
218
|
-
// ../design
|
|
219
|
-
var
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
number: (text5) => color.cyanBright(text5),
|
|
224
|
-
intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
|
|
225
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
226
|
-
errorSymbol: color.red("\u25A0"),
|
|
227
|
-
accent: (text5) => color.cyan(text5),
|
|
228
|
-
muted: (text5) => color.dim(text5),
|
|
229
|
-
success: (text5) => color.green(text5),
|
|
230
|
-
warning: (text5) => color.yellow(text5),
|
|
231
|
-
error: (text5) => color.red(text5),
|
|
232
|
-
info: (text5) => color.magenta(text5),
|
|
233
|
-
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
218
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
219
|
+
var brands = {
|
|
220
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
221
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
222
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
234
223
|
};
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
|
|
241
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
242
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
243
|
-
accent: (text5) => color.hex("#006699").bold(text5),
|
|
244
|
-
muted: (text5) => color.hex("#666666")(text5),
|
|
245
|
-
success: (text5) => color.hex("#008800")(text5),
|
|
246
|
-
warning: (text5) => color.hex("#cc6600")(text5),
|
|
247
|
-
error: (text5) => color.hex("#cc0000")(text5),
|
|
248
|
-
info: (text5) => color.hex("#a200ff")(text5),
|
|
249
|
-
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
224
|
+
|
|
225
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
226
|
+
var defaults = {
|
|
227
|
+
brand: "purple",
|
|
228
|
+
label: "Poe"
|
|
250
229
|
};
|
|
230
|
+
var config = { ...defaults };
|
|
231
|
+
var revision = 0;
|
|
232
|
+
var brandConfigured = false;
|
|
233
|
+
function configureTheme(patch) {
|
|
234
|
+
if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
|
|
235
|
+
throw new Error(`Unknown brand: ${patch.brand}`);
|
|
236
|
+
}
|
|
237
|
+
config = {
|
|
238
|
+
brand: patch.brand ?? config.brand,
|
|
239
|
+
label: patch.label ?? config.label
|
|
240
|
+
};
|
|
241
|
+
if (patch.brand !== void 0) {
|
|
242
|
+
brandConfigured = true;
|
|
243
|
+
}
|
|
244
|
+
revision += 1;
|
|
245
|
+
}
|
|
246
|
+
function getThemeConfig() {
|
|
247
|
+
return { ...config };
|
|
248
|
+
}
|
|
249
|
+
function getThemeRevision() {
|
|
250
|
+
return revision;
|
|
251
|
+
}
|
|
252
|
+
function isThemeBrandConfigured() {
|
|
253
|
+
return brandConfigured;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
257
|
+
var brand = brands.purple.primary;
|
|
258
|
+
function withStyles(palette, styles) {
|
|
259
|
+
return Object.defineProperty(palette, "styles", {
|
|
260
|
+
value: styles,
|
|
261
|
+
enumerable: false
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
function brandColor(activeBrand, purple) {
|
|
265
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
266
|
+
}
|
|
267
|
+
function brandBackground(activeBrand, purple) {
|
|
268
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
269
|
+
}
|
|
270
|
+
function createPalette(activeBrand, mode) {
|
|
271
|
+
const isPurple = activeBrand.name === "purple";
|
|
272
|
+
if (mode === "light") {
|
|
273
|
+
const active2 = color.hex(activeBrand.primary);
|
|
274
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
275
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
276
|
+
return withStyles(
|
|
277
|
+
{
|
|
278
|
+
header: (text5) => active2.bold(text5),
|
|
279
|
+
divider: (text5) => color.hex("#666666")(text5),
|
|
280
|
+
prompt: (text5) => prompt2.bold(text5),
|
|
281
|
+
number: (text5) => number2.bold(text5),
|
|
282
|
+
intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
|
|
283
|
+
get resolvedSymbol() {
|
|
284
|
+
return active2("\u25C7");
|
|
285
|
+
},
|
|
286
|
+
get errorSymbol() {
|
|
287
|
+
return color.hex("#cc0000")("\u25A0");
|
|
288
|
+
},
|
|
289
|
+
accent: (text5) => prompt2.bold(text5),
|
|
290
|
+
muted: (text5) => color.hex("#666666")(text5),
|
|
291
|
+
success: (text5) => color.hex("#008800")(text5),
|
|
292
|
+
warning: (text5) => color.hex("#cc6600")(text5),
|
|
293
|
+
error: (text5) => color.hex("#cc0000")(text5),
|
|
294
|
+
info: (text5) => active2(text5),
|
|
295
|
+
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
299
|
+
muted: { fg: "#666666" },
|
|
300
|
+
success: { fg: "#008800" },
|
|
301
|
+
warning: { fg: "#cc6600" },
|
|
302
|
+
error: { fg: "#cc0000" },
|
|
303
|
+
info: { fg: activeBrand.primary }
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
308
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
309
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
310
|
+
const prompt = isPurple ? color.cyan : active;
|
|
311
|
+
const number = isPurple ? color.cyanBright : active;
|
|
312
|
+
return withStyles(
|
|
313
|
+
{
|
|
314
|
+
header: (text5) => activeBright.bold(text5),
|
|
315
|
+
divider: (text5) => color.dim(text5),
|
|
316
|
+
prompt: (text5) => prompt(text5),
|
|
317
|
+
number: (text5) => number(text5),
|
|
318
|
+
intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
|
|
319
|
+
get resolvedSymbol() {
|
|
320
|
+
return active("\u25C7");
|
|
321
|
+
},
|
|
322
|
+
get errorSymbol() {
|
|
323
|
+
return color.red("\u25A0");
|
|
324
|
+
},
|
|
325
|
+
accent: (text5) => prompt(text5),
|
|
326
|
+
muted: (text5) => color.dim(text5),
|
|
327
|
+
success: (text5) => color.green(text5),
|
|
328
|
+
warning: (text5) => color.yellow(text5),
|
|
329
|
+
error: (text5) => color.red(text5),
|
|
330
|
+
info: (text5) => active(text5),
|
|
331
|
+
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
335
|
+
muted: { dim: true },
|
|
336
|
+
success: { fg: "green" },
|
|
337
|
+
warning: { fg: "yellow" },
|
|
338
|
+
error: { fg: "red" },
|
|
339
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
var dark = createPalette(brands.purple, "dark");
|
|
344
|
+
var light = createPalette(brands.purple, "light");
|
|
251
345
|
|
|
252
|
-
// ../design
|
|
346
|
+
// ../toolcraft-design/src/tokens/typography.ts
|
|
253
347
|
var typography = {
|
|
254
348
|
bold: (text5) => color.bold(text5),
|
|
255
349
|
dim: (text5) => color.dim(text5),
|
|
@@ -258,14 +352,14 @@ var typography = {
|
|
|
258
352
|
strikethrough: (text5) => color.strikethrough(text5)
|
|
259
353
|
};
|
|
260
354
|
|
|
261
|
-
// ../design
|
|
355
|
+
// ../toolcraft-design/src/tokens/widths.ts
|
|
262
356
|
var widths = {
|
|
263
357
|
header: 60,
|
|
264
358
|
helpColumn: 24,
|
|
265
359
|
maxLine: 80
|
|
266
360
|
};
|
|
267
361
|
|
|
268
|
-
// ../design
|
|
362
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
269
363
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
270
364
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
271
365
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -286,7 +380,7 @@ function resetOutputFormatCache() {
|
|
|
286
380
|
cached = void 0;
|
|
287
381
|
}
|
|
288
382
|
|
|
289
|
-
// ../design
|
|
383
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
290
384
|
function detectThemeFromEnv(env) {
|
|
291
385
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
292
386
|
if (typeof apple === "string") {
|
|
@@ -323,17 +417,30 @@ function resolveThemeName(env = process.env) {
|
|
|
323
417
|
}
|
|
324
418
|
return "dark";
|
|
325
419
|
}
|
|
326
|
-
var
|
|
420
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
421
|
+
var cachedRevision = -1;
|
|
327
422
|
function getTheme(env) {
|
|
423
|
+
const themeName = resolveThemeName(env);
|
|
424
|
+
const config2 = getThemeConfig();
|
|
425
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
426
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
427
|
+
const revision2 = getThemeRevision();
|
|
428
|
+
if (revision2 !== cachedRevision) {
|
|
429
|
+
themeCache.clear();
|
|
430
|
+
cachedRevision = revision2;
|
|
431
|
+
}
|
|
432
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
433
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
328
434
|
if (cachedTheme) {
|
|
329
435
|
return cachedTheme;
|
|
330
436
|
}
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
437
|
+
const activeBrand = brands[activeBrandName];
|
|
438
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
439
|
+
themeCache.set(cacheKey, theme);
|
|
440
|
+
return theme;
|
|
334
441
|
}
|
|
335
442
|
|
|
336
|
-
// ../design
|
|
443
|
+
// ../toolcraft-design/src/components/text.ts
|
|
337
444
|
function renderMarkdownInline(content) {
|
|
338
445
|
return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
339
446
|
}
|
|
@@ -449,7 +556,7 @@ var text = {
|
|
|
449
556
|
}
|
|
450
557
|
};
|
|
451
558
|
|
|
452
|
-
// ../design
|
|
559
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
453
560
|
var symbols = {
|
|
454
561
|
get info() {
|
|
455
562
|
const format = resolveOutputFormat();
|
|
@@ -503,12 +610,12 @@ var symbols = {
|
|
|
503
610
|
}
|
|
504
611
|
};
|
|
505
612
|
|
|
506
|
-
// ../design
|
|
613
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
507
614
|
function stripAnsi2(value) {
|
|
508
615
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
509
616
|
}
|
|
510
617
|
|
|
511
|
-
// ../design
|
|
618
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
512
619
|
function renderMarkdownInline2(value) {
|
|
513
620
|
return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
514
621
|
}
|
|
@@ -635,7 +742,7 @@ var log = {
|
|
|
635
742
|
error
|
|
636
743
|
};
|
|
637
744
|
|
|
638
|
-
// ../design
|
|
745
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
639
746
|
function createLogger(emitter) {
|
|
640
747
|
const emit = (level, message2) => {
|
|
641
748
|
if (emitter) {
|
|
@@ -696,7 +803,7 @@ function createLogger(emitter) {
|
|
|
696
803
|
}
|
|
697
804
|
var logger = createLogger();
|
|
698
805
|
|
|
699
|
-
// ../design
|
|
806
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
700
807
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
701
808
|
function normalizeInline(value) {
|
|
702
809
|
return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
@@ -872,7 +979,7 @@ function formatOptionList(options) {
|
|
|
872
979
|
});
|
|
873
980
|
}
|
|
874
981
|
|
|
875
|
-
// ../design
|
|
982
|
+
// ../toolcraft-design/src/components/help-formatter-plain.ts
|
|
876
983
|
var help_formatter_plain_exports = {};
|
|
877
984
|
__export(help_formatter_plain_exports, {
|
|
878
985
|
formatColumns: () => formatColumns2,
|
|
@@ -1009,7 +1116,7 @@ function formatOptionList2(options) {
|
|
|
1009
1116
|
});
|
|
1010
1117
|
}
|
|
1011
1118
|
|
|
1012
|
-
// ../design
|
|
1119
|
+
// ../toolcraft-design/src/components/table.ts
|
|
1013
1120
|
var reset2 = "\x1B[0m";
|
|
1014
1121
|
var ellipsis = "\u2026";
|
|
1015
1122
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -1293,7 +1400,7 @@ function renderTable(options) {
|
|
|
1293
1400
|
}
|
|
1294
1401
|
}
|
|
1295
1402
|
|
|
1296
|
-
// ../design
|
|
1403
|
+
// ../toolcraft-design/src/components/detail-card.ts
|
|
1297
1404
|
function wrap(value, width) {
|
|
1298
1405
|
const lines = [];
|
|
1299
1406
|
for (const paragraph of value.split("\n")) {
|
|
@@ -1356,7 +1463,8 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1356
1463
|
return blocks.join("\n\n");
|
|
1357
1464
|
}
|
|
1358
1465
|
|
|
1359
|
-
// ../design
|
|
1466
|
+
// ../toolcraft-design/src/components/template.ts
|
|
1467
|
+
var MAX_PARTIAL_DEPTH = 100;
|
|
1360
1468
|
var HTML_ESCAPE = {
|
|
1361
1469
|
"&": "&",
|
|
1362
1470
|
"<": "<",
|
|
@@ -1368,14 +1476,27 @@ var HTML_ESCAPE = {
|
|
|
1368
1476
|
"=": "="
|
|
1369
1477
|
};
|
|
1370
1478
|
function renderTemplate(template, view, options = {}) {
|
|
1371
|
-
const prepared = options.yield === void 0 ? template : template.split("{{yield}}").join(options.yield);
|
|
1479
|
+
const prepared = options.yield === void 0 ? template : resolveTemplatePartials(template, options.partials ?? {}).split("{{yield}}").join(options.yield);
|
|
1372
1480
|
const tokens = parseTemplate(prepared);
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1481
|
+
validatePartialReferences(tokens, options.partials ?? {}, []);
|
|
1482
|
+
if (options.validate === true) {
|
|
1483
|
+
const expanded = resolveTemplatePartials(prepared, options.partials ?? {});
|
|
1484
|
+
validateVariables(parseTemplate(expanded), { view });
|
|
1485
|
+
}
|
|
1486
|
+
const state = {
|
|
1487
|
+
escape: options.escape === "none" ? String : escapeHtml,
|
|
1488
|
+
partials: options.partials ?? {},
|
|
1489
|
+
partialStack: [],
|
|
1490
|
+
preserveMissing: options.yield !== void 0 && options.escape === "none",
|
|
1491
|
+
validate: options.validate === true
|
|
1492
|
+
};
|
|
1493
|
+
return renderTokens(tokens, { view }, prepared, state);
|
|
1494
|
+
}
|
|
1495
|
+
function resolveTemplatePartials(template, partials) {
|
|
1496
|
+
return expandTemplatePartials(template, partials, []);
|
|
1376
1497
|
}
|
|
1377
|
-
function renderTemplateInContext(template, context,
|
|
1378
|
-
return renderTokens(parseTemplate(template), context, template,
|
|
1498
|
+
function renderTemplateInContext(template, context, state) {
|
|
1499
|
+
return renderTokens(parseTemplate(template), context, template, state);
|
|
1379
1500
|
}
|
|
1380
1501
|
function parseTemplate(template) {
|
|
1381
1502
|
const root = [];
|
|
@@ -1398,9 +1519,6 @@ function parseTemplate(template) {
|
|
|
1398
1519
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1399
1520
|
continue;
|
|
1400
1521
|
}
|
|
1401
|
-
if (parsed.kind === "partial") {
|
|
1402
|
-
throw new Error(`Partials are not supported: "${parsed.name}"`);
|
|
1403
|
-
}
|
|
1404
1522
|
if (parsed.kind === "delimiter") {
|
|
1405
1523
|
throw new Error("Custom delimiters are not supported");
|
|
1406
1524
|
}
|
|
@@ -1418,6 +1536,15 @@ function parseTemplate(template) {
|
|
|
1418
1536
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1419
1537
|
continue;
|
|
1420
1538
|
}
|
|
1539
|
+
if (parsed.kind === "partial") {
|
|
1540
|
+
tokens.push({
|
|
1541
|
+
type: "partial",
|
|
1542
|
+
name: parsed.name,
|
|
1543
|
+
indent: standalone === void 0 ? "" : template.slice(standalone.lineStart, open)
|
|
1544
|
+
});
|
|
1545
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1546
|
+
continue;
|
|
1547
|
+
}
|
|
1421
1548
|
if (parsed.kind === "close") {
|
|
1422
1549
|
const frame2 = stack.pop();
|
|
1423
1550
|
if (frame2 === void 0) {
|
|
@@ -1488,7 +1615,7 @@ function getStandalone(template, tagStart, tagEnd, kind) {
|
|
|
1488
1615
|
}
|
|
1489
1616
|
return void 0;
|
|
1490
1617
|
}
|
|
1491
|
-
function renderTokens(tokens, context, template,
|
|
1618
|
+
function renderTokens(tokens, context, template, state) {
|
|
1492
1619
|
let output = "";
|
|
1493
1620
|
for (const token of tokens) {
|
|
1494
1621
|
switch (token.type) {
|
|
@@ -1497,32 +1624,62 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1497
1624
|
continue;
|
|
1498
1625
|
case "name":
|
|
1499
1626
|
case "unescaped": {
|
|
1500
|
-
const
|
|
1501
|
-
if (value == null) {
|
|
1502
|
-
if (
|
|
1627
|
+
const result = lookup(context, token.name);
|
|
1628
|
+
if (!result.hit || result.value == null) {
|
|
1629
|
+
if (state.validate) {
|
|
1630
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1631
|
+
}
|
|
1632
|
+
if (state.preserveMissing) {
|
|
1503
1633
|
output += token.raw;
|
|
1504
1634
|
}
|
|
1505
1635
|
continue;
|
|
1506
1636
|
}
|
|
1507
|
-
const rendered = String(value);
|
|
1508
|
-
output += token.type === "name" ? escape(rendered) : rendered;
|
|
1637
|
+
const rendered = String(result.value);
|
|
1638
|
+
output += token.type === "name" ? state.escape(rendered) : rendered;
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
case "partial": {
|
|
1642
|
+
if (!Object.hasOwn(state.partials, token.name)) {
|
|
1643
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1644
|
+
}
|
|
1645
|
+
if (state.partialStack.includes(token.name)) {
|
|
1646
|
+
throw new Error(
|
|
1647
|
+
`Circular partial reference detected: ${[...state.partialStack, token.name].join(" -> ")}.`
|
|
1648
|
+
);
|
|
1649
|
+
}
|
|
1650
|
+
if (state.partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1651
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1652
|
+
}
|
|
1653
|
+
const partial = indentPartial(state.partials[token.name], token.indent);
|
|
1654
|
+
output += renderTokens(parseTemplate(partial), context, partial, {
|
|
1655
|
+
...state,
|
|
1656
|
+
partialStack: [...state.partialStack, token.name]
|
|
1657
|
+
});
|
|
1509
1658
|
continue;
|
|
1510
1659
|
}
|
|
1511
1660
|
case "inverted": {
|
|
1512
|
-
const
|
|
1661
|
+
const result = lookup(context, token.name);
|
|
1662
|
+
if (!result.hit && state.validate) {
|
|
1663
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1664
|
+
}
|
|
1665
|
+
const value = result.value;
|
|
1513
1666
|
if (!value || Array.isArray(value) && value.length === 0) {
|
|
1514
|
-
output += renderTokens(token.children, context, template,
|
|
1667
|
+
output += renderTokens(token.children, context, template, state);
|
|
1515
1668
|
}
|
|
1516
1669
|
continue;
|
|
1517
1670
|
}
|
|
1518
1671
|
case "section": {
|
|
1519
|
-
const
|
|
1672
|
+
const result = lookup(context, token.name);
|
|
1673
|
+
if (!result.hit && state.validate) {
|
|
1674
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1675
|
+
}
|
|
1676
|
+
const value = result.value;
|
|
1520
1677
|
if (!value) {
|
|
1521
1678
|
continue;
|
|
1522
1679
|
}
|
|
1523
1680
|
if (Array.isArray(value)) {
|
|
1524
1681
|
for (const item of value) {
|
|
1525
|
-
output += renderTokens(token.children, pushContext(context, item), template,
|
|
1682
|
+
output += renderTokens(token.children, pushContext(context, item), template, state);
|
|
1526
1683
|
}
|
|
1527
1684
|
continue;
|
|
1528
1685
|
}
|
|
@@ -1531,7 +1688,7 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1531
1688
|
const rendered = value.call(
|
|
1532
1689
|
context.view,
|
|
1533
1690
|
raw,
|
|
1534
|
-
(nextTemplate) => renderTemplateInContext(nextTemplate, context,
|
|
1691
|
+
(nextTemplate) => renderTemplateInContext(nextTemplate, context, state)
|
|
1535
1692
|
);
|
|
1536
1693
|
if (rendered != null) {
|
|
1537
1694
|
output += String(rendered);
|
|
@@ -1539,10 +1696,10 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1539
1696
|
continue;
|
|
1540
1697
|
}
|
|
1541
1698
|
if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
1542
|
-
output += renderTokens(token.children, pushContext(context, value), template,
|
|
1699
|
+
output += renderTokens(token.children, pushContext(context, value), template, state);
|
|
1543
1700
|
continue;
|
|
1544
1701
|
}
|
|
1545
|
-
output += renderTokens(token.children, context, template,
|
|
1702
|
+
output += renderTokens(token.children, context, template, state);
|
|
1546
1703
|
}
|
|
1547
1704
|
}
|
|
1548
1705
|
}
|
|
@@ -1550,17 +1707,115 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1550
1707
|
}
|
|
1551
1708
|
function lookup(context, name) {
|
|
1552
1709
|
if (name === ".") {
|
|
1553
|
-
return callLambda(context.view, context.view);
|
|
1710
|
+
return { hit: true, value: callLambda(context.view, context.view) };
|
|
1554
1711
|
}
|
|
1555
1712
|
let cursor = context;
|
|
1556
1713
|
while (cursor !== void 0) {
|
|
1557
1714
|
const result = name.includes(".") ? lookupDotted(cursor.view, name) : lookupName(cursor.view, name);
|
|
1558
1715
|
if (result.hit) {
|
|
1559
|
-
return callLambda(result.value, cursor.view);
|
|
1716
|
+
return { hit: true, value: callLambda(result.value, cursor.view) };
|
|
1560
1717
|
}
|
|
1561
1718
|
cursor = cursor.parent;
|
|
1562
1719
|
}
|
|
1563
|
-
return void 0;
|
|
1720
|
+
return { hit: false, value: void 0 };
|
|
1721
|
+
}
|
|
1722
|
+
function validateVariables(tokens, context) {
|
|
1723
|
+
for (const token of tokens) {
|
|
1724
|
+
if (token.type === "text" || token.type === "partial") {
|
|
1725
|
+
continue;
|
|
1726
|
+
}
|
|
1727
|
+
if (token.type === "name" || token.type === "unescaped") {
|
|
1728
|
+
if (!lookup(context, token.name).hit) {
|
|
1729
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1730
|
+
}
|
|
1731
|
+
continue;
|
|
1732
|
+
}
|
|
1733
|
+
if (token.type !== "section" && token.type !== "inverted") {
|
|
1734
|
+
continue;
|
|
1735
|
+
}
|
|
1736
|
+
const result = lookup(context, token.name);
|
|
1737
|
+
if (!result.hit) {
|
|
1738
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1739
|
+
}
|
|
1740
|
+
if (Array.isArray(result.value) && result.value.length > 0) {
|
|
1741
|
+
for (const item of result.value) {
|
|
1742
|
+
validateVariables(token.children, pushContext(context, item));
|
|
1743
|
+
}
|
|
1744
|
+
continue;
|
|
1745
|
+
}
|
|
1746
|
+
if (typeof result.value === "object" && result.value !== null || typeof result.value === "string" || typeof result.value === "number") {
|
|
1747
|
+
validateVariables(token.children, pushContext(context, result.value));
|
|
1748
|
+
continue;
|
|
1749
|
+
}
|
|
1750
|
+
validateVariables(token.children, context);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
function validatePartialReferences(tokens, partials, partialStack) {
|
|
1754
|
+
for (const token of tokens) {
|
|
1755
|
+
if (token.type === "section" || token.type === "inverted") {
|
|
1756
|
+
validatePartialReferences(token.children, partials, partialStack);
|
|
1757
|
+
continue;
|
|
1758
|
+
}
|
|
1759
|
+
if (token.type !== "partial") {
|
|
1760
|
+
continue;
|
|
1761
|
+
}
|
|
1762
|
+
if (!Object.hasOwn(partials, token.name)) {
|
|
1763
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1764
|
+
}
|
|
1765
|
+
if (partialStack.includes(token.name)) {
|
|
1766
|
+
throw new Error(
|
|
1767
|
+
`Circular partial reference detected: ${[...partialStack, token.name].join(" -> ")}.`
|
|
1768
|
+
);
|
|
1769
|
+
}
|
|
1770
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1771
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1772
|
+
}
|
|
1773
|
+
validatePartialReferences(parseTemplate(partials[token.name]), partials, [
|
|
1774
|
+
...partialStack,
|
|
1775
|
+
token.name
|
|
1776
|
+
]);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
function indentPartial(partial, indent) {
|
|
1780
|
+
if (indent === "") {
|
|
1781
|
+
return partial;
|
|
1782
|
+
}
|
|
1783
|
+
return partial.split("\n").map((line) => line === "" ? "" : `${indent}${line}`).join("\n");
|
|
1784
|
+
}
|
|
1785
|
+
function expandTemplatePartials(template, partials, partialStack) {
|
|
1786
|
+
let output = "";
|
|
1787
|
+
let index = 0;
|
|
1788
|
+
while (index < template.length) {
|
|
1789
|
+
const open = template.indexOf("{{", index);
|
|
1790
|
+
if (open === -1) {
|
|
1791
|
+
output += template.slice(index);
|
|
1792
|
+
break;
|
|
1793
|
+
}
|
|
1794
|
+
const parsed = parseTag(template, open);
|
|
1795
|
+
if (parsed.kind !== "partial") {
|
|
1796
|
+
output += template.slice(index, parsed.end);
|
|
1797
|
+
index = parsed.end;
|
|
1798
|
+
continue;
|
|
1799
|
+
}
|
|
1800
|
+
if (!Object.hasOwn(partials, parsed.name)) {
|
|
1801
|
+
throw new Error(`Partial "${parsed.name}" not found.`);
|
|
1802
|
+
}
|
|
1803
|
+
if (partialStack.includes(parsed.name)) {
|
|
1804
|
+
throw new Error(
|
|
1805
|
+
`Circular partial reference detected: ${[...partialStack, parsed.name].join(" -> ")}.`
|
|
1806
|
+
);
|
|
1807
|
+
}
|
|
1808
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1809
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1810
|
+
}
|
|
1811
|
+
const standalone = getStandalone(template, open, parsed.end, parsed.kind);
|
|
1812
|
+
const beforePartial = standalone === void 0 ? template.slice(index, open) : template.slice(index, standalone.lineStart);
|
|
1813
|
+
const indent = standalone === void 0 ? "" : template.slice(standalone.lineStart, open);
|
|
1814
|
+
const partial = indentPartial(partials[parsed.name], indent);
|
|
1815
|
+
output += beforePartial + expandTemplatePartials(partial, partials, [...partialStack, parsed.name]);
|
|
1816
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1817
|
+
}
|
|
1818
|
+
return output;
|
|
1564
1819
|
}
|
|
1565
1820
|
function lookupName(view, name) {
|
|
1566
1821
|
if (!isPropertyContainer(view) || !hasProperty(view, name)) {
|
|
@@ -1620,22 +1875,22 @@ function hasProperty(value, key2) {
|
|
|
1620
1875
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1621
1876
|
}
|
|
1622
1877
|
|
|
1623
|
-
// ../design
|
|
1878
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1624
1879
|
import { spawn } from "node:child_process";
|
|
1625
1880
|
import process2 from "node:process";
|
|
1626
1881
|
|
|
1627
|
-
// ../design
|
|
1882
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1628
1883
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1629
1884
|
var storage = new AsyncLocalStorage2();
|
|
1630
1885
|
|
|
1631
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1632
1887
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1633
1888
|
|
|
1634
|
-
// ../design
|
|
1889
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1635
1890
|
import readline from "node:readline";
|
|
1636
1891
|
import { PassThrough } from "node:stream";
|
|
1637
1892
|
|
|
1638
|
-
// ../design
|
|
1893
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1639
1894
|
var REGION_HEADER = 1 << 0;
|
|
1640
1895
|
var REGION_LIST = 1 << 1;
|
|
1641
1896
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1644,10 +1899,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1644
1899
|
var REGION_TOAST = 1 << 5;
|
|
1645
1900
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1646
1901
|
|
|
1647
|
-
// ../design
|
|
1902
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1648
1903
|
import * as clack from "@clack/prompts";
|
|
1649
1904
|
|
|
1650
|
-
// ../design
|
|
1905
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1651
1906
|
import { isCancel } from "@clack/prompts";
|
|
1652
1907
|
function cancel(msg = "") {
|
|
1653
1908
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1658,7 +1913,7 @@ function cancel(msg = "") {
|
|
|
1658
1913
|
`);
|
|
1659
1914
|
}
|
|
1660
1915
|
|
|
1661
|
-
// ../design
|
|
1916
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1662
1917
|
function getVisibleWidth(value) {
|
|
1663
1918
|
return stripAnsi2(value).length;
|
|
1664
1919
|
}
|
|
@@ -1707,10 +1962,10 @@ function note(message2, title) {
|
|
|
1707
1962
|
`);
|
|
1708
1963
|
}
|
|
1709
1964
|
|
|
1710
|
-
// ../design
|
|
1965
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1711
1966
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1712
1967
|
|
|
1713
|
-
// ../design
|
|
1968
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1714
1969
|
async function select2(opts) {
|
|
1715
1970
|
return clack.select(opts);
|
|
1716
1971
|
}
|
|
@@ -1753,19 +2008,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1753
2008
|
};
|
|
1754
2009
|
|
|
1755
2010
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1756
|
-
function validateHumanInLoopOnDefine(
|
|
1757
|
-
const label = Array.isArray(
|
|
1758
|
-
if (
|
|
1759
|
-
throw new Error(`${label} '${
|
|
2011
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
2012
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
2013
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
2014
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
1760
2015
|
}
|
|
1761
|
-
if (
|
|
2016
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1762
2017
|
return;
|
|
1763
2018
|
}
|
|
1764
|
-
if (
|
|
1765
|
-
throw new Error(`${label} '${
|
|
2019
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
2020
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
1766
2021
|
}
|
|
1767
|
-
if (typeof
|
|
1768
|
-
throw new Error(`${label} '${
|
|
2022
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
2023
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1769
2024
|
}
|
|
1770
2025
|
}
|
|
1771
2026
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1841,12 +2096,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1841
2096
|
}
|
|
1842
2097
|
}
|
|
1843
2098
|
}
|
|
1844
|
-
function OneOf(
|
|
1845
|
-
assertValidBranches(
|
|
2099
|
+
function OneOf(config2) {
|
|
2100
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1846
2101
|
return {
|
|
1847
2102
|
kind: "oneOf",
|
|
1848
|
-
discriminator:
|
|
1849
|
-
branches:
|
|
2103
|
+
discriminator: config2.discriminator,
|
|
2104
|
+
branches: config2.branches
|
|
1850
2105
|
};
|
|
1851
2106
|
}
|
|
1852
2107
|
|
|
@@ -2096,22 +2351,22 @@ function cloneStringArray(values) {
|
|
|
2096
2351
|
function cloneStringRecord(values) {
|
|
2097
2352
|
return values === void 0 ? void 0 : { ...values };
|
|
2098
2353
|
}
|
|
2099
|
-
function cloneMcpServerConfig(
|
|
2100
|
-
if (
|
|
2354
|
+
function cloneMcpServerConfig(config2) {
|
|
2355
|
+
if (config2 === void 0) {
|
|
2101
2356
|
return void 0;
|
|
2102
2357
|
}
|
|
2103
|
-
if (
|
|
2358
|
+
if (config2.transport === "stdio") {
|
|
2104
2359
|
return {
|
|
2105
2360
|
transport: "stdio",
|
|
2106
|
-
command:
|
|
2107
|
-
args: cloneStringArray(
|
|
2108
|
-
env: cloneStringRecord(
|
|
2361
|
+
command: config2.command,
|
|
2362
|
+
args: cloneStringArray(config2.args),
|
|
2363
|
+
env: cloneStringRecord(config2.env)
|
|
2109
2364
|
};
|
|
2110
2365
|
}
|
|
2111
2366
|
return {
|
|
2112
2367
|
transport: "http",
|
|
2113
|
-
url:
|
|
2114
|
-
headers: cloneStringRecord(
|
|
2368
|
+
url: config2.url,
|
|
2369
|
+
headers: cloneStringRecord(config2.headers)
|
|
2115
2370
|
};
|
|
2116
2371
|
}
|
|
2117
2372
|
function cloneRenameMap(rename5) {
|
|
@@ -2352,57 +2607,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2352
2607
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2353
2608
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2354
2609
|
}
|
|
2355
|
-
function createBaseCommand(
|
|
2610
|
+
function createBaseCommand(config2) {
|
|
2356
2611
|
const command = {
|
|
2357
2612
|
kind: "command",
|
|
2358
|
-
name:
|
|
2359
|
-
description:
|
|
2360
|
-
aliases: [...
|
|
2361
|
-
positional: [...
|
|
2362
|
-
params:
|
|
2363
|
-
secrets: cloneSecrets(
|
|
2364
|
-
scope: resolveCommandScope(
|
|
2365
|
-
confirm:
|
|
2366
|
-
humanInLoop:
|
|
2367
|
-
requires: cloneRequires(
|
|
2368
|
-
handler:
|
|
2369
|
-
render:
|
|
2613
|
+
name: config2.name,
|
|
2614
|
+
description: config2.description,
|
|
2615
|
+
aliases: [...config2.aliases ?? []],
|
|
2616
|
+
positional: [...config2.positional ?? []],
|
|
2617
|
+
params: config2.params,
|
|
2618
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2619
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
2620
|
+
confirm: config2.confirm ?? false,
|
|
2621
|
+
humanInLoop: config2.humanInLoop,
|
|
2622
|
+
requires: cloneRequires(config2.requires),
|
|
2623
|
+
handler: config2.handler,
|
|
2624
|
+
render: config2.render
|
|
2370
2625
|
};
|
|
2371
2626
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2372
2627
|
value: {
|
|
2373
|
-
scope: cloneScope(
|
|
2374
|
-
humanInLoop:
|
|
2375
|
-
secrets: cloneSecrets(
|
|
2376
|
-
requires: cloneRequires(
|
|
2628
|
+
scope: cloneScope(config2.scope),
|
|
2629
|
+
humanInLoop: config2.humanInLoop,
|
|
2630
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2631
|
+
requires: cloneRequires(config2.requires),
|
|
2377
2632
|
sourcePath: inferCommandSourcePath()
|
|
2378
2633
|
}
|
|
2379
2634
|
});
|
|
2380
2635
|
return command;
|
|
2381
2636
|
}
|
|
2382
|
-
function createBaseGroup(
|
|
2637
|
+
function createBaseGroup(config2) {
|
|
2383
2638
|
const group = {
|
|
2384
2639
|
kind: "group",
|
|
2385
|
-
name:
|
|
2386
|
-
description:
|
|
2387
|
-
aliases: [...
|
|
2388
|
-
scope: resolveGroupScope(
|
|
2389
|
-
humanInLoop:
|
|
2390
|
-
secrets: cloneSecrets(
|
|
2391
|
-
requires: cloneRequires(
|
|
2640
|
+
name: config2.name,
|
|
2641
|
+
description: config2.description,
|
|
2642
|
+
aliases: [...config2.aliases ?? []],
|
|
2643
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
2644
|
+
humanInLoop: config2.humanInLoop,
|
|
2645
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2646
|
+
requires: cloneRequires(config2.requires),
|
|
2392
2647
|
children: [],
|
|
2393
2648
|
default: void 0
|
|
2394
2649
|
};
|
|
2395
2650
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2396
2651
|
value: {
|
|
2397
|
-
mcp: cloneMcpServerConfig(
|
|
2398
|
-
scope: cloneScope(
|
|
2399
|
-
humanInLoop:
|
|
2400
|
-
secrets: cloneSecrets(
|
|
2401
|
-
tools: cloneStringArray(
|
|
2402
|
-
rename: cloneRenameMap(
|
|
2403
|
-
requires: cloneRequires(
|
|
2404
|
-
children: [...
|
|
2405
|
-
default:
|
|
2652
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
2653
|
+
scope: cloneScope(config2.scope),
|
|
2654
|
+
humanInLoop: config2.humanInLoop,
|
|
2655
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2656
|
+
tools: cloneStringArray(config2.tools),
|
|
2657
|
+
rename: cloneRenameMap(config2.rename),
|
|
2658
|
+
requires: cloneRequires(config2.requires),
|
|
2659
|
+
children: [...config2.children],
|
|
2660
|
+
default: config2.default
|
|
2406
2661
|
}
|
|
2407
2662
|
});
|
|
2408
2663
|
return group;
|
|
@@ -2505,10 +2760,10 @@ function materializeNode(node, inherited) {
|
|
|
2505
2760
|
}
|
|
2506
2761
|
return materializeGroup(node, inherited);
|
|
2507
2762
|
}
|
|
2508
|
-
function defineCommand(
|
|
2509
|
-
validateHumanInLoopOnDefine(
|
|
2763
|
+
function defineCommand(config2) {
|
|
2764
|
+
validateHumanInLoopOnDefine(config2);
|
|
2510
2765
|
return materializeCommand(
|
|
2511
|
-
createBaseCommand(
|
|
2766
|
+
createBaseCommand(config2),
|
|
2512
2767
|
{
|
|
2513
2768
|
scope: void 0,
|
|
2514
2769
|
humanInLoop: void 0,
|
|
@@ -2517,10 +2772,10 @@ function defineCommand(config) {
|
|
|
2517
2772
|
}
|
|
2518
2773
|
);
|
|
2519
2774
|
}
|
|
2520
|
-
function defineGroup(
|
|
2521
|
-
validateRenameMap(
|
|
2522
|
-
validateHumanInLoopOnDefine(
|
|
2523
|
-
return materializeGroup(createBaseGroup(
|
|
2775
|
+
function defineGroup(config2) {
|
|
2776
|
+
validateRenameMap(config2.rename);
|
|
2777
|
+
validateHumanInLoopOnDefine(config2);
|
|
2778
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2524
2779
|
scope: void 0,
|
|
2525
2780
|
humanInLoop: void 0,
|
|
2526
2781
|
secrets: {},
|
|
@@ -2681,17 +2936,22 @@ import { randomBytes } from "node:crypto";
|
|
|
2681
2936
|
// ../process-runner/src/docker/args.ts
|
|
2682
2937
|
import path2 from "node:path";
|
|
2683
2938
|
|
|
2939
|
+
// ../process-runner/src/docker/env-file.ts
|
|
2940
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2941
|
+
import { tmpdir } from "node:os";
|
|
2942
|
+
import path3 from "node:path";
|
|
2943
|
+
|
|
2684
2944
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2685
2945
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2686
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
2687
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2688
|
-
import { tmpdir } from "node:os";
|
|
2689
|
-
import
|
|
2946
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2947
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2948
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
2949
|
+
import path5 from "node:path";
|
|
2690
2950
|
|
|
2691
2951
|
// ../process-runner/src/host/host-runner.ts
|
|
2692
2952
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
2693
2953
|
function createHostRunner(options = {}) {
|
|
2694
|
-
const
|
|
2954
|
+
const detachedByDefault = options.detached === true;
|
|
2695
2955
|
return {
|
|
2696
2956
|
name: "host",
|
|
2697
2957
|
exec(spec) {
|
|
@@ -2709,18 +2969,19 @@ function createHostRunner(options = {}) {
|
|
|
2709
2969
|
const stdinMode = spec.stdin ?? "ignore";
|
|
2710
2970
|
const stdoutMode = spec.stdout ?? "pipe";
|
|
2711
2971
|
const stderrMode = spec.stderr ?? "pipe";
|
|
2972
|
+
const killProcessGroup = detachedByDefault || spec.killProcessGroup === true;
|
|
2712
2973
|
const stdio = stdinMode === "inherit" && stdoutMode === "inherit" && stderrMode === "inherit" ? "inherit" : [stdinMode, stdoutMode, stderrMode];
|
|
2713
2974
|
const child = spawnChildProcess(spec.command, spec.args ?? [], {
|
|
2714
2975
|
cwd: spec.cwd,
|
|
2715
2976
|
env: spec.env,
|
|
2716
2977
|
stdio,
|
|
2717
|
-
...
|
|
2978
|
+
...killProcessGroup ? { detached: true } : {}
|
|
2718
2979
|
});
|
|
2719
|
-
if (
|
|
2980
|
+
if (killProcessGroup) {
|
|
2720
2981
|
child.unref();
|
|
2721
2982
|
}
|
|
2722
2983
|
const kill = (signal) => {
|
|
2723
|
-
if (
|
|
2984
|
+
if (killProcessGroup && process.platform !== "win32" && child.pid !== void 0) {
|
|
2724
2985
|
process.kill(-child.pid, signal);
|
|
2725
2986
|
return;
|
|
2726
2987
|
}
|
|
@@ -2778,9 +3039,9 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
2778
3039
|
}
|
|
2779
3040
|
|
|
2780
3041
|
// ../process-runner/src/workspace-transfer.ts
|
|
2781
|
-
import { createHash } from "node:crypto";
|
|
3042
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2782
3043
|
import { promises as nodeFs } from "node:fs";
|
|
2783
|
-
import
|
|
3044
|
+
import path4 from "node:path";
|
|
2784
3045
|
|
|
2785
3046
|
// ../process-runner/src/testing/mock-runner.ts
|
|
2786
3047
|
import { Readable, Writable } from "node:stream";
|
|
@@ -2851,7 +3112,7 @@ function resolveEndpoint(options = {}) {
|
|
|
2851
3112
|
}
|
|
2852
3113
|
|
|
2853
3114
|
// ../task-list/src/backends/utils.ts
|
|
2854
|
-
import
|
|
3115
|
+
import path6 from "node:path";
|
|
2855
3116
|
function compareCreated(left, right) {
|
|
2856
3117
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
2857
3118
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -2901,12 +3162,12 @@ async function statIfExists(fs4, filePath) {
|
|
|
2901
3162
|
}
|
|
2902
3163
|
}
|
|
2903
3164
|
async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
2904
|
-
const resolvedPath =
|
|
2905
|
-
const rootPath =
|
|
2906
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
3165
|
+
const resolvedPath = path6.resolve(filePath);
|
|
3166
|
+
const rootPath = path6.parse(resolvedPath).root;
|
|
3167
|
+
const components = resolvedPath.slice(rootPath.length).split(path6.sep).filter(Boolean);
|
|
2907
3168
|
let currentPath = rootPath;
|
|
2908
3169
|
for (const component of components) {
|
|
2909
|
-
currentPath =
|
|
3170
|
+
currentPath = path6.join(currentPath, component);
|
|
2910
3171
|
try {
|
|
2911
3172
|
if ((await fs4.lstat(currentPath)).isSymbolicLink()) {
|
|
2912
3173
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
@@ -2922,7 +3183,7 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
2922
3183
|
async function writeAtomically(fs4, filePath, content) {
|
|
2923
3184
|
const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
|
|
2924
3185
|
tmpFileCounter += 1;
|
|
2925
|
-
await fs4.mkdir(
|
|
3186
|
+
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
2926
3187
|
try {
|
|
2927
3188
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
2928
3189
|
await fs4.rename(tempPath, filePath);
|
|
@@ -2938,7 +3199,7 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
2938
3199
|
}
|
|
2939
3200
|
}
|
|
2940
3201
|
async function withFileLock(fs4, lockPath, operation) {
|
|
2941
|
-
await fs4.mkdir(
|
|
3202
|
+
await fs4.mkdir(path6.dirname(lockPath), { recursive: true });
|
|
2942
3203
|
for (; ; ) {
|
|
2943
3204
|
try {
|
|
2944
3205
|
await fs4.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
@@ -4025,7 +4286,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
4025
4286
|
}
|
|
4026
4287
|
|
|
4027
4288
|
// ../task-list/src/backends/markdown-dir.ts
|
|
4028
|
-
import
|
|
4289
|
+
import path7 from "node:path";
|
|
4029
4290
|
import { parseDocument, stringify } from "yaml";
|
|
4030
4291
|
|
|
4031
4292
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -4144,16 +4405,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
4144
4405
|
};
|
|
4145
4406
|
}
|
|
4146
4407
|
function listPath(rootPath, layout, list) {
|
|
4147
|
-
return layout.kind === "single" ? rootPath :
|
|
4408
|
+
return layout.kind === "single" ? rootPath : path7.join(rootPath, list);
|
|
4148
4409
|
}
|
|
4149
4410
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
4150
|
-
return layout.kind === "single" ?
|
|
4411
|
+
return layout.kind === "single" ? path7.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path7.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
4151
4412
|
}
|
|
4152
4413
|
function activeTaskFilename(id, order, width) {
|
|
4153
4414
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
4154
4415
|
}
|
|
4155
4416
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
4156
|
-
return
|
|
4417
|
+
return path7.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
4157
4418
|
}
|
|
4158
4419
|
function isMarkdownFile(entryName) {
|
|
4159
4420
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -4279,7 +4540,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
4279
4540
|
state: frontmatter.state,
|
|
4280
4541
|
description: body,
|
|
4281
4542
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
4282
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
4543
|
+
...sourcePath !== void 0 && { sourcePath: path7.resolve(sourcePath) }
|
|
4283
4544
|
};
|
|
4284
4545
|
}
|
|
4285
4546
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -4319,7 +4580,7 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
4319
4580
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
4320
4581
|
};
|
|
4321
4582
|
}
|
|
4322
|
-
const parsedFilename = parseActiveFilename(
|
|
4583
|
+
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
4323
4584
|
const defaultName = parsedFilename?.id ?? id;
|
|
4324
4585
|
const effectiveFrontmatter = {
|
|
4325
4586
|
...frontmatter,
|
|
@@ -4348,7 +4609,7 @@ async function findTaskLocation(fs4, rootPath, layout, list, id) {
|
|
|
4348
4609
|
await rejectSymbolicLinkComponents(fs4, listDirectoryPath);
|
|
4349
4610
|
const activeName = await findActiveTaskFilename(fs4, listDirectoryPath, id);
|
|
4350
4611
|
if (activeName) {
|
|
4351
|
-
const activePath =
|
|
4612
|
+
const activePath = path7.join(listDirectoryPath, activeName);
|
|
4352
4613
|
await rejectSymbolicLinkComponents(fs4, activePath);
|
|
4353
4614
|
const activeStat = await statIfExists(fs4, activePath);
|
|
4354
4615
|
if (activeStat?.isFile()) {
|
|
@@ -4371,7 +4632,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4371
4632
|
}
|
|
4372
4633
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4373
4634
|
}
|
|
4374
|
-
function createdFrontmatter(
|
|
4635
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4375
4636
|
const frontmatter = mode !== "passthrough" ? {
|
|
4376
4637
|
$schema: TASK_SCHEMA_ID,
|
|
4377
4638
|
kind: TASK_KIND,
|
|
@@ -4383,7 +4644,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4383
4644
|
state: initialState
|
|
4384
4645
|
};
|
|
4385
4646
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4386
|
-
for (const [key2, value] of Object.entries(
|
|
4647
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4387
4648
|
if (!reservedKeys.has(key2)) {
|
|
4388
4649
|
setOwnValue(frontmatter, key2, value);
|
|
4389
4650
|
}
|
|
@@ -4470,7 +4731,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4470
4731
|
if (isHiddenEntry(entryName)) continue;
|
|
4471
4732
|
const parsed = parseActiveFilename(entryName);
|
|
4472
4733
|
if (!parsed) continue;
|
|
4473
|
-
const entryPath =
|
|
4734
|
+
const entryPath = path7.join(listDirectoryPath, entryName);
|
|
4474
4735
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4475
4736
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4476
4737
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4488,7 +4749,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4488
4749
|
const entries = await readActiveEntries();
|
|
4489
4750
|
const tasks = /* @__PURE__ */ new Map();
|
|
4490
4751
|
for (const entry of entries) {
|
|
4491
|
-
const filePath =
|
|
4752
|
+
const filePath = path7.join(listDirectoryPath, entry.filename);
|
|
4492
4753
|
const file = await readTaskFile(
|
|
4493
4754
|
deps.fs,
|
|
4494
4755
|
list,
|
|
@@ -4509,7 +4770,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4509
4770
|
const result = [];
|
|
4510
4771
|
for (const entryName of entries) {
|
|
4511
4772
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
4512
|
-
const entryPath =
|
|
4773
|
+
const entryPath = path7.join(archivePath, entryName);
|
|
4513
4774
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4514
4775
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4515
4776
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4539,12 +4800,12 @@ function createTasksView2(deps, layout, list) {
|
|
|
4539
4800
|
if (desiredOrder === void 0) continue;
|
|
4540
4801
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
4541
4802
|
if (entry.filename !== desiredFilename) {
|
|
4542
|
-
const fromPath =
|
|
4543
|
-
const stagingPath =
|
|
4803
|
+
const fromPath = path7.join(listDirectoryPath, entry.filename);
|
|
4804
|
+
const stagingPath = path7.join(
|
|
4544
4805
|
listDirectoryPath,
|
|
4545
4806
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
4546
4807
|
);
|
|
4547
|
-
const targetPath =
|
|
4808
|
+
const targetPath = path7.join(listDirectoryPath, desiredFilename);
|
|
4548
4809
|
try {
|
|
4549
4810
|
await deps.fs.rename(fromPath, stagingPath);
|
|
4550
4811
|
staged.push({ original: fromPath, staging: stagingPath, target: targetPath, finalized: false });
|
|
@@ -4693,7 +4954,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4693
4954
|
assertCreateHasId(input);
|
|
4694
4955
|
validateTaskId(input.id);
|
|
4695
4956
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
4696
|
-
return withFileLock(deps.fs,
|
|
4957
|
+
return withFileLock(deps.fs, path7.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
4697
4958
|
const existing = await findTaskLocation(deps.fs, deps.path, layout, list, input.id);
|
|
4698
4959
|
if (existing) {
|
|
4699
4960
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -4706,7 +4967,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4706
4967
|
const nextOrder = maxOrder + 1;
|
|
4707
4968
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
4708
4969
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
4709
|
-
const targetPath =
|
|
4970
|
+
const targetPath = path7.join(listDirectoryPath, filename);
|
|
4710
4971
|
const frontmatter = createdFrontmatter(
|
|
4711
4972
|
deps.defaults,
|
|
4712
4973
|
input,
|
|
@@ -4814,7 +5075,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4814
5075
|
validateTaskId(id);
|
|
4815
5076
|
const { event, nextTask } = await withFileLock(
|
|
4816
5077
|
deps.fs,
|
|
4817
|
-
|
|
5078
|
+
path7.join(listDirectoryPath, ".transition.lock"),
|
|
4818
5079
|
fireTask
|
|
4819
5080
|
);
|
|
4820
5081
|
await event.onEnter?.(nextTask);
|
|
@@ -4907,7 +5168,7 @@ async function markdownDirBackend(deps) {
|
|
|
4907
5168
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
4908
5169
|
continue;
|
|
4909
5170
|
}
|
|
4910
|
-
const entryPath =
|
|
5171
|
+
const entryPath = path7.join(deps.path, entryName);
|
|
4911
5172
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4912
5173
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4913
5174
|
if (entryStat?.isDirectory()) {
|
|
@@ -4949,7 +5210,7 @@ async function markdownDirBackend(deps) {
|
|
|
4949
5210
|
}
|
|
4950
5211
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
4951
5212
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
4952
|
-
return withFileLock(deps.fs,
|
|
5213
|
+
return withFileLock(deps.fs, path7.join(targetListDir, ".transition.lock"), async () => {
|
|
4953
5214
|
const targetExisting = await findTaskLocation(deps.fs, deps.path, layout, targetListName, id);
|
|
4954
5215
|
if (targetExisting) {
|
|
4955
5216
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
@@ -4999,7 +5260,7 @@ async function markdownDirBackend(deps) {
|
|
|
4999
5260
|
);
|
|
5000
5261
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
5001
5262
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
5002
|
-
const targetPath =
|
|
5263
|
+
const targetPath = path7.join(targetListDir, targetFilename);
|
|
5003
5264
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
5004
5265
|
return createTask(
|
|
5005
5266
|
targetListName,
|
|
@@ -5021,7 +5282,7 @@ async function markdownDirBackend(deps) {
|
|
|
5021
5282
|
}
|
|
5022
5283
|
|
|
5023
5284
|
// ../task-list/src/backends/yaml-file.ts
|
|
5024
|
-
import
|
|
5285
|
+
import path8 from "node:path";
|
|
5025
5286
|
import { isMap, parseDocument as parseDocument2 } from "yaml";
|
|
5026
5287
|
|
|
5027
5288
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -5117,7 +5378,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5117
5378
|
state: taskRecord.state,
|
|
5118
5379
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5119
5380
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5120
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5381
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5121
5382
|
};
|
|
5122
5383
|
}
|
|
5123
5384
|
function matchesFilter(task, filter) {
|
|
@@ -5129,13 +5390,13 @@ function matchesFilter(task, filter) {
|
|
|
5129
5390
|
}
|
|
5130
5391
|
return true;
|
|
5131
5392
|
}
|
|
5132
|
-
function createTaskRecord(
|
|
5393
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5133
5394
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5134
5395
|
name: input.name,
|
|
5135
5396
|
state: initialState,
|
|
5136
5397
|
description: input.description ?? ""
|
|
5137
5398
|
});
|
|
5138
|
-
for (const [key2, value] of Object.entries(
|
|
5399
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5139
5400
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5140
5401
|
taskRecord[key2] = value;
|
|
5141
5402
|
}
|
|
@@ -5682,7 +5943,7 @@ async function openGhIssuesBackend(options) {
|
|
|
5682
5943
|
|
|
5683
5944
|
// ../task-list/src/move.ts
|
|
5684
5945
|
import * as fsPromises2 from "node:fs/promises";
|
|
5685
|
-
import
|
|
5946
|
+
import path9 from "node:path";
|
|
5686
5947
|
|
|
5687
5948
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
5688
5949
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6178,13 +6439,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
6178
6439
|
}
|
|
6179
6440
|
function enumerateApprovalCommandPaths(root) {
|
|
6180
6441
|
const paths = [];
|
|
6181
|
-
const visit = (node,
|
|
6442
|
+
const visit = (node, path25) => {
|
|
6182
6443
|
if (node.kind === "command") {
|
|
6183
|
-
paths.push(
|
|
6444
|
+
paths.push(path25.join("."));
|
|
6184
6445
|
return;
|
|
6185
6446
|
}
|
|
6186
6447
|
for (const child of getVisibleCliChildren(node)) {
|
|
6187
|
-
visit(child, [...
|
|
6448
|
+
visit(child, [...path25, child.name]);
|
|
6188
6449
|
}
|
|
6189
6450
|
};
|
|
6190
6451
|
if (root.kind === "command") {
|
|
@@ -6219,21 +6480,21 @@ function createHandlerContext(command, params17) {
|
|
|
6219
6480
|
}
|
|
6220
6481
|
function createFs() {
|
|
6221
6482
|
return {
|
|
6222
|
-
readFile: async (
|
|
6223
|
-
writeFile: async (
|
|
6224
|
-
await writeFile2(
|
|
6483
|
+
readFile: async (path25, encoding = "utf8") => readFile2(path25, { encoding }),
|
|
6484
|
+
writeFile: async (path25, contents) => {
|
|
6485
|
+
await writeFile2(path25, contents);
|
|
6225
6486
|
},
|
|
6226
|
-
exists: async (
|
|
6487
|
+
exists: async (path25) => {
|
|
6227
6488
|
try {
|
|
6228
|
-
await access(
|
|
6489
|
+
await access(path25);
|
|
6229
6490
|
return true;
|
|
6230
6491
|
} catch {
|
|
6231
6492
|
return false;
|
|
6232
6493
|
}
|
|
6233
6494
|
},
|
|
6234
|
-
lstat: async (
|
|
6495
|
+
lstat: async (path25) => lstat(path25),
|
|
6235
6496
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
6236
|
-
unlink: async (
|
|
6497
|
+
unlink: async (path25) => unlink(path25)
|
|
6237
6498
|
};
|
|
6238
6499
|
}
|
|
6239
6500
|
function createEnv(values = process.env) {
|
|
@@ -6509,17 +6770,17 @@ function isMissingStateError(error3) {
|
|
|
6509
6770
|
}
|
|
6510
6771
|
|
|
6511
6772
|
// ../toolcraft/src/error-report.ts
|
|
6512
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6513
|
-
import { randomUUID as
|
|
6773
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6774
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6514
6775
|
import os from "node:os";
|
|
6515
|
-
import
|
|
6776
|
+
import path13 from "node:path";
|
|
6516
6777
|
import { CommanderError } from "commander";
|
|
6517
6778
|
|
|
6518
6779
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6519
6780
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6520
6781
|
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6521
|
-
import
|
|
6522
|
-
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
6782
|
+
import path12 from "node:path";
|
|
6783
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
6523
6784
|
|
|
6524
6785
|
// ../tiny-mcp-client/src/internal.ts
|
|
6525
6786
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6527,13 +6788,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
6527
6788
|
|
|
6528
6789
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
6529
6790
|
import crypto from "node:crypto";
|
|
6530
|
-
import
|
|
6791
|
+
import path11 from "node:path";
|
|
6531
6792
|
|
|
6532
6793
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6533
6794
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6534
6795
|
import { promises as fs } from "node:fs";
|
|
6535
6796
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6536
|
-
import
|
|
6797
|
+
import path10 from "node:path";
|
|
6537
6798
|
var derivedKeyCache = /* @__PURE__ */ new Map();
|
|
6538
6799
|
var ENCRYPTION_ALGORITHM = "aes-256-gcm";
|
|
6539
6800
|
var ENCRYPTION_VERSION = 1;
|
|
@@ -6545,6 +6806,7 @@ var temporaryFileSequence = 0;
|
|
|
6545
6806
|
var EncryptedFileStore = class {
|
|
6546
6807
|
fs;
|
|
6547
6808
|
filePath;
|
|
6809
|
+
symbolicLinkCheckStartPath;
|
|
6548
6810
|
salt;
|
|
6549
6811
|
getMachineIdentity;
|
|
6550
6812
|
getRandomBytes;
|
|
@@ -6552,11 +6814,22 @@ var EncryptedFileStore = class {
|
|
|
6552
6814
|
constructor(input) {
|
|
6553
6815
|
this.fs = input.fs ?? fs;
|
|
6554
6816
|
this.salt = input.salt;
|
|
6555
|
-
|
|
6556
|
-
(input.getHomeDirectory ?? homedir)()
|
|
6557
|
-
input.defaultDirectory ?? ".auth-store"
|
|
6558
|
-
|
|
6559
|
-
|
|
6817
|
+
if (input.filePath === void 0) {
|
|
6818
|
+
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
6819
|
+
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
6820
|
+
this.filePath = path10.join(
|
|
6821
|
+
homeDirectory,
|
|
6822
|
+
defaultDirectory,
|
|
6823
|
+
input.defaultFileName ?? "credentials.enc"
|
|
6824
|
+
);
|
|
6825
|
+
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
6826
|
+
homeDirectory,
|
|
6827
|
+
defaultDirectory
|
|
6828
|
+
);
|
|
6829
|
+
} else {
|
|
6830
|
+
this.filePath = input.filePath;
|
|
6831
|
+
this.symbolicLinkCheckStartPath = null;
|
|
6832
|
+
}
|
|
6560
6833
|
this.getMachineIdentity = input.getMachineIdentity ?? defaultMachineIdentity;
|
|
6561
6834
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6562
6835
|
}
|
|
@@ -6607,7 +6880,7 @@ var EncryptedFileStore = class {
|
|
|
6607
6880
|
authTag: authTag.toString("base64"),
|
|
6608
6881
|
ciphertext: ciphertext.toString("base64")
|
|
6609
6882
|
};
|
|
6610
|
-
await this.fs.mkdir(
|
|
6883
|
+
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6611
6884
|
await this.assertRegularCredentialPath();
|
|
6612
6885
|
const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
|
|
6613
6886
|
try {
|
|
@@ -6636,8 +6909,11 @@ var EncryptedFileStore = class {
|
|
|
6636
6909
|
}
|
|
6637
6910
|
}
|
|
6638
6911
|
async assertRegularCredentialPath() {
|
|
6639
|
-
const resolvedPath =
|
|
6640
|
-
const protectedPaths =
|
|
6912
|
+
const resolvedPath = path10.resolve(this.filePath);
|
|
6913
|
+
const protectedPaths = getProtectedCredentialPaths(
|
|
6914
|
+
resolvedPath,
|
|
6915
|
+
this.symbolicLinkCheckStartPath
|
|
6916
|
+
);
|
|
6641
6917
|
for (const currentPath of protectedPaths) {
|
|
6642
6918
|
try {
|
|
6643
6919
|
const stats = await this.fs.lstat(currentPath);
|
|
@@ -6665,6 +6941,30 @@ var EncryptedFileStore = class {
|
|
|
6665
6941
|
return this.keyPromise;
|
|
6666
6942
|
}
|
|
6667
6943
|
};
|
|
6944
|
+
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
6945
|
+
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
6946
|
+
return path10.resolve(homeDirectory, firstSegment ?? ".");
|
|
6947
|
+
}
|
|
6948
|
+
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
6949
|
+
if (symbolicLinkCheckStartPath === null) {
|
|
6950
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6951
|
+
}
|
|
6952
|
+
const resolvedStartPath = path10.resolve(symbolicLinkCheckStartPath);
|
|
6953
|
+
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
6954
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6955
|
+
}
|
|
6956
|
+
const protectedPaths = [resolvedStartPath];
|
|
6957
|
+
let currentPath = resolvedStartPath;
|
|
6958
|
+
for (const segment of path10.relative(resolvedStartPath, resolvedPath).split(path10.sep).filter(Boolean)) {
|
|
6959
|
+
currentPath = path10.join(currentPath, segment);
|
|
6960
|
+
protectedPaths.push(currentPath);
|
|
6961
|
+
}
|
|
6962
|
+
return protectedPaths;
|
|
6963
|
+
}
|
|
6964
|
+
function isPathInsideOrEqual(childPath, parentPath) {
|
|
6965
|
+
const relativePath = path10.relative(parentPath, childPath);
|
|
6966
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
|
|
6967
|
+
}
|
|
6668
6968
|
async function removeIfPresent(fileSystem, filePath) {
|
|
6669
6969
|
try {
|
|
6670
6970
|
await fileSystem.unlink(filePath);
|
|
@@ -6815,6 +7115,17 @@ function runSecurityCommand(command, args, options) {
|
|
|
6815
7115
|
});
|
|
6816
7116
|
let stdout = "";
|
|
6817
7117
|
let stderr = "";
|
|
7118
|
+
let stdinErrorMessage;
|
|
7119
|
+
const appendStderr = (message2) => {
|
|
7120
|
+
stderr = stderr.length === 0 ? message2 : `${stderr}${stderr.endsWith("\n") ? "" : "\n"}${message2}`;
|
|
7121
|
+
};
|
|
7122
|
+
const appendStdinError = () => {
|
|
7123
|
+
if (stdinErrorMessage === void 0) {
|
|
7124
|
+
return;
|
|
7125
|
+
}
|
|
7126
|
+
appendStderr(stdinErrorMessage);
|
|
7127
|
+
stdinErrorMessage = void 0;
|
|
7128
|
+
};
|
|
6818
7129
|
child.stdout?.setEncoding("utf8");
|
|
6819
7130
|
child.stdout?.on("data", (chunk) => {
|
|
6820
7131
|
stdout += chunk.toString();
|
|
@@ -6824,17 +7135,23 @@ function runSecurityCommand(command, args, options) {
|
|
|
6824
7135
|
stderr += chunk.toString();
|
|
6825
7136
|
});
|
|
6826
7137
|
if (options?.stdin !== void 0) {
|
|
7138
|
+
child.stdin?.once("error", (error3) => {
|
|
7139
|
+
stdinErrorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
7140
|
+
});
|
|
6827
7141
|
child.stdin?.end(options.stdin);
|
|
6828
7142
|
}
|
|
6829
7143
|
child.on("error", (error3) => {
|
|
6830
7144
|
const message2 = error3 instanceof Error ? error3.message : String(error3 ?? "Unknown error");
|
|
7145
|
+
appendStdinError();
|
|
7146
|
+
appendStderr(message2);
|
|
6831
7147
|
resolve({
|
|
6832
7148
|
stdout,
|
|
6833
|
-
stderr
|
|
7149
|
+
stderr,
|
|
6834
7150
|
exitCode: 127
|
|
6835
7151
|
});
|
|
6836
7152
|
});
|
|
6837
7153
|
child.on("close", (code) => {
|
|
7154
|
+
appendStdinError();
|
|
6838
7155
|
resolve({
|
|
6839
7156
|
stdout,
|
|
6840
7157
|
stderr,
|
|
@@ -6972,19 +7289,24 @@ function createAuthStoreClientStore(options) {
|
|
|
6972
7289
|
}
|
|
6973
7290
|
};
|
|
6974
7291
|
}
|
|
6975
|
-
function createNamedSecretStore(key2, options,
|
|
7292
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
6976
7293
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
6977
|
-
const
|
|
7294
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7295
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
6978
7296
|
const fileStore = {
|
|
6979
7297
|
...options.fileStore,
|
|
6980
|
-
|
|
6981
|
-
|
|
7298
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7299
|
+
parsedFilePath.dir,
|
|
7300
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7301
|
+
),
|
|
7302
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7303
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
6982
7304
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
6983
7305
|
};
|
|
6984
7306
|
const keychainStore = {
|
|
6985
7307
|
...options.keychainStore,
|
|
6986
|
-
service: options.keychainStore?.service ??
|
|
6987
|
-
account: `${options.keychainStore?.account ??
|
|
7308
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7309
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
6988
7310
|
};
|
|
6989
7311
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
6990
7312
|
}
|
|
@@ -8557,10 +8879,19 @@ var McpClient = class {
|
|
|
8557
8879
|
}
|
|
8558
8880
|
try {
|
|
8559
8881
|
let requestId;
|
|
8882
|
+
let cancellationSent = false;
|
|
8883
|
+
const sendCancellationNotification = () => {
|
|
8884
|
+
if (requestId === void 0 || cancellationSent) {
|
|
8885
|
+
return;
|
|
8886
|
+
}
|
|
8887
|
+
cancellationSent = true;
|
|
8888
|
+
messageLayer.sendNotification("notifications/cancelled", { requestId });
|
|
8889
|
+
};
|
|
8560
8890
|
const requestPromise = messageLayer.sendRequest("tools/call", requestParams, {
|
|
8561
8891
|
onRequestId: (nextRequestId) => {
|
|
8562
8892
|
requestId = nextRequestId;
|
|
8563
|
-
}
|
|
8893
|
+
},
|
|
8894
|
+
onTimeout: sendCancellationNotification
|
|
8564
8895
|
}).then((result) => {
|
|
8565
8896
|
if (!isCallToolResult(result)) {
|
|
8566
8897
|
throw new McpError(ERROR_INVALID_REQUEST, "Invalid tool result");
|
|
@@ -8574,8 +8905,9 @@ var McpClient = class {
|
|
|
8574
8905
|
let abortListener;
|
|
8575
8906
|
const abortPromise = new Promise((_, reject) => {
|
|
8576
8907
|
const rejectWithAbortReason = () => {
|
|
8908
|
+
sendCancellationNotification();
|
|
8577
8909
|
if (requestId !== void 0) {
|
|
8578
|
-
messageLayer.
|
|
8910
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
8579
8911
|
}
|
|
8580
8912
|
reject(signal.reason);
|
|
8581
8913
|
};
|
|
@@ -8751,11 +9083,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8751
9083
|
const child = this.child;
|
|
8752
9084
|
this.readable = child.stdout;
|
|
8753
9085
|
this.writable = child.stdin;
|
|
9086
|
+
const stderrDecoder = new TextDecoder();
|
|
8754
9087
|
child.stderr.on("data", (chunk) => {
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
9088
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9089
|
+
this.appendStderrOutput(decoded);
|
|
9090
|
+
});
|
|
9091
|
+
child.stderr.once("end", () => {
|
|
9092
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8759
9093
|
});
|
|
8760
9094
|
this.closed = new Promise((resolve) => {
|
|
8761
9095
|
let settled = false;
|
|
@@ -8795,6 +9129,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
8795
9129
|
getStderrOutput() {
|
|
8796
9130
|
return this.stderrOutput;
|
|
8797
9131
|
}
|
|
9132
|
+
appendStderrOutput(chunk) {
|
|
9133
|
+
if (chunk.length === 0) {
|
|
9134
|
+
return;
|
|
9135
|
+
}
|
|
9136
|
+
this.stderrOutput += chunk;
|
|
9137
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9138
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9139
|
+
}
|
|
9140
|
+
}
|
|
8798
9141
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
8799
9142
|
void reason;
|
|
8800
9143
|
if (this.disposed) {
|
|
@@ -9202,15 +9545,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9202
9545
|
return `${JSON.stringify(message2)}
|
|
9203
9546
|
`;
|
|
9204
9547
|
}
|
|
9205
|
-
function chunkToString(chunk) {
|
|
9206
|
-
if (typeof chunk === "string") {
|
|
9207
|
-
return chunk;
|
|
9208
|
-
}
|
|
9209
|
-
if (chunk instanceof Uint8Array) {
|
|
9210
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9211
|
-
}
|
|
9212
|
-
return String(chunk);
|
|
9213
|
-
}
|
|
9214
9548
|
function normalizeLine(line) {
|
|
9215
9549
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9216
9550
|
}
|
|
@@ -9387,6 +9721,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9387
9721
|
return new Promise((resolve, reject) => {
|
|
9388
9722
|
const timeout = setTimeout(() => {
|
|
9389
9723
|
this.pendingRequests.delete(id);
|
|
9724
|
+
options.onTimeout?.(id);
|
|
9390
9725
|
reject(new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`));
|
|
9391
9726
|
}, timeoutMs);
|
|
9392
9727
|
this.pendingRequests.set(id, { resolve, reject, timeout });
|
|
@@ -9399,6 +9734,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9399
9734
|
}
|
|
9400
9735
|
});
|
|
9401
9736
|
}
|
|
9737
|
+
cancelRequest(requestId, reason) {
|
|
9738
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9739
|
+
if (pending === void 0) {
|
|
9740
|
+
return false;
|
|
9741
|
+
}
|
|
9742
|
+
this.pendingRequests.delete(requestId);
|
|
9743
|
+
clearTimeout(pending.timeout);
|
|
9744
|
+
pending.reject(reason);
|
|
9745
|
+
return true;
|
|
9746
|
+
}
|
|
9402
9747
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9403
9748
|
if (this.disposedError !== void 0) {
|
|
9404
9749
|
return;
|
|
@@ -9799,13 +10144,13 @@ function convertJsonSchema(schema) {
|
|
|
9799
10144
|
}
|
|
9800
10145
|
return convertSchema(schema, schema, []);
|
|
9801
10146
|
}
|
|
9802
|
-
function convertSchema(schema, root,
|
|
9803
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
10147
|
+
function convertSchema(schema, root, path25) {
|
|
10148
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path25);
|
|
9804
10149
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
9805
10150
|
const composition = getComposition(normalizedSchema.schema);
|
|
9806
10151
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
9807
10152
|
throw new Error(
|
|
9808
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10153
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
|
|
9809
10154
|
normalizedSchema.schema.type
|
|
9810
10155
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9811
10156
|
);
|
|
@@ -9817,13 +10162,13 @@ function convertSchema(schema, root, path24) {
|
|
|
9817
10162
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
9818
10163
|
}
|
|
9819
10164
|
if (composition !== void 0) {
|
|
9820
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
10165
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path25);
|
|
9821
10166
|
}
|
|
9822
10167
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
9823
10168
|
return applyMetadata(
|
|
9824
10169
|
S.Record(
|
|
9825
10170
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
9826
|
-
...
|
|
10171
|
+
...path25,
|
|
9827
10172
|
"additionalProperties"
|
|
9828
10173
|
])
|
|
9829
10174
|
),
|
|
@@ -9872,12 +10217,12 @@ function convertSchema(schema, root, path24) {
|
|
|
9872
10217
|
if (normalizedSchema.schema.items === void 0) {
|
|
9873
10218
|
throw new Error(
|
|
9874
10219
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9875
|
-
|
|
10220
|
+
path25
|
|
9876
10221
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
9877
10222
|
);
|
|
9878
10223
|
}
|
|
9879
10224
|
return S.Array(
|
|
9880
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
10225
|
+
convertSchema(normalizedSchema.schema.items, root, [...path25, "items"]),
|
|
9881
10226
|
createCommonOptions(
|
|
9882
10227
|
normalizedSchema.schema,
|
|
9883
10228
|
normalizedSchema.nullable,
|
|
@@ -9887,7 +10232,7 @@ function convertSchema(schema, root, path24) {
|
|
|
9887
10232
|
case "object":
|
|
9888
10233
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
9889
10234
|
nullable: normalizedSchema.nullable,
|
|
9890
|
-
path:
|
|
10235
|
+
path: path25
|
|
9891
10236
|
});
|
|
9892
10237
|
case "null":
|
|
9893
10238
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -9902,12 +10247,12 @@ function convertSchema(schema, root, path24) {
|
|
|
9902
10247
|
}
|
|
9903
10248
|
throw new Error(
|
|
9904
10249
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9905
|
-
|
|
10250
|
+
path25
|
|
9906
10251
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
9907
10252
|
);
|
|
9908
10253
|
}
|
|
9909
10254
|
throw new Error(
|
|
9910
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10255
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" has an unsupported type "${formatJsonSchemaType(
|
|
9911
10256
|
normalizedSchema.schema.type
|
|
9912
10257
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9913
10258
|
);
|
|
@@ -9951,21 +10296,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
9951
10296
|
)
|
|
9952
10297
|
});
|
|
9953
10298
|
}
|
|
9954
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
10299
|
+
function convertCompositionSchema(schema, root, nullable, path25) {
|
|
9955
10300
|
const composition = getComposition(schema);
|
|
9956
10301
|
const branchSchemas = composition?.branches ?? [];
|
|
9957
10302
|
const keyword = composition?.keyword ?? "oneOf";
|
|
9958
10303
|
const branches = branchSchemas.map(
|
|
9959
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
10304
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path25, keyword, String(index)])
|
|
9960
10305
|
);
|
|
9961
|
-
const discriminator = findDiscriminator(branches, root,
|
|
10306
|
+
const discriminator = findDiscriminator(branches, root, path25);
|
|
9962
10307
|
if (discriminator !== void 0) {
|
|
9963
10308
|
const convertedBranches = Object.fromEntries(
|
|
9964
10309
|
branches.map((branch, index) => [
|
|
9965
10310
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
9966
10311
|
convertObjectSchema(branch, root, {
|
|
9967
10312
|
omitProperty: discriminator,
|
|
9968
|
-
path: [...
|
|
10313
|
+
path: [...path25, keyword, String(index)]
|
|
9969
10314
|
})
|
|
9970
10315
|
])
|
|
9971
10316
|
);
|
|
@@ -9984,7 +10329,7 @@ function convertCompositionSchema(schema, root, nullable, path24) {
|
|
|
9984
10329
|
S.Union(
|
|
9985
10330
|
branches.map(
|
|
9986
10331
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
9987
|
-
path: [...
|
|
10332
|
+
path: [...path25, keyword, String(index)]
|
|
9988
10333
|
})
|
|
9989
10334
|
)
|
|
9990
10335
|
),
|
|
@@ -10086,11 +10431,11 @@ function getComposition(schema) {
|
|
|
10086
10431
|
}
|
|
10087
10432
|
return void 0;
|
|
10088
10433
|
}
|
|
10089
|
-
function formatJsonSchemaPath(
|
|
10090
|
-
if (
|
|
10434
|
+
function formatJsonSchemaPath(path25) {
|
|
10435
|
+
if (path25.length === 0) {
|
|
10091
10436
|
return "#";
|
|
10092
10437
|
}
|
|
10093
|
-
return `#/${
|
|
10438
|
+
return `#/${path25.map(escapeJsonPointerSegment).join("/")}`;
|
|
10094
10439
|
}
|
|
10095
10440
|
function formatJsonSchemaType(type2) {
|
|
10096
10441
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -10106,11 +10451,11 @@ function isRecordSchema(schema) {
|
|
|
10106
10451
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
10107
10452
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
10108
10453
|
}
|
|
10109
|
-
function findDiscriminator(branches, root,
|
|
10454
|
+
function findDiscriminator(branches, root, path25) {
|
|
10110
10455
|
const [firstBranch] = branches;
|
|
10111
10456
|
if (firstBranch === void 0) {
|
|
10112
10457
|
throw new Error(
|
|
10113
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10458
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
10114
10459
|
);
|
|
10115
10460
|
}
|
|
10116
10461
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -10150,19 +10495,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
10150
10495
|
}
|
|
10151
10496
|
return void 0;
|
|
10152
10497
|
}
|
|
10153
|
-
function resolveReferencedSchema(schema, root,
|
|
10498
|
+
function resolveReferencedSchema(schema, root, path25) {
|
|
10154
10499
|
if (schema.$ref === void 0) {
|
|
10155
10500
|
return schema;
|
|
10156
10501
|
}
|
|
10157
10502
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
10158
10503
|
if (resolvedTarget === void 0) {
|
|
10159
10504
|
throw new Error(
|
|
10160
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10505
|
+
`JSON Schema "${formatJsonSchemaPath(path25)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
10161
10506
|
);
|
|
10162
10507
|
}
|
|
10163
10508
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
10164
10509
|
void ignoredRef;
|
|
10165
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
10510
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path25);
|
|
10166
10511
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
10167
10512
|
return resolvedSchema;
|
|
10168
10513
|
}
|
|
@@ -10186,9 +10531,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
10186
10531
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
10187
10532
|
};
|
|
10188
10533
|
}
|
|
10189
|
-
function hasSelfReferencingRef(schema, root,
|
|
10534
|
+
function hasSelfReferencingRef(schema, root, path25 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
10190
10535
|
const nextActivePaths = new Set(activePaths);
|
|
10191
|
-
nextActivePaths.add(
|
|
10536
|
+
nextActivePaths.add(path25);
|
|
10192
10537
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
10193
10538
|
if (localRefPath !== void 0) {
|
|
10194
10539
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -10199,13 +10544,13 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
10199
10544
|
return true;
|
|
10200
10545
|
}
|
|
10201
10546
|
}
|
|
10202
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
10547
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path25}/items`, nextActivePaths)) {
|
|
10203
10548
|
return true;
|
|
10204
10549
|
}
|
|
10205
10550
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
10206
10551
|
schema.additionalProperties,
|
|
10207
10552
|
root,
|
|
10208
|
-
`${
|
|
10553
|
+
`${path25}/additionalProperties`,
|
|
10209
10554
|
nextActivePaths
|
|
10210
10555
|
)) {
|
|
10211
10556
|
return true;
|
|
@@ -10214,7 +10559,7 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
10214
10559
|
if (hasSelfReferencingRef(
|
|
10215
10560
|
childSchema,
|
|
10216
10561
|
root,
|
|
10217
|
-
`${
|
|
10562
|
+
`${path25}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
10218
10563
|
nextActivePaths
|
|
10219
10564
|
)) {
|
|
10220
10565
|
return true;
|
|
@@ -10224,24 +10569,24 @@ function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__P
|
|
|
10224
10569
|
if (hasSelfReferencingRef(
|
|
10225
10570
|
childSchema,
|
|
10226
10571
|
root,
|
|
10227
|
-
`${
|
|
10572
|
+
`${path25}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
10228
10573
|
nextActivePaths
|
|
10229
10574
|
)) {
|
|
10230
10575
|
return true;
|
|
10231
10576
|
}
|
|
10232
10577
|
}
|
|
10233
10578
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
10234
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10579
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/oneOf/${index}`, nextActivePaths)) {
|
|
10235
10580
|
return true;
|
|
10236
10581
|
}
|
|
10237
10582
|
}
|
|
10238
10583
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
10239
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10584
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/anyOf/${index}`, nextActivePaths)) {
|
|
10240
10585
|
return true;
|
|
10241
10586
|
}
|
|
10242
10587
|
}
|
|
10243
10588
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
10244
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10589
|
+
if (hasSelfReferencingRef(childSchema, root, `${path25}/allOf/${index}`, nextActivePaths)) {
|
|
10245
10590
|
return true;
|
|
10246
10591
|
}
|
|
10247
10592
|
}
|
|
@@ -10257,14 +10602,14 @@ function getLocalRefPath(ref) {
|
|
|
10257
10602
|
return ref.startsWith("#/") ? ref : void 0;
|
|
10258
10603
|
}
|
|
10259
10604
|
function resolveLocalRef(root, ref) {
|
|
10260
|
-
const
|
|
10261
|
-
if (
|
|
10605
|
+
const path25 = getLocalRefPath(ref);
|
|
10606
|
+
if (path25 === void 0) {
|
|
10262
10607
|
return void 0;
|
|
10263
10608
|
}
|
|
10264
|
-
if (
|
|
10609
|
+
if (path25 === "#") {
|
|
10265
10610
|
return root;
|
|
10266
10611
|
}
|
|
10267
|
-
const segments =
|
|
10612
|
+
const segments = path25.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
10268
10613
|
let current = root;
|
|
10269
10614
|
for (const segment of segments) {
|
|
10270
10615
|
if (Array.isArray(current)) {
|
|
@@ -10467,10 +10812,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10467
10812
|
}
|
|
10468
10813
|
}
|
|
10469
10814
|
}
|
|
10470
|
-
function createConnection(name,
|
|
10815
|
+
function createConnection(name, config2) {
|
|
10471
10816
|
const connection = {
|
|
10472
10817
|
name,
|
|
10473
|
-
config,
|
|
10818
|
+
config: config2,
|
|
10474
10819
|
async dispose() {
|
|
10475
10820
|
shutdownDisposers.delete(connection.dispose);
|
|
10476
10821
|
connection.connecting = void 0;
|
|
@@ -10525,8 +10870,8 @@ async function readCache(cachePath) {
|
|
|
10525
10870
|
}
|
|
10526
10871
|
}
|
|
10527
10872
|
async function writeCache(cachePath, cache) {
|
|
10528
|
-
const directory =
|
|
10529
|
-
const tempPath = `${cachePath}.tmp-${
|
|
10873
|
+
const directory = path12.dirname(cachePath);
|
|
10874
|
+
const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
|
|
10530
10875
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10531
10876
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10532
10877
|
await mkdir(directory, { recursive: true });
|
|
@@ -10537,13 +10882,13 @@ async function writeCache(cachePath, cache) {
|
|
|
10537
10882
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10538
10883
|
await rename2(tempPath, cachePath);
|
|
10539
10884
|
}
|
|
10540
|
-
async function fetchCache(name,
|
|
10885
|
+
async function fetchCache(name, config2) {
|
|
10541
10886
|
const logger2 = createLogger((message2) => {
|
|
10542
10887
|
process.stderr.write(`${message2}
|
|
10543
10888
|
`);
|
|
10544
10889
|
});
|
|
10545
10890
|
logger2.info(`MCP ${name}: connecting`);
|
|
10546
|
-
const client = await dialUpstream(name,
|
|
10891
|
+
const client = await dialUpstream(name, config2);
|
|
10547
10892
|
try {
|
|
10548
10893
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10549
10894
|
const tools = [];
|
|
@@ -10562,7 +10907,7 @@ async function fetchCache(name, config) {
|
|
|
10562
10907
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10563
10908
|
version: 1,
|
|
10564
10909
|
upstream,
|
|
10565
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
10910
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10566
10911
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10567
10912
|
tools
|
|
10568
10913
|
};
|
|
@@ -10632,8 +10977,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10632
10977
|
}
|
|
10633
10978
|
async function resolveSingleProxy(group, options) {
|
|
10634
10979
|
const internal = getInternalGroupConfig2(group);
|
|
10635
|
-
const
|
|
10636
|
-
if (
|
|
10980
|
+
const config2 = internal.mcp;
|
|
10981
|
+
if (config2 === void 0) {
|
|
10637
10982
|
return;
|
|
10638
10983
|
}
|
|
10639
10984
|
const name = group.name;
|
|
@@ -10643,21 +10988,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10643
10988
|
let cache;
|
|
10644
10989
|
let shouldWriteCache = false;
|
|
10645
10990
|
if (isRefreshRequested(name, refresh)) {
|
|
10646
|
-
cache = await fetchCache(name,
|
|
10991
|
+
cache = await fetchCache(name, config2);
|
|
10647
10992
|
shouldWriteCache = true;
|
|
10648
10993
|
} else {
|
|
10649
10994
|
const storedCache = await readCache(cachePath);
|
|
10650
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
10995
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10651
10996
|
cache = storedCache;
|
|
10652
10997
|
} else {
|
|
10653
|
-
cache = await fetchCache(name,
|
|
10998
|
+
cache = await fetchCache(name, config2);
|
|
10654
10999
|
shouldWriteCache = true;
|
|
10655
11000
|
}
|
|
10656
11001
|
}
|
|
10657
11002
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10658
11003
|
validateRenameMap2(name, tools, internal.rename);
|
|
10659
11004
|
const previousConnection = getProxyConnection(group);
|
|
10660
|
-
const nextConnection = createConnection(name,
|
|
11005
|
+
const nextConnection = createConnection(name, config2);
|
|
10661
11006
|
try {
|
|
10662
11007
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10663
11008
|
if (shouldWriteCache) {
|
|
@@ -10682,11 +11027,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10682
11027
|
);
|
|
10683
11028
|
}
|
|
10684
11029
|
}
|
|
10685
|
-
function cacheMatchesConfig(cache,
|
|
10686
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
11030
|
+
function cacheMatchesConfig(cache, config2) {
|
|
11031
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10687
11032
|
}
|
|
10688
|
-
function fingerprintMcpServerConfig(
|
|
10689
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
11033
|
+
function fingerprintMcpServerConfig(config2) {
|
|
11034
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10690
11035
|
}
|
|
10691
11036
|
function collectProxyGroups(root) {
|
|
10692
11037
|
const groups = [];
|
|
@@ -10706,13 +11051,13 @@ function collectProxyGroups(root) {
|
|
|
10706
11051
|
function findProjectRoot(from = process.cwd()) {
|
|
10707
11052
|
let current = process.cwd();
|
|
10708
11053
|
if (from !== current) {
|
|
10709
|
-
current =
|
|
11054
|
+
current = path12.resolve(from);
|
|
10710
11055
|
}
|
|
10711
11056
|
while (true) {
|
|
10712
|
-
if (existsSync2(
|
|
11057
|
+
if (existsSync2(path12.join(current, "package.json"))) {
|
|
10713
11058
|
return current;
|
|
10714
11059
|
}
|
|
10715
|
-
const parent =
|
|
11060
|
+
const parent = path12.dirname(current);
|
|
10716
11061
|
if (parent === current) {
|
|
10717
11062
|
return void 0;
|
|
10718
11063
|
}
|
|
@@ -10729,7 +11074,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
10729
11074
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
10730
11075
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
10731
11076
|
}
|
|
10732
|
-
return
|
|
11077
|
+
return path12.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
10733
11078
|
}
|
|
10734
11079
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
10735
11080
|
let currentPath = filePath;
|
|
@@ -10743,10 +11088,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
10743
11088
|
throw error3;
|
|
10744
11089
|
}
|
|
10745
11090
|
}
|
|
10746
|
-
if (
|
|
11091
|
+
if (path12.basename(currentPath) === ".toolcraft") {
|
|
10747
11092
|
return;
|
|
10748
11093
|
}
|
|
10749
|
-
const parentPath =
|
|
11094
|
+
const parentPath = path12.dirname(currentPath);
|
|
10750
11095
|
if (parentPath === currentPath) {
|
|
10751
11096
|
return;
|
|
10752
11097
|
}
|
|
@@ -10764,20 +11109,20 @@ function parseRefreshEnv(value) {
|
|
|
10764
11109
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10765
11110
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10766
11111
|
}
|
|
10767
|
-
async function dialUpstream(name,
|
|
11112
|
+
async function dialUpstream(name, config2) {
|
|
10768
11113
|
const client = new McpClient({
|
|
10769
11114
|
clientInfo: {
|
|
10770
11115
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10771
11116
|
version: DEFAULT_CLIENT_INFO.version
|
|
10772
11117
|
}
|
|
10773
11118
|
});
|
|
10774
|
-
const transport =
|
|
10775
|
-
command:
|
|
10776
|
-
...
|
|
10777
|
-
...
|
|
11119
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11120
|
+
command: config2.command,
|
|
11121
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11122
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10778
11123
|
}) : new HttpTransport({
|
|
10779
|
-
url:
|
|
10780
|
-
...
|
|
11124
|
+
url: config2.url,
|
|
11125
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10781
11126
|
});
|
|
10782
11127
|
await client.connect(transport);
|
|
10783
11128
|
return client;
|
|
@@ -10787,10 +11132,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
10787
11132
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
10788
11133
|
}
|
|
10789
11134
|
|
|
11135
|
+
// ../toolcraft/src/redaction.ts
|
|
11136
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11137
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11138
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11139
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11140
|
+
function isPlainObject2(value) {
|
|
11141
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11142
|
+
}
|
|
11143
|
+
function normalizeName(name) {
|
|
11144
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11145
|
+
}
|
|
11146
|
+
function isSensitiveName(name) {
|
|
11147
|
+
const normalized = normalizeName(name);
|
|
11148
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11149
|
+
}
|
|
11150
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11151
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11152
|
+
return REDACTED_VALUE;
|
|
11153
|
+
}
|
|
11154
|
+
if (Array.isArray(value)) {
|
|
11155
|
+
if (seen.has(value)) {
|
|
11156
|
+
return "[Circular]";
|
|
11157
|
+
}
|
|
11158
|
+
seen.add(value);
|
|
11159
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11160
|
+
}
|
|
11161
|
+
if (isPlainObject2(value)) {
|
|
11162
|
+
if (seen.has(value)) {
|
|
11163
|
+
return "[Circular]";
|
|
11164
|
+
}
|
|
11165
|
+
seen.add(value);
|
|
11166
|
+
return Object.fromEntries(
|
|
11167
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11168
|
+
key2,
|
|
11169
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11170
|
+
])
|
|
11171
|
+
);
|
|
11172
|
+
}
|
|
11173
|
+
return value;
|
|
11174
|
+
}
|
|
11175
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11176
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11177
|
+
}
|
|
11178
|
+
function parseJsonObjectOrArray(value) {
|
|
11179
|
+
const trimmed = value.trim();
|
|
11180
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11181
|
+
return void 0;
|
|
11182
|
+
}
|
|
11183
|
+
try {
|
|
11184
|
+
const parsed = JSON.parse(trimmed);
|
|
11185
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11186
|
+
} catch {
|
|
11187
|
+
return void 0;
|
|
11188
|
+
}
|
|
11189
|
+
}
|
|
11190
|
+
function redactHttpBody(body) {
|
|
11191
|
+
if (typeof body === "string") {
|
|
11192
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11193
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11194
|
+
}
|
|
11195
|
+
return redactSecretLikeFields(body);
|
|
11196
|
+
}
|
|
11197
|
+
function redactHttpHeaderValue(name, value) {
|
|
11198
|
+
const normalized = normalizeName(name);
|
|
11199
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11200
|
+
return "Bearer ****";
|
|
11201
|
+
}
|
|
11202
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11203
|
+
return REDACTED_VALUE;
|
|
11204
|
+
}
|
|
11205
|
+
return value;
|
|
11206
|
+
}
|
|
11207
|
+
|
|
10790
11208
|
// ../toolcraft/src/error-report.ts
|
|
10791
11209
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
10792
|
-
|
|
10793
|
-
function isPlainObject2(value) {
|
|
11210
|
+
function isPlainObject3(value) {
|
|
10794
11211
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10795
11212
|
}
|
|
10796
11213
|
function unwrapOptional(schema) {
|
|
@@ -10800,7 +11217,7 @@ function unwrapOptional(schema) {
|
|
|
10800
11217
|
return schema;
|
|
10801
11218
|
}
|
|
10802
11219
|
function hasHttpContext(error3) {
|
|
10803
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11220
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
10804
11221
|
}
|
|
10805
11222
|
function isSkippedError(error3) {
|
|
10806
11223
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -10820,25 +11237,25 @@ function reportsEnabled(option, env) {
|
|
|
10820
11237
|
function resolveReportDir(option, projectRoot) {
|
|
10821
11238
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10822
11239
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
10823
|
-
return
|
|
11240
|
+
return path13.join(projectRoot, ".toolcraft", "errors");
|
|
10824
11241
|
}
|
|
10825
|
-
return
|
|
11242
|
+
return path13.isAbsolute(configuredDir) ? configuredDir : path13.join(projectRoot, configuredDir);
|
|
10826
11243
|
}
|
|
10827
11244
|
function reportDirMustStayWithinProject(option) {
|
|
10828
11245
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10829
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
11246
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path13.isAbsolute(configuredDir);
|
|
10830
11247
|
}
|
|
10831
11248
|
function isWithinDirectory(parent, child) {
|
|
10832
|
-
const relative =
|
|
10833
|
-
return relative === "" || !
|
|
11249
|
+
const relative = path13.relative(parent, child);
|
|
11250
|
+
return relative === "" || !path13.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path13.sep}`);
|
|
10834
11251
|
}
|
|
10835
11252
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
10836
|
-
if (!isWithinDirectory(
|
|
11253
|
+
if (!isWithinDirectory(path13.resolve(projectRoot), path13.resolve(reportDir))) {
|
|
10837
11254
|
throw new Error("Error report directory resolves outside project root.");
|
|
10838
11255
|
}
|
|
10839
11256
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
10840
|
-
|
|
10841
|
-
|
|
11257
|
+
realpath2(projectRoot),
|
|
11258
|
+
realpath2(reportDir)
|
|
10842
11259
|
]);
|
|
10843
11260
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
10844
11261
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -10884,7 +11301,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
10884
11301
|
return output.length === 0 ? "root" : output;
|
|
10885
11302
|
}
|
|
10886
11303
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
10887
|
-
const relative =
|
|
11304
|
+
const relative = path13.relative(projectRoot, absolutePath);
|
|
10888
11305
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
10889
11306
|
}
|
|
10890
11307
|
function redactValue(value) {
|
|
@@ -10893,9 +11310,24 @@ function redactValue(value) {
|
|
|
10893
11310
|
}
|
|
10894
11311
|
return `<set, ${value.length} chars>`;
|
|
10895
11312
|
}
|
|
10896
|
-
function
|
|
10897
|
-
|
|
10898
|
-
|
|
11313
|
+
function collectStringLeaves(value, output) {
|
|
11314
|
+
if (typeof value === "string") {
|
|
11315
|
+
if (value.length > 0) {
|
|
11316
|
+
output.add(value);
|
|
11317
|
+
}
|
|
11318
|
+
return;
|
|
11319
|
+
}
|
|
11320
|
+
if (Array.isArray(value)) {
|
|
11321
|
+
for (const entry of value) {
|
|
11322
|
+
collectStringLeaves(entry, output);
|
|
11323
|
+
}
|
|
11324
|
+
return;
|
|
11325
|
+
}
|
|
11326
|
+
if (isPlainObject3(value)) {
|
|
11327
|
+
for (const entry of Object.values(value)) {
|
|
11328
|
+
collectStringLeaves(entry, output);
|
|
11329
|
+
}
|
|
11330
|
+
}
|
|
10899
11331
|
}
|
|
10900
11332
|
function schemaSecretValue(schema) {
|
|
10901
11333
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -10916,7 +11348,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
10916
11348
|
return "<redacted>";
|
|
10917
11349
|
}
|
|
10918
11350
|
const unwrapped = unwrapOptional(schema);
|
|
10919
|
-
if (unwrapped.kind === "object" &&
|
|
11351
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
10920
11352
|
return Object.fromEntries(
|
|
10921
11353
|
Object.entries(value).map(([key2, childValue]) => {
|
|
10922
11354
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -10938,6 +11370,52 @@ function redactParams(params17, command) {
|
|
|
10938
11370
|
}
|
|
10939
11371
|
return redactParamsValue(params17, command.params, "");
|
|
10940
11372
|
}
|
|
11373
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11374
|
+
if (shouldRedactParam(name, schema)) {
|
|
11375
|
+
collectStringLeaves(value, output);
|
|
11376
|
+
return;
|
|
11377
|
+
}
|
|
11378
|
+
const unwrapped = unwrapOptional(schema);
|
|
11379
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11380
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11381
|
+
const childSchema = unwrapped.shape[key2];
|
|
11382
|
+
if (childSchema !== void 0) {
|
|
11383
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11384
|
+
}
|
|
11385
|
+
}
|
|
11386
|
+
return;
|
|
11387
|
+
}
|
|
11388
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11389
|
+
for (const entry of value) {
|
|
11390
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11391
|
+
}
|
|
11392
|
+
}
|
|
11393
|
+
}
|
|
11394
|
+
function createReportStringRedactor(context, env) {
|
|
11395
|
+
const values = /* @__PURE__ */ new Set();
|
|
11396
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11397
|
+
if (value !== void 0 && value.length > 0) {
|
|
11398
|
+
values.add(value);
|
|
11399
|
+
}
|
|
11400
|
+
}
|
|
11401
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11402
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11403
|
+
if (value !== void 0 && value.length > 0) {
|
|
11404
|
+
values.add(value);
|
|
11405
|
+
}
|
|
11406
|
+
}
|
|
11407
|
+
if (context.command !== void 0) {
|
|
11408
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11409
|
+
}
|
|
11410
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11411
|
+
return (value) => {
|
|
11412
|
+
let redacted = value;
|
|
11413
|
+
for (const secretValue of orderedValues) {
|
|
11414
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11415
|
+
}
|
|
11416
|
+
return redacted;
|
|
11417
|
+
};
|
|
11418
|
+
}
|
|
10941
11419
|
function commandSecretEnvNames(secrets) {
|
|
10942
11420
|
if (secrets === void 0) {
|
|
10943
11421
|
return [];
|
|
@@ -10991,28 +11469,42 @@ function redactArgv(argv, options) {
|
|
|
10991
11469
|
function stableJson(value) {
|
|
10992
11470
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
10993
11471
|
}
|
|
10994
|
-
function redactStructuredErrorField(name, value) {
|
|
10995
|
-
if (typeof value === "string"
|
|
10996
|
-
|
|
11472
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11473
|
+
if (typeof value === "string") {
|
|
11474
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11475
|
+
if (redactedHeaderValue !== value) {
|
|
11476
|
+
return redactedHeaderValue;
|
|
11477
|
+
}
|
|
11478
|
+
if (isSensitiveName(name)) {
|
|
11479
|
+
return "<redacted>";
|
|
11480
|
+
}
|
|
11481
|
+
return redactString(value);
|
|
10997
11482
|
}
|
|
10998
11483
|
if (Array.isArray(value)) {
|
|
10999
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11484
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
11000
11485
|
}
|
|
11001
|
-
if (
|
|
11486
|
+
if (isPlainObject3(value)) {
|
|
11002
11487
|
return Object.fromEntries(
|
|
11003
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11488
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11489
|
+
key2,
|
|
11490
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11491
|
+
])
|
|
11004
11492
|
);
|
|
11005
11493
|
}
|
|
11006
11494
|
return value;
|
|
11007
11495
|
}
|
|
11008
|
-
function ownStructuredFields(error3) {
|
|
11496
|
+
function ownStructuredFields(error3, redactString) {
|
|
11009
11497
|
const fields = {};
|
|
11010
11498
|
for (const key2 of Object.keys(error3)) {
|
|
11011
11499
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
11012
11500
|
continue;
|
|
11013
11501
|
}
|
|
11014
11502
|
Object.defineProperty(fields, key2, {
|
|
11015
|
-
value: redactStructuredErrorField(
|
|
11503
|
+
value: redactStructuredErrorField(
|
|
11504
|
+
key2,
|
|
11505
|
+
error3[key2],
|
|
11506
|
+
redactString
|
|
11507
|
+
),
|
|
11016
11508
|
enumerable: true,
|
|
11017
11509
|
configurable: true,
|
|
11018
11510
|
writable: true
|
|
@@ -11020,43 +11512,44 @@ function ownStructuredFields(error3) {
|
|
|
11020
11512
|
}
|
|
11021
11513
|
return fields;
|
|
11022
11514
|
}
|
|
11023
|
-
function formatStackChain(error3) {
|
|
11515
|
+
function formatStackChain(error3, redactString) {
|
|
11024
11516
|
const lines = [];
|
|
11025
11517
|
let current = error3;
|
|
11026
11518
|
let index = 0;
|
|
11027
11519
|
while (current !== void 0) {
|
|
11028
11520
|
if (current instanceof Error) {
|
|
11029
|
-
|
|
11030
|
-
|
|
11031
|
-
);
|
|
11521
|
+
const stack = current.stack ?? String(current);
|
|
11522
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
11032
11523
|
current = current.cause;
|
|
11033
11524
|
} else {
|
|
11034
|
-
|
|
11525
|
+
const message2 = String(current);
|
|
11526
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
11035
11527
|
current = void 0;
|
|
11036
11528
|
}
|
|
11037
11529
|
index += 1;
|
|
11038
11530
|
}
|
|
11039
11531
|
return lines.join("\n");
|
|
11040
11532
|
}
|
|
11041
|
-
function formatHeaderValue(name, value) {
|
|
11042
|
-
return name
|
|
11533
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11534
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
11043
11535
|
}
|
|
11044
|
-
function formatHeaders(headers) {
|
|
11045
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11536
|
+
function formatHeaders(headers, redactString) {
|
|
11537
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
11046
11538
|
}
|
|
11047
|
-
function formatBody(body) {
|
|
11048
|
-
|
|
11049
|
-
|
|
11539
|
+
function formatBody(body, redactString) {
|
|
11540
|
+
const redactedBody = redactHttpBody(body);
|
|
11541
|
+
if (typeof redactedBody === "string") {
|
|
11542
|
+
return redactString(redactedBody);
|
|
11050
11543
|
}
|
|
11051
|
-
return stableJson(
|
|
11544
|
+
return redactString(stableJson(redactedBody));
|
|
11052
11545
|
}
|
|
11053
|
-
function formatHttpTranscript(error3) {
|
|
11546
|
+
function formatHttpTranscript(error3, redactString) {
|
|
11054
11547
|
const requestLines = [
|
|
11055
11548
|
`${error3.request.method} ${error3.request.url}`,
|
|
11056
|
-
formatHeaders(error3.request.headers)
|
|
11549
|
+
formatHeaders(error3.request.headers, redactString)
|
|
11057
11550
|
].filter((line) => line.length > 0);
|
|
11058
11551
|
if (error3.request.body !== void 0) {
|
|
11059
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11552
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
11060
11553
|
}
|
|
11061
11554
|
return [
|
|
11062
11555
|
"Request:",
|
|
@@ -11064,9 +11557,9 @@ function formatHttpTranscript(error3) {
|
|
|
11064
11557
|
"",
|
|
11065
11558
|
"Response:",
|
|
11066
11559
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
11067
|
-
formatHeaders(error3.response.headers),
|
|
11560
|
+
formatHeaders(error3.response.headers, redactString),
|
|
11068
11561
|
"",
|
|
11069
|
-
formatBody(error3.response.body)
|
|
11562
|
+
formatBody(error3.response.body, redactString)
|
|
11070
11563
|
].join("\n");
|
|
11071
11564
|
}
|
|
11072
11565
|
function resolveToolcraftVersion(version) {
|
|
@@ -11075,9 +11568,10 @@ function resolveToolcraftVersion(version) {
|
|
|
11075
11568
|
function buildReport(context) {
|
|
11076
11569
|
const env = context.env ?? process.env;
|
|
11077
11570
|
const error3 = context.error;
|
|
11571
|
+
const redactString = createReportStringRedactor(context, env);
|
|
11078
11572
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11079
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11080
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11573
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11574
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11081
11575
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11082
11576
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11083
11577
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11091,7 +11585,9 @@ function buildReport(context) {
|
|
|
11091
11585
|
`platform: ${process.platform} ${process.arch}`,
|
|
11092
11586
|
"",
|
|
11093
11587
|
"Argv",
|
|
11094
|
-
|
|
11588
|
+
redactString(
|
|
11589
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11590
|
+
),
|
|
11095
11591
|
"",
|
|
11096
11592
|
"Resolved Secrets",
|
|
11097
11593
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11100,19 +11596,19 @@ function buildReport(context) {
|
|
|
11100
11596
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11101
11597
|
"",
|
|
11102
11598
|
"Parsed Params",
|
|
11103
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11599
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11104
11600
|
"",
|
|
11105
11601
|
"Error",
|
|
11106
11602
|
`name: ${errorName}`,
|
|
11107
11603
|
`message: ${errorMessage}`,
|
|
11108
11604
|
"structured fields:",
|
|
11109
|
-
stableJson(structuredFields),
|
|
11605
|
+
redactString(stableJson(structuredFields)),
|
|
11110
11606
|
"",
|
|
11111
11607
|
"Stack",
|
|
11112
|
-
formatStackChain(error3)
|
|
11608
|
+
formatStackChain(error3, redactString)
|
|
11113
11609
|
];
|
|
11114
11610
|
if (hasHttpContext(error3)) {
|
|
11115
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11611
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11116
11612
|
}
|
|
11117
11613
|
return `${lines.join("\n")}
|
|
11118
11614
|
`;
|
|
@@ -11124,8 +11620,8 @@ async function writeErrorReport(context) {
|
|
|
11124
11620
|
}
|
|
11125
11621
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11126
11622
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11127
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11128
|
-
const absolutePath =
|
|
11623
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
|
|
11624
|
+
const absolutePath = path13.join(reportDir, fileName);
|
|
11129
11625
|
await mkdir2(reportDir, { recursive: true });
|
|
11130
11626
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
11131
11627
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -11572,6 +12068,7 @@ ${rendered.join("\n")}`);
|
|
|
11572
12068
|
}
|
|
11573
12069
|
|
|
11574
12070
|
// ../toolcraft/src/cli.ts
|
|
12071
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11575
12072
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11576
12073
|
"params",
|
|
11577
12074
|
"secrets",
|
|
@@ -11589,7 +12086,7 @@ function inferProgramName(argv) {
|
|
|
11589
12086
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
11590
12087
|
return "toolcraft";
|
|
11591
12088
|
}
|
|
11592
|
-
const parsed =
|
|
12089
|
+
const parsed = path14.parse(entrypoint);
|
|
11593
12090
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
11594
12091
|
}
|
|
11595
12092
|
function normalizeRoots(roots, argv) {
|
|
@@ -11647,11 +12144,11 @@ function formatSegment(segment, casing) {
|
|
|
11647
12144
|
const separator = casing === "snake" ? "_" : "-";
|
|
11648
12145
|
return splitWords3(segment).join(separator);
|
|
11649
12146
|
}
|
|
11650
|
-
function toOptionFlag(
|
|
11651
|
-
return `--${
|
|
12147
|
+
function toOptionFlag(path25, casing) {
|
|
12148
|
+
return `--${path25.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
11652
12149
|
}
|
|
11653
|
-
function toOptionAttribute(
|
|
11654
|
-
return
|
|
12150
|
+
function toOptionAttribute(path25, casing) {
|
|
12151
|
+
return path25.map((segment) => {
|
|
11655
12152
|
const formatted = formatSegment(segment, casing);
|
|
11656
12153
|
if (casing === "snake") {
|
|
11657
12154
|
return formatted;
|
|
@@ -11662,23 +12159,23 @@ function toOptionAttribute(path24, casing) {
|
|
|
11662
12159
|
).join("");
|
|
11663
12160
|
}).join(".");
|
|
11664
12161
|
}
|
|
11665
|
-
function toDisplayPath(
|
|
11666
|
-
return
|
|
12162
|
+
function toDisplayPath(path25) {
|
|
12163
|
+
return path25.join(".");
|
|
11667
12164
|
}
|
|
11668
|
-
function toUnionKindControlPath(
|
|
11669
|
-
if (
|
|
12165
|
+
function toUnionKindControlPath(path25) {
|
|
12166
|
+
if (path25.length === 0) {
|
|
11670
12167
|
return ["kind"];
|
|
11671
12168
|
}
|
|
11672
|
-
const head =
|
|
11673
|
-
const tail =
|
|
12169
|
+
const head = path25.slice(0, -1);
|
|
12170
|
+
const tail = path25[path25.length - 1] ?? "";
|
|
11674
12171
|
return [...head, `${tail}Kind`];
|
|
11675
12172
|
}
|
|
11676
|
-
function toUnionKindDisplayPath(
|
|
11677
|
-
if (
|
|
12173
|
+
function toUnionKindDisplayPath(path25) {
|
|
12174
|
+
if (path25.length === 0) {
|
|
11678
12175
|
return "kind";
|
|
11679
12176
|
}
|
|
11680
|
-
const head =
|
|
11681
|
-
const tail =
|
|
12177
|
+
const head = path25.slice(0, -1);
|
|
12178
|
+
const tail = path25[path25.length - 1] ?? "";
|
|
11682
12179
|
return [...head, `${tail}-kind`].join(".");
|
|
11683
12180
|
}
|
|
11684
12181
|
function createSyntheticEnumSchema(values) {
|
|
@@ -11694,14 +12191,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
11694
12191
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
11695
12192
|
return requiredKeys.join("+");
|
|
11696
12193
|
}
|
|
11697
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
12194
|
+
function collectFields(schema, casing, globalLongOptionFlags, path25 = [], inheritedOptional = false, variantContext) {
|
|
11698
12195
|
const collected = {
|
|
11699
12196
|
dynamicFields: [],
|
|
11700
12197
|
fields: [],
|
|
11701
12198
|
variants: []
|
|
11702
12199
|
};
|
|
11703
12200
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
11704
|
-
const nextPath = [...
|
|
12201
|
+
const nextPath = [...path25, key2];
|
|
11705
12202
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
11706
12203
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
11707
12204
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -11882,9 +12379,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inher
|
|
|
11882
12379
|
}
|
|
11883
12380
|
return collected;
|
|
11884
12381
|
}
|
|
11885
|
-
function toCommanderOptionAttribute(
|
|
11886
|
-
const optionAttribute = toOptionAttribute(
|
|
11887
|
-
const optionFlag = toOptionFlag(
|
|
12382
|
+
function toCommanderOptionAttribute(path25, casing, globalLongOptionFlags) {
|
|
12383
|
+
const optionAttribute = toOptionAttribute(path25, casing);
|
|
12384
|
+
const optionFlag = toOptionFlag(path25, casing);
|
|
11888
12385
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
11889
12386
|
return optionAttribute;
|
|
11890
12387
|
}
|
|
@@ -12853,10 +13350,10 @@ function parseDebugStackMode(value) {
|
|
|
12853
13350
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
12854
13351
|
);
|
|
12855
13352
|
}
|
|
12856
|
-
function setNestedValue(target,
|
|
13353
|
+
function setNestedValue(target, path25, value) {
|
|
12857
13354
|
let cursor = target;
|
|
12858
|
-
for (let index = 0; index <
|
|
12859
|
-
const segment =
|
|
13355
|
+
for (let index = 0; index < path25.length - 1; index += 1) {
|
|
13356
|
+
const segment = path25[index] ?? "";
|
|
12860
13357
|
const existing = Object.prototype.hasOwnProperty.call(cursor, segment) ? cursor[segment] : void 0;
|
|
12861
13358
|
if (typeof existing === "object" && existing !== null) {
|
|
12862
13359
|
cursor = existing;
|
|
@@ -12871,7 +13368,7 @@ function setNestedValue(target, path24, value) {
|
|
|
12871
13368
|
});
|
|
12872
13369
|
cursor = next;
|
|
12873
13370
|
}
|
|
12874
|
-
const leaf =
|
|
13371
|
+
const leaf = path25[path25.length - 1];
|
|
12875
13372
|
if (leaf !== void 0) {
|
|
12876
13373
|
Object.defineProperty(cursor, leaf, {
|
|
12877
13374
|
value,
|
|
@@ -12981,21 +13478,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
12981
13478
|
}
|
|
12982
13479
|
function createFs2() {
|
|
12983
13480
|
return {
|
|
12984
|
-
readFile: async (
|
|
12985
|
-
writeFile: async (
|
|
12986
|
-
await writeFile5(
|
|
13481
|
+
readFile: async (path25, encoding = "utf8") => readFile4(path25, { encoding }),
|
|
13482
|
+
writeFile: async (path25, contents) => {
|
|
13483
|
+
await writeFile5(path25, contents);
|
|
12987
13484
|
},
|
|
12988
|
-
exists: async (
|
|
13485
|
+
exists: async (path25) => {
|
|
12989
13486
|
try {
|
|
12990
|
-
await access2(
|
|
13487
|
+
await access2(path25);
|
|
12991
13488
|
return true;
|
|
12992
13489
|
} catch {
|
|
12993
13490
|
return false;
|
|
12994
13491
|
}
|
|
12995
13492
|
},
|
|
12996
|
-
lstat: async (
|
|
13493
|
+
lstat: async (path25) => lstat3(path25),
|
|
12997
13494
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
12998
|
-
unlink: async (
|
|
13495
|
+
unlink: async (path25) => unlink2(path25)
|
|
12999
13496
|
};
|
|
13000
13497
|
}
|
|
13001
13498
|
function createEnv2(values = process.env) {
|
|
@@ -13005,15 +13502,15 @@ function createEnv2(values = process.env) {
|
|
|
13005
13502
|
}
|
|
13006
13503
|
};
|
|
13007
13504
|
}
|
|
13008
|
-
function
|
|
13505
|
+
function isPlainObject4(value) {
|
|
13009
13506
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13010
13507
|
}
|
|
13011
13508
|
function hasFieldValue(value) {
|
|
13012
13509
|
return value !== void 0;
|
|
13013
13510
|
}
|
|
13014
|
-
function hasNestedField(fields,
|
|
13511
|
+
function hasNestedField(fields, path25) {
|
|
13015
13512
|
return fields.some(
|
|
13016
|
-
(field) =>
|
|
13513
|
+
(field) => path25.length < field.path.length && path25.every((segment, index) => field.path[index] === segment)
|
|
13017
13514
|
);
|
|
13018
13515
|
}
|
|
13019
13516
|
function describeExpectedPresetValue(schema) {
|
|
@@ -13114,14 +13611,14 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13114
13611
|
{ cause: error3 }
|
|
13115
13612
|
);
|
|
13116
13613
|
}
|
|
13117
|
-
if (!
|
|
13614
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13118
13615
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13119
13616
|
}
|
|
13120
13617
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
13121
13618
|
const presetValues = {};
|
|
13122
|
-
function visitObject(current,
|
|
13619
|
+
function visitObject(current, path25) {
|
|
13123
13620
|
for (const [key2, value] of Object.entries(current)) {
|
|
13124
|
-
const nextPath = [...
|
|
13621
|
+
const nextPath = [...path25, key2];
|
|
13125
13622
|
const displayPath = toDisplayPath(nextPath);
|
|
13126
13623
|
const field = fieldByPath.get(displayPath);
|
|
13127
13624
|
if (field !== void 0) {
|
|
@@ -13133,7 +13630,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13133
13630
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13134
13631
|
);
|
|
13135
13632
|
}
|
|
13136
|
-
if (!
|
|
13633
|
+
if (!isPlainObject4(value)) {
|
|
13137
13634
|
throw new UserError(
|
|
13138
13635
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13139
13636
|
);
|
|
@@ -13176,8 +13673,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13176
13673
|
}
|
|
13177
13674
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13178
13675
|
}
|
|
13179
|
-
if (
|
|
13180
|
-
if (!
|
|
13676
|
+
if (isPlainObject4(expected)) {
|
|
13677
|
+
if (!isPlainObject4(actual)) {
|
|
13181
13678
|
return false;
|
|
13182
13679
|
}
|
|
13183
13680
|
return Object.entries(expected).every(
|
|
@@ -13240,9 +13737,9 @@ function createFixtureFetch(entries) {
|
|
|
13240
13737
|
};
|
|
13241
13738
|
}
|
|
13242
13739
|
function createFixtureFs(definition) {
|
|
13243
|
-
const fsDefinition =
|
|
13244
|
-
const readFileEntries =
|
|
13245
|
-
const existsEntries =
|
|
13740
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13741
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13742
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13246
13743
|
return {
|
|
13247
13744
|
readFile: async (filePath) => {
|
|
13248
13745
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13265,10 +13762,10 @@ function createFixtureFs(definition) {
|
|
|
13265
13762
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13266
13763
|
if (Array.isArray(definition)) {
|
|
13267
13764
|
for (const entry of definition) {
|
|
13268
|
-
if (!
|
|
13765
|
+
if (!isPlainObject4(entry)) {
|
|
13269
13766
|
continue;
|
|
13270
13767
|
}
|
|
13271
|
-
const explicitMatcher =
|
|
13768
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13272
13769
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13273
13770
|
Object.entries(entry).filter(
|
|
13274
13771
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13280,7 +13777,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13280
13777
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13281
13778
|
} else if (Object.keys(matcher).length === 0) {
|
|
13282
13779
|
matched = true;
|
|
13283
|
-
} else if (
|
|
13780
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13284
13781
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13285
13782
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13286
13783
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13301,7 +13798,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13301
13798
|
return Promise.resolve(null);
|
|
13302
13799
|
}
|
|
13303
13800
|
}
|
|
13304
|
-
if (
|
|
13801
|
+
if (isPlainObject4(definition)) {
|
|
13305
13802
|
const firstArg = args[0];
|
|
13306
13803
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13307
13804
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13313,7 +13810,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13313
13810
|
return Promise.resolve(null);
|
|
13314
13811
|
}
|
|
13315
13812
|
function createFixtureService(definition) {
|
|
13316
|
-
const methods =
|
|
13813
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13317
13814
|
return new Proxy(
|
|
13318
13815
|
{},
|
|
13319
13816
|
{
|
|
@@ -13328,8 +13825,8 @@ function createFixtureService(definition) {
|
|
|
13328
13825
|
);
|
|
13329
13826
|
}
|
|
13330
13827
|
function resolveFixturePath(commandPath) {
|
|
13331
|
-
const parsed =
|
|
13332
|
-
return
|
|
13828
|
+
const parsed = path14.parse(commandPath);
|
|
13829
|
+
return path14.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
13333
13830
|
}
|
|
13334
13831
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
13335
13832
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -13411,7 +13908,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13411
13908
|
};
|
|
13412
13909
|
}
|
|
13413
13910
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13414
|
-
const scenarioServices =
|
|
13911
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13415
13912
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13416
13913
|
...Object.keys(services),
|
|
13417
13914
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13463,8 +13960,8 @@ function validateServices(services) {
|
|
|
13463
13960
|
}
|
|
13464
13961
|
}
|
|
13465
13962
|
}
|
|
13466
|
-
function getNestedValue(target,
|
|
13467
|
-
return
|
|
13963
|
+
function getNestedValue(target, path25) {
|
|
13964
|
+
return path25.reduce(
|
|
13468
13965
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
13469
13966
|
target
|
|
13470
13967
|
);
|
|
@@ -13693,7 +14190,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13693
14190
|
if (itemSchema.kind !== "object") {
|
|
13694
14191
|
return value;
|
|
13695
14192
|
}
|
|
13696
|
-
if (!
|
|
14193
|
+
if (!isPlainObject4(value)) {
|
|
13697
14194
|
errors2.push({
|
|
13698
14195
|
path: displayPath,
|
|
13699
14196
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13728,7 +14225,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13728
14225
|
);
|
|
13729
14226
|
}
|
|
13730
14227
|
case "object": {
|
|
13731
|
-
if (!
|
|
14228
|
+
if (!isPlainObject4(value)) {
|
|
13732
14229
|
errors2.push({
|
|
13733
14230
|
path: displayPath,
|
|
13734
14231
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13759,7 +14256,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13759
14256
|
return result;
|
|
13760
14257
|
}
|
|
13761
14258
|
case "record": {
|
|
13762
|
-
if (!
|
|
14259
|
+
if (!isPlainObject4(value)) {
|
|
13763
14260
|
errors2.push({
|
|
13764
14261
|
path: displayPath,
|
|
13765
14262
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14185,10 +14682,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14185
14682
|
}
|
|
14186
14683
|
}
|
|
14187
14684
|
function isStringRecord(value) {
|
|
14188
|
-
return
|
|
14685
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14189
14686
|
}
|
|
14190
14687
|
function isHttpErrorLike(error3) {
|
|
14191
|
-
if (!
|
|
14688
|
+
if (!isPlainObject4(error3)) {
|
|
14192
14689
|
return false;
|
|
14193
14690
|
}
|
|
14194
14691
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14196,7 +14693,7 @@ function isHttpErrorLike(error3) {
|
|
|
14196
14693
|
}
|
|
14197
14694
|
const request = error3.request;
|
|
14198
14695
|
const response = error3.response;
|
|
14199
|
-
return
|
|
14696
|
+
return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
|
|
14200
14697
|
}
|
|
14201
14698
|
function hasTypedOptionalField(value, field, type2) {
|
|
14202
14699
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14205,7 +14702,7 @@ function isNonEmptyString(value) {
|
|
|
14205
14702
|
return typeof value === "string" && value.trim().length > 0;
|
|
14206
14703
|
}
|
|
14207
14704
|
function isProblemDetailsLike(body) {
|
|
14208
|
-
if (!
|
|
14705
|
+
if (!isPlainObject4(body)) {
|
|
14209
14706
|
return false;
|
|
14210
14707
|
}
|
|
14211
14708
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14226,11 +14723,11 @@ function isProblemDetailsLike(body) {
|
|
|
14226
14723
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14227
14724
|
}
|
|
14228
14725
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14229
|
-
if (!
|
|
14726
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14230
14727
|
return false;
|
|
14231
14728
|
}
|
|
14232
14729
|
return body.errors.every((error3) => {
|
|
14233
|
-
if (!
|
|
14730
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14234
14731
|
return false;
|
|
14235
14732
|
}
|
|
14236
14733
|
if ("path" in error3) {
|
|
@@ -14240,7 +14737,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14240
14737
|
}
|
|
14241
14738
|
}
|
|
14242
14739
|
if ("extensions" in error3) {
|
|
14243
|
-
if (!
|
|
14740
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14244
14741
|
return false;
|
|
14245
14742
|
}
|
|
14246
14743
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14288,23 +14785,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14288
14785
|
}).join("\n\n");
|
|
14289
14786
|
}
|
|
14290
14787
|
function formatHttpErrorBody(body) {
|
|
14291
|
-
|
|
14292
|
-
|
|
14788
|
+
const redactedBody = redactHttpBody(body);
|
|
14789
|
+
if (typeof redactedBody === "string") {
|
|
14790
|
+
return redactedBody;
|
|
14293
14791
|
}
|
|
14294
|
-
if (isProblemDetailsLike(
|
|
14295
|
-
return formatProblemDetailsBody(
|
|
14792
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
14793
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14296
14794
|
}
|
|
14297
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14298
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
14795
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
14796
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14299
14797
|
}
|
|
14300
|
-
const serialized = JSON.stringify(
|
|
14301
|
-
return serialized === void 0 ? String(
|
|
14798
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
14799
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14302
14800
|
}
|
|
14303
14801
|
function indentHttpErrorBlock(value) {
|
|
14304
14802
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14305
14803
|
}
|
|
14306
14804
|
function formatHttpHeaderValue(name, value) {
|
|
14307
|
-
return name
|
|
14805
|
+
return redactHttpHeaderValue(name, value);
|
|
14308
14806
|
}
|
|
14309
14807
|
function formatHttpErrorHeaders(headers) {
|
|
14310
14808
|
return Object.entries(headers).map(
|
|
@@ -14322,7 +14820,11 @@ function renderHttpError(error3, options) {
|
|
|
14322
14820
|
if (detailed) {
|
|
14323
14821
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14324
14822
|
if (error3.request.body !== void 0) {
|
|
14325
|
-
lines.push(
|
|
14823
|
+
lines.push(
|
|
14824
|
+
"Request body:",
|
|
14825
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
14826
|
+
""
|
|
14827
|
+
);
|
|
14326
14828
|
}
|
|
14327
14829
|
}
|
|
14328
14830
|
lines.push(
|
|
@@ -14615,7 +15117,8 @@ function configureCommanderSuggestionOutput(command) {
|
|
|
14615
15117
|
}
|
|
14616
15118
|
async function runCLI(roots, options = {}) {
|
|
14617
15119
|
enableSourceMaps();
|
|
14618
|
-
const
|
|
15120
|
+
const normalizedRoot = normalizeRoots(roots, process.argv);
|
|
15121
|
+
const root = options.approvals === false ? normalizedRoot : mergeApprovalsGroup(normalizedRoot);
|
|
14619
15122
|
await resolveMcpProxies(root, { projectRoot: options.projectRoot });
|
|
14620
15123
|
const casing = options.casing ?? "kebab";
|
|
14621
15124
|
const services = options.services ?? {};
|
|
@@ -14727,7 +15230,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14727
15230
|
}
|
|
14728
15231
|
|
|
14729
15232
|
// src/terminal-pilot.ts
|
|
14730
|
-
import { randomUUID as
|
|
15233
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
14731
15234
|
|
|
14732
15235
|
// src/terminal-session.ts
|
|
14733
15236
|
import { EventEmitter } from "node:events";
|
|
@@ -15929,7 +16432,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
15929
16432
|
}
|
|
15930
16433
|
async newSession(opts) {
|
|
15931
16434
|
const session = new TerminalSession({
|
|
15932
|
-
id:
|
|
16435
|
+
id: randomUUID4(),
|
|
15933
16436
|
command: opts.command,
|
|
15934
16437
|
args: opts.args,
|
|
15935
16438
|
cwd: opts.cwd,
|
|
@@ -16204,7 +16707,7 @@ var getSession = defineCommand({
|
|
|
16204
16707
|
|
|
16205
16708
|
// ../agent-skill-config/src/configs.ts
|
|
16206
16709
|
import os2 from "node:os";
|
|
16207
|
-
import
|
|
16710
|
+
import path15 from "node:path";
|
|
16208
16711
|
|
|
16209
16712
|
// ../agent-defs/src/agents/claude-code.ts
|
|
16210
16713
|
var claudeCodeAgent = {
|
|
@@ -16410,11 +16913,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16410
16913
|
if (!resolvedId) {
|
|
16411
16914
|
return { status: "unknown", input };
|
|
16412
16915
|
}
|
|
16413
|
-
const
|
|
16414
|
-
if (!
|
|
16916
|
+
const config2 = registry[resolvedId];
|
|
16917
|
+
if (!config2) {
|
|
16415
16918
|
return { status: "unsupported", input, id: resolvedId };
|
|
16416
16919
|
}
|
|
16417
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
16920
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16418
16921
|
}
|
|
16419
16922
|
function getAgentConfig(agentId) {
|
|
16420
16923
|
const support = resolveAgentSupport(agentId);
|
|
@@ -16513,7 +17016,7 @@ var templateMutation = {
|
|
|
16513
17016
|
};
|
|
16514
17017
|
|
|
16515
17018
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
16516
|
-
import
|
|
17019
|
+
import path17 from "node:path";
|
|
16517
17020
|
|
|
16518
17021
|
// ../config-mutations/src/formats/json.ts
|
|
16519
17022
|
import * as jsonc from "jsonc-parser";
|
|
@@ -16551,6 +17054,13 @@ function cloneConfigValue(value) {
|
|
|
16551
17054
|
function isConfigObject(value) {
|
|
16552
17055
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16553
17056
|
}
|
|
17057
|
+
function detectIndent(content) {
|
|
17058
|
+
const match = content.match(/^[\t ]+/m);
|
|
17059
|
+
if (match) {
|
|
17060
|
+
return match[0];
|
|
17061
|
+
}
|
|
17062
|
+
return " ";
|
|
17063
|
+
}
|
|
16554
17064
|
function parse3(content) {
|
|
16555
17065
|
if (!content || content.trim() === "") {
|
|
16556
17066
|
return {};
|
|
@@ -16590,6 +17100,9 @@ function merge(base, patch) {
|
|
|
16590
17100
|
}
|
|
16591
17101
|
return result;
|
|
16592
17102
|
}
|
|
17103
|
+
function configValuesEqual(left, right) {
|
|
17104
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
17105
|
+
}
|
|
16593
17106
|
function prune(obj, shape) {
|
|
16594
17107
|
let changed = false;
|
|
16595
17108
|
const result = cloneConfigObject(obj);
|
|
@@ -16626,9 +17139,56 @@ function prune(obj, shape) {
|
|
|
16626
17139
|
}
|
|
16627
17140
|
return { changed, result };
|
|
16628
17141
|
}
|
|
17142
|
+
function modifyAtPath(content, path25, value) {
|
|
17143
|
+
const indent = detectIndent(content);
|
|
17144
|
+
const formattingOptions = {
|
|
17145
|
+
tabSize: indent === " " ? 1 : indent.length,
|
|
17146
|
+
insertSpaces: indent !== " ",
|
|
17147
|
+
eol: "\n"
|
|
17148
|
+
};
|
|
17149
|
+
const edits = jsonc.modify(content, path25, value, { formattingOptions });
|
|
17150
|
+
let result = jsonc.applyEdits(content, edits);
|
|
17151
|
+
if (!result.endsWith("\n")) {
|
|
17152
|
+
result += "\n";
|
|
17153
|
+
}
|
|
17154
|
+
return result;
|
|
17155
|
+
}
|
|
17156
|
+
function removeAtPath(content, path25) {
|
|
17157
|
+
return modifyAtPath(content, path25, void 0);
|
|
17158
|
+
}
|
|
17159
|
+
function serializeUpdate(content, current, next) {
|
|
17160
|
+
let result = content || "{}";
|
|
17161
|
+
result = applyObjectUpdate(result, [], current, next);
|
|
17162
|
+
if (!result.endsWith("\n")) {
|
|
17163
|
+
result += "\n";
|
|
17164
|
+
}
|
|
17165
|
+
return result;
|
|
17166
|
+
}
|
|
17167
|
+
function applyObjectUpdate(content, path25, current, next) {
|
|
17168
|
+
let result = content;
|
|
17169
|
+
for (const key2 of Object.keys(current)) {
|
|
17170
|
+
if (!hasConfigEntry(next, key2)) {
|
|
17171
|
+
result = removeAtPath(result, [...path25, key2]);
|
|
17172
|
+
}
|
|
17173
|
+
}
|
|
17174
|
+
for (const [key2, nextValue] of Object.entries(next)) {
|
|
17175
|
+
const nextPath = [...path25, key2];
|
|
17176
|
+
const hasCurrent = hasConfigEntry(current, key2);
|
|
17177
|
+
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
17178
|
+
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
17179
|
+
result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
|
|
17180
|
+
continue;
|
|
17181
|
+
}
|
|
17182
|
+
if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
|
|
17183
|
+
result = modifyAtPath(result, nextPath, nextValue);
|
|
17184
|
+
}
|
|
17185
|
+
}
|
|
17186
|
+
return result;
|
|
17187
|
+
}
|
|
16629
17188
|
var jsonFormat = {
|
|
16630
17189
|
parse: parse3,
|
|
16631
17190
|
serialize,
|
|
17191
|
+
serializeUpdate,
|
|
16632
17192
|
merge,
|
|
16633
17193
|
prune
|
|
16634
17194
|
};
|
|
@@ -16812,20 +17372,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
16812
17372
|
}
|
|
16813
17373
|
return formatRegistry[formatName];
|
|
16814
17374
|
}
|
|
16815
|
-
function detectFormat(
|
|
16816
|
-
const ext = getExtension(
|
|
17375
|
+
function detectFormat(path25) {
|
|
17376
|
+
const ext = getExtension(path25);
|
|
16817
17377
|
return extensionMap[ext];
|
|
16818
17378
|
}
|
|
16819
|
-
function getExtension(
|
|
16820
|
-
const lastDot =
|
|
17379
|
+
function getExtension(path25) {
|
|
17380
|
+
const lastDot = path25.lastIndexOf(".");
|
|
16821
17381
|
if (lastDot === -1) {
|
|
16822
17382
|
return "";
|
|
16823
17383
|
}
|
|
16824
|
-
return
|
|
17384
|
+
return path25.slice(lastDot).toLowerCase();
|
|
16825
17385
|
}
|
|
16826
17386
|
|
|
16827
17387
|
// ../config-mutations/src/execution/path-utils.ts
|
|
16828
|
-
import
|
|
17388
|
+
import path16 from "node:path";
|
|
16829
17389
|
function expandHome(targetPath, homeDir) {
|
|
16830
17390
|
if (!targetPath?.startsWith("~")) {
|
|
16831
17391
|
return targetPath;
|
|
@@ -16842,7 +17402,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
16842
17402
|
remainder = remainder.slice(1);
|
|
16843
17403
|
}
|
|
16844
17404
|
}
|
|
16845
|
-
return remainder.length === 0 ? homeDir :
|
|
17405
|
+
return remainder.length === 0 ? homeDir : path16.join(homeDir, remainder);
|
|
16846
17406
|
}
|
|
16847
17407
|
function validateHomePath(targetPath) {
|
|
16848
17408
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -16857,21 +17417,21 @@ function validateHomePath(targetPath) {
|
|
|
16857
17417
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
16858
17418
|
validateHomePath(rawPath);
|
|
16859
17419
|
const expanded = expandHome(rawPath, homeDir);
|
|
16860
|
-
const canonicalHome =
|
|
16861
|
-
const canonicalExpanded =
|
|
16862
|
-
const relative =
|
|
16863
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
17420
|
+
const canonicalHome = path16.resolve(homeDir);
|
|
17421
|
+
const canonicalExpanded = path16.resolve(expanded);
|
|
17422
|
+
const relative = path16.relative(canonicalHome, canonicalExpanded);
|
|
17423
|
+
if (relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
|
|
16864
17424
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
16865
17425
|
}
|
|
16866
17426
|
if (!pathMapper) {
|
|
16867
17427
|
return canonicalExpanded;
|
|
16868
17428
|
}
|
|
16869
|
-
const rawDirectory =
|
|
17429
|
+
const rawDirectory = path16.dirname(expanded);
|
|
16870
17430
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
16871
17431
|
targetDirectory: rawDirectory
|
|
16872
17432
|
});
|
|
16873
|
-
const filename =
|
|
16874
|
-
return filename.length === 0 ? mappedDirectory :
|
|
17433
|
+
const filename = path16.basename(expanded);
|
|
17434
|
+
return filename.length === 0 ? mappedDirectory : path16.join(mappedDirectory, filename);
|
|
16875
17435
|
}
|
|
16876
17436
|
|
|
16877
17437
|
// ../config-mutations/src/fs-utils.ts
|
|
@@ -16935,8 +17495,8 @@ function isAlreadyExists(error3) {
|
|
|
16935
17495
|
return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
|
|
16936
17496
|
}
|
|
16937
17497
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
16938
|
-
const boundary =
|
|
16939
|
-
let currentPath =
|
|
17498
|
+
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
17499
|
+
let currentPath = path17.resolve(targetPath);
|
|
16940
17500
|
while (currentPath !== boundary) {
|
|
16941
17501
|
try {
|
|
16942
17502
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -16947,7 +17507,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
16947
17507
|
throw error3;
|
|
16948
17508
|
}
|
|
16949
17509
|
}
|
|
16950
|
-
const parentPath =
|
|
17510
|
+
const parentPath = path17.dirname(currentPath);
|
|
16951
17511
|
if (parentPath === currentPath) {
|
|
16952
17512
|
return;
|
|
16953
17513
|
}
|
|
@@ -17010,7 +17570,7 @@ function pruneKeysByPrefix(table, prefix) {
|
|
|
17010
17570
|
const result = {};
|
|
17011
17571
|
for (const [key2, value] of Object.entries(table)) {
|
|
17012
17572
|
if (!key2.startsWith(prefix)) {
|
|
17013
|
-
result
|
|
17573
|
+
setConfigEntry(result, key2, value);
|
|
17014
17574
|
}
|
|
17015
17575
|
}
|
|
17016
17576
|
return result;
|
|
@@ -17019,28 +17579,43 @@ function isConfigObject4(value) {
|
|
|
17019
17579
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17020
17580
|
}
|
|
17021
17581
|
function mergeWithPruneByPrefix(base, patch, pruneByPrefix) {
|
|
17022
|
-
const result =
|
|
17582
|
+
const result = cloneConfigObject(base);
|
|
17023
17583
|
const prefixMap = pruneByPrefix ?? {};
|
|
17024
17584
|
for (const [key2, value] of Object.entries(patch)) {
|
|
17585
|
+
if (value === void 0) {
|
|
17586
|
+
continue;
|
|
17587
|
+
}
|
|
17025
17588
|
const current = result[key2];
|
|
17026
17589
|
const prefix = prefixMap[key2];
|
|
17027
17590
|
if (isConfigObject4(current) && isConfigObject4(value)) {
|
|
17028
17591
|
if (prefix) {
|
|
17029
17592
|
const pruned = pruneKeysByPrefix(current, prefix);
|
|
17030
|
-
result
|
|
17593
|
+
setConfigEntry(result, key2, mergePrunedConfigObject(pruned, value));
|
|
17031
17594
|
} else {
|
|
17032
|
-
result
|
|
17033
|
-
current,
|
|
17034
|
-
value,
|
|
17035
|
-
prefixMap
|
|
17036
|
-
);
|
|
17595
|
+
setConfigEntry(result, key2, mergeWithPruneByPrefix(current, value, prefixMap));
|
|
17037
17596
|
}
|
|
17038
17597
|
continue;
|
|
17039
17598
|
}
|
|
17040
|
-
result
|
|
17599
|
+
setConfigEntry(result, key2, value);
|
|
17600
|
+
}
|
|
17601
|
+
return result;
|
|
17602
|
+
}
|
|
17603
|
+
function mergePrunedConfigObject(base, patch) {
|
|
17604
|
+
const result = cloneConfigObject(base);
|
|
17605
|
+
for (const [key2, value] of Object.entries(patch)) {
|
|
17606
|
+
if (value === void 0) {
|
|
17607
|
+
continue;
|
|
17608
|
+
}
|
|
17609
|
+
setConfigEntry(result, key2, value);
|
|
17041
17610
|
}
|
|
17042
17611
|
return result;
|
|
17043
17612
|
}
|
|
17613
|
+
function serializeConfigUpdate(format, rawContent, current, next) {
|
|
17614
|
+
if (rawContent !== null && format.serializeUpdate) {
|
|
17615
|
+
return format.serializeUpdate(rawContent, current, next);
|
|
17616
|
+
}
|
|
17617
|
+
return format.serialize(next);
|
|
17618
|
+
}
|
|
17044
17619
|
async function applyMutation(mutation, context, options) {
|
|
17045
17620
|
switch (mutation.kind) {
|
|
17046
17621
|
case "ensureDirectory":
|
|
@@ -17353,6 +17928,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17353
17928
|
}
|
|
17354
17929
|
const format = getConfigFormat(formatName);
|
|
17355
17930
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
17931
|
+
let preserveContent = rawContent;
|
|
17356
17932
|
let current;
|
|
17357
17933
|
try {
|
|
17358
17934
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17361,6 +17937,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17361
17937
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17362
17938
|
}
|
|
17363
17939
|
current = {};
|
|
17940
|
+
preserveContent = null;
|
|
17364
17941
|
}
|
|
17365
17942
|
const value = resolveValue(mutation.value, options);
|
|
17366
17943
|
let merged;
|
|
@@ -17369,7 +17946,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17369
17946
|
} else {
|
|
17370
17947
|
merged = format.merge(current, value);
|
|
17371
17948
|
}
|
|
17372
|
-
const serialized = format
|
|
17949
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, merged);
|
|
17373
17950
|
const changed = serialized !== rawContent;
|
|
17374
17951
|
if (changed && !context.dryRun) {
|
|
17375
17952
|
await writeAtomically2(context, targetPath, serialized);
|
|
@@ -17437,7 +18014,7 @@ async function applyConfigPrune(mutation, context, options) {
|
|
|
17437
18014
|
details
|
|
17438
18015
|
};
|
|
17439
18016
|
}
|
|
17440
|
-
const serialized = format
|
|
18017
|
+
const serialized = serializeConfigUpdate(format, rawContent, current, result);
|
|
17441
18018
|
if (!context.dryRun) {
|
|
17442
18019
|
await writeAtomically2(context, targetPath, serialized);
|
|
17443
18020
|
}
|
|
@@ -17462,6 +18039,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17462
18039
|
}
|
|
17463
18040
|
const format = getConfigFormat(formatName);
|
|
17464
18041
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
18042
|
+
let preserveContent = rawContent;
|
|
17465
18043
|
let current;
|
|
17466
18044
|
try {
|
|
17467
18045
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17470,6 +18048,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17470
18048
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17471
18049
|
}
|
|
17472
18050
|
current = {};
|
|
18051
|
+
preserveContent = null;
|
|
17473
18052
|
}
|
|
17474
18053
|
const { content: transformed, changed } = mutation.transform(current, options);
|
|
17475
18054
|
if (!changed) {
|
|
@@ -17493,7 +18072,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17493
18072
|
details
|
|
17494
18073
|
};
|
|
17495
18074
|
}
|
|
17496
|
-
const serialized = format
|
|
18075
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
17497
18076
|
if (!context.dryRun) {
|
|
17498
18077
|
await writeAtomically2(context, targetPath, serialized);
|
|
17499
18078
|
}
|
|
@@ -17635,7 +18214,7 @@ async function executeMutation(mutation, context, options) {
|
|
|
17635
18214
|
|
|
17636
18215
|
// ../agent-skill-config/src/templates.ts
|
|
17637
18216
|
import { readFile as readFile5, stat } from "node:fs/promises";
|
|
17638
|
-
import
|
|
18217
|
+
import path18 from "node:path";
|
|
17639
18218
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17640
18219
|
|
|
17641
18220
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -17670,14 +18249,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17670
18249
|
throw new UnsupportedAgentError(agentId);
|
|
17671
18250
|
}
|
|
17672
18251
|
const scope = options.scope ?? "local";
|
|
17673
|
-
const
|
|
18252
|
+
const config2 = support.config;
|
|
17674
18253
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17675
18254
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17676
18255
|
}
|
|
17677
|
-
const skillDir = scope === "global" ?
|
|
18256
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17678
18257
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17679
18258
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17680
|
-
const displayPath = `${scope === "global" ?
|
|
18259
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17681
18260
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17682
18261
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17683
18262
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -17712,21 +18291,21 @@ async function installSkill(agentId, skill, options) {
|
|
|
17712
18291
|
|
|
17713
18292
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
17714
18293
|
import { statSync as statSync2 } from "node:fs";
|
|
17715
|
-
import
|
|
18294
|
+
import path19 from "node:path";
|
|
17716
18295
|
|
|
17717
18296
|
// ../agent-skill-config/src/git-exclude.ts
|
|
17718
18297
|
import { execFileSync } from "node:child_process";
|
|
17719
18298
|
import * as fs2 from "node:fs";
|
|
17720
|
-
import
|
|
18299
|
+
import path20 from "node:path";
|
|
17721
18300
|
|
|
17722
18301
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
17723
18302
|
import * as fs3 from "node:fs";
|
|
17724
|
-
import { createHash as createHash4, randomUUID as
|
|
17725
|
-
import
|
|
18303
|
+
import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
|
|
18304
|
+
import path21 from "node:path";
|
|
17726
18305
|
|
|
17727
18306
|
// src/commands/installer.ts
|
|
17728
18307
|
import os3 from "node:os";
|
|
17729
|
-
import
|
|
18308
|
+
import path22 from "node:path";
|
|
17730
18309
|
import * as nodeFs2 from "node:fs/promises";
|
|
17731
18310
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
17732
18311
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
@@ -17793,28 +18372,28 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
17793
18372
|
return homeDir;
|
|
17794
18373
|
}
|
|
17795
18374
|
if (targetPath.startsWith("~/")) {
|
|
17796
|
-
return
|
|
18375
|
+
return path22.join(homeDir, targetPath.slice(2));
|
|
17797
18376
|
}
|
|
17798
18377
|
return targetPath;
|
|
17799
18378
|
}
|
|
17800
18379
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
17801
|
-
const
|
|
17802
|
-
if (!
|
|
18380
|
+
const config2 = getAgentConfig(agent);
|
|
18381
|
+
if (!config2) {
|
|
17803
18382
|
throwUnsupportedAgent(agent);
|
|
17804
18383
|
}
|
|
17805
18384
|
return {
|
|
17806
|
-
displayPath:
|
|
17807
|
-
scope === "global" ?
|
|
18385
|
+
displayPath: path22.join(
|
|
18386
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
17808
18387
|
TERMINAL_PILOT_SKILL_NAME
|
|
17809
18388
|
),
|
|
17810
|
-
fullPath:
|
|
17811
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18389
|
+
fullPath: path22.join(
|
|
18390
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
17812
18391
|
TERMINAL_PILOT_SKILL_NAME
|
|
17813
18392
|
)
|
|
17814
18393
|
};
|
|
17815
18394
|
}
|
|
17816
18395
|
async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
17817
|
-
const rootPath =
|
|
18396
|
+
const rootPath = path22.parse(targetPath).root;
|
|
17818
18397
|
let currentPath = targetPath;
|
|
17819
18398
|
while (currentPath !== rootPath) {
|
|
17820
18399
|
try {
|
|
@@ -17826,7 +18405,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
17826
18405
|
throw error3;
|
|
17827
18406
|
}
|
|
17828
18407
|
}
|
|
17829
|
-
currentPath =
|
|
18408
|
+
currentPath = path22.dirname(currentPath);
|
|
17830
18409
|
}
|
|
17831
18410
|
}
|
|
17832
18411
|
|
|
@@ -17965,7 +18544,7 @@ var resize = defineCommand({
|
|
|
17965
18544
|
});
|
|
17966
18545
|
|
|
17967
18546
|
// ../terminal-png/src/index.ts
|
|
17968
|
-
import { randomUUID as
|
|
18547
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17969
18548
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
17970
18549
|
|
|
17971
18550
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -18905,7 +19484,7 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
18905
19484
|
});
|
|
18906
19485
|
const png = renderPng(svg);
|
|
18907
19486
|
if (options.output) {
|
|
18908
|
-
const temporaryPath = `${options.output}.${
|
|
19487
|
+
const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
|
|
18909
19488
|
try {
|
|
18910
19489
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
18911
19490
|
await rename4(temporaryPath, options.output);
|
|
@@ -18982,7 +19561,7 @@ var type = defineCommand({
|
|
|
18982
19561
|
});
|
|
18983
19562
|
|
|
18984
19563
|
// src/commands/uninstall.ts
|
|
18985
|
-
import { randomUUID as
|
|
19564
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18986
19565
|
var params14 = S.Object({
|
|
18987
19566
|
agent: S.Enum(installableAgents, {
|
|
18988
19567
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19018,7 +19597,7 @@ var uninstall = defineCommand({
|
|
|
19018
19597
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19019
19598
|
continue;
|
|
19020
19599
|
}
|
|
19021
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19600
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
|
|
19022
19601
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19023
19602
|
staged.push({ ...skill, stagingPath });
|
|
19024
19603
|
}
|
|
@@ -19125,6 +19704,7 @@ function createTerminalPilotGroup() {
|
|
|
19125
19704
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19126
19705
|
|
|
19127
19706
|
// src/cli.ts
|
|
19707
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19128
19708
|
function normalizeArgv(argv) {
|
|
19129
19709
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19130
19710
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19148,8 +19728,8 @@ async function isDirectExecution(argv) {
|
|
|
19148
19728
|
try {
|
|
19149
19729
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19150
19730
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19151
|
-
|
|
19152
|
-
|
|
19731
|
+
realpath3(path23.resolve(entryPoint)),
|
|
19732
|
+
realpath3(modulePath)
|
|
19153
19733
|
]);
|
|
19154
19734
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19155
19735
|
} catch {
|
|
@@ -19260,13 +19840,13 @@ function createTerminalPilotCliRepl() {
|
|
|
19260
19840
|
}
|
|
19261
19841
|
|
|
19262
19842
|
// src/testing/qa-cli.ts
|
|
19263
|
-
var testingDirectory =
|
|
19264
|
-
var repoRoot =
|
|
19265
|
-
var tsxPath =
|
|
19266
|
-
var testCliPath =
|
|
19267
|
-
var menuCliPath =
|
|
19268
|
-
var vimSavedFile =
|
|
19269
|
-
var vimDiscardFile =
|
|
19843
|
+
var testingDirectory = path24.dirname(fileURLToPath6(import.meta.url));
|
|
19844
|
+
var repoRoot = path24.resolve(testingDirectory, "../../../..");
|
|
19845
|
+
var tsxPath = path24.join(repoRoot, "node_modules", ".bin", "tsx");
|
|
19846
|
+
var testCliPath = path24.join(repoRoot, "packages/terminal-pilot/src/testing/test-cli.js");
|
|
19847
|
+
var menuCliPath = path24.join(repoRoot, "packages/terminal-pilot/src/testing/menu-cli.js");
|
|
19848
|
+
var vimSavedFile = path24.join(os4.tmpdir(), "terminal-pilot-qa-test.txt");
|
|
19849
|
+
var vimDiscardFile = path24.join(os4.tmpdir(), "terminal-pilot-qa-discard.txt");
|
|
19270
19850
|
var QaContext = class {
|
|
19271
19851
|
repl = createTerminalPilotCliRepl();
|
|
19272
19852
|
async close() {
|
|
@@ -20012,7 +20592,7 @@ var cases = [
|
|
|
20012
20592
|
"VIM",
|
|
20013
20593
|
"-t",
|
|
20014
20594
|
"5000",
|
|
20015
|
-
|
|
20595
|
+
path24.basename(vimSavedFile)
|
|
20016
20596
|
]);
|
|
20017
20597
|
await ctx.expectOk(["press-key", "-s", "VIM", "i"]);
|
|
20018
20598
|
await ctx.expectOk(["type", "-s", "VIM", "hello from terminal-pilot"]);
|
|
@@ -20067,7 +20647,7 @@ var cases = [
|
|
|
20067
20647
|
"VIM2",
|
|
20068
20648
|
"-t",
|
|
20069
20649
|
"5000",
|
|
20070
|
-
|
|
20650
|
+
path24.basename(vimDiscardFile)
|
|
20071
20651
|
]);
|
|
20072
20652
|
await ctx.expectOk(["press-key", "-s", "VIM2", "i"]);
|
|
20073
20653
|
await ctx.expectOk(["type", "-s", "VIM2", "this should not be saved"]);
|