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/cli.js
CHANGED
|
@@ -6,13 +6,13 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
|
-
import { realpath as
|
|
10
|
-
import
|
|
9
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
10
|
+
import path23 from "node:path";
|
|
11
11
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
12
12
|
|
|
13
13
|
// ../toolcraft/src/cli.ts
|
|
14
14
|
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
|
|
15
|
-
import
|
|
15
|
+
import path14 from "node:path";
|
|
16
16
|
import {
|
|
17
17
|
Command as CommanderCommand,
|
|
18
18
|
CommanderError as CommanderError2,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
Option
|
|
21
21
|
} from "commander";
|
|
22
22
|
|
|
23
|
-
// ../design
|
|
23
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
24
24
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
25
25
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
26
26
|
return true;
|
|
@@ -34,7 +34,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
34
34
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// ../design
|
|
37
|
+
// ../toolcraft-design/src/components/color.ts
|
|
38
38
|
var reset = "\x1B[0m";
|
|
39
39
|
var ansiStyles = {
|
|
40
40
|
reset: { open: reset },
|
|
@@ -136,41 +136,135 @@ function createColor(styles = []) {
|
|
|
136
136
|
}
|
|
137
137
|
var color = createColor();
|
|
138
138
|
|
|
139
|
-
// ../design
|
|
140
|
-
var
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
number: (text5) => color.cyanBright(text5),
|
|
145
|
-
intro: (text5) => color.bgMagenta.white(` Poe - ${text5} `),
|
|
146
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
147
|
-
errorSymbol: color.red("\u25A0"),
|
|
148
|
-
accent: (text5) => color.cyan(text5),
|
|
149
|
-
muted: (text5) => color.dim(text5),
|
|
150
|
-
success: (text5) => color.green(text5),
|
|
151
|
-
warning: (text5) => color.yellow(text5),
|
|
152
|
-
error: (text5) => color.red(text5),
|
|
153
|
-
info: (text5) => color.magenta(text5),
|
|
154
|
-
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
139
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
140
|
+
var brands = {
|
|
141
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
142
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
143
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
155
144
|
};
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
intro: (text5) => color.bgHex("#a200ff").white(` Poe - ${text5} `),
|
|
162
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
163
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
164
|
-
accent: (text5) => color.hex("#006699").bold(text5),
|
|
165
|
-
muted: (text5) => color.hex("#666666")(text5),
|
|
166
|
-
success: (text5) => color.hex("#008800")(text5),
|
|
167
|
-
warning: (text5) => color.hex("#cc6600")(text5),
|
|
168
|
-
error: (text5) => color.hex("#cc0000")(text5),
|
|
169
|
-
info: (text5) => color.hex("#a200ff")(text5),
|
|
170
|
-
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
145
|
+
|
|
146
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
147
|
+
var defaults = {
|
|
148
|
+
brand: "purple",
|
|
149
|
+
label: "Poe"
|
|
171
150
|
};
|
|
151
|
+
var config = { ...defaults };
|
|
152
|
+
var revision = 0;
|
|
153
|
+
var brandConfigured = false;
|
|
154
|
+
function configureTheme(patch) {
|
|
155
|
+
if (patch.brand !== void 0 && !Object.hasOwn(brands, patch.brand)) {
|
|
156
|
+
throw new Error(`Unknown brand: ${patch.brand}`);
|
|
157
|
+
}
|
|
158
|
+
config = {
|
|
159
|
+
brand: patch.brand ?? config.brand,
|
|
160
|
+
label: patch.label ?? config.label
|
|
161
|
+
};
|
|
162
|
+
if (patch.brand !== void 0) {
|
|
163
|
+
brandConfigured = true;
|
|
164
|
+
}
|
|
165
|
+
revision += 1;
|
|
166
|
+
}
|
|
167
|
+
function getThemeConfig() {
|
|
168
|
+
return { ...config };
|
|
169
|
+
}
|
|
170
|
+
function getThemeRevision() {
|
|
171
|
+
return revision;
|
|
172
|
+
}
|
|
173
|
+
function isThemeBrandConfigured() {
|
|
174
|
+
return brandConfigured;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
178
|
+
var brand = brands.purple.primary;
|
|
179
|
+
function withStyles(palette, styles) {
|
|
180
|
+
return Object.defineProperty(palette, "styles", {
|
|
181
|
+
value: styles,
|
|
182
|
+
enumerable: false
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
function brandColor(activeBrand, purple) {
|
|
186
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
187
|
+
}
|
|
188
|
+
function brandBackground(activeBrand, purple) {
|
|
189
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
190
|
+
}
|
|
191
|
+
function createPalette(activeBrand, mode) {
|
|
192
|
+
const isPurple = activeBrand.name === "purple";
|
|
193
|
+
if (mode === "light") {
|
|
194
|
+
const active2 = color.hex(activeBrand.primary);
|
|
195
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
196
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
197
|
+
return withStyles(
|
|
198
|
+
{
|
|
199
|
+
header: (text5) => active2.bold(text5),
|
|
200
|
+
divider: (text5) => color.hex("#666666")(text5),
|
|
201
|
+
prompt: (text5) => prompt2.bold(text5),
|
|
202
|
+
number: (text5) => number2.bold(text5),
|
|
203
|
+
intro: (text5) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text5} `),
|
|
204
|
+
get resolvedSymbol() {
|
|
205
|
+
return active2("\u25C7");
|
|
206
|
+
},
|
|
207
|
+
get errorSymbol() {
|
|
208
|
+
return color.hex("#cc0000")("\u25A0");
|
|
209
|
+
},
|
|
210
|
+
accent: (text5) => prompt2.bold(text5),
|
|
211
|
+
muted: (text5) => color.hex("#666666")(text5),
|
|
212
|
+
success: (text5) => color.hex("#008800")(text5),
|
|
213
|
+
warning: (text5) => color.hex("#cc6600")(text5),
|
|
214
|
+
error: (text5) => color.hex("#cc0000")(text5),
|
|
215
|
+
info: (text5) => active2(text5),
|
|
216
|
+
badge: (text5) => color.bgHex("#cc6600").white(` ${text5} `)
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
220
|
+
muted: { fg: "#666666" },
|
|
221
|
+
success: { fg: "#008800" },
|
|
222
|
+
warning: { fg: "#cc6600" },
|
|
223
|
+
error: { fg: "#cc0000" },
|
|
224
|
+
info: { fg: activeBrand.primary }
|
|
225
|
+
}
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
229
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
230
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
231
|
+
const prompt = isPurple ? color.cyan : active;
|
|
232
|
+
const number = isPurple ? color.cyanBright : active;
|
|
233
|
+
return withStyles(
|
|
234
|
+
{
|
|
235
|
+
header: (text5) => activeBright.bold(text5),
|
|
236
|
+
divider: (text5) => color.dim(text5),
|
|
237
|
+
prompt: (text5) => prompt(text5),
|
|
238
|
+
number: (text5) => number(text5),
|
|
239
|
+
intro: (text5) => activeBackground.white(` ${getThemeConfig().label} - ${text5} `),
|
|
240
|
+
get resolvedSymbol() {
|
|
241
|
+
return active("\u25C7");
|
|
242
|
+
},
|
|
243
|
+
get errorSymbol() {
|
|
244
|
+
return color.red("\u25A0");
|
|
245
|
+
},
|
|
246
|
+
accent: (text5) => prompt(text5),
|
|
247
|
+
muted: (text5) => color.dim(text5),
|
|
248
|
+
success: (text5) => color.green(text5),
|
|
249
|
+
warning: (text5) => color.yellow(text5),
|
|
250
|
+
error: (text5) => color.red(text5),
|
|
251
|
+
info: (text5) => active(text5),
|
|
252
|
+
badge: (text5) => color.bgYellow.black(` ${text5} `)
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
256
|
+
muted: { dim: true },
|
|
257
|
+
success: { fg: "green" },
|
|
258
|
+
warning: { fg: "yellow" },
|
|
259
|
+
error: { fg: "red" },
|
|
260
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
var dark = createPalette(brands.purple, "dark");
|
|
265
|
+
var light = createPalette(brands.purple, "light");
|
|
172
266
|
|
|
173
|
-
// ../design
|
|
267
|
+
// ../toolcraft-design/src/tokens/typography.ts
|
|
174
268
|
var typography = {
|
|
175
269
|
bold: (text5) => color.bold(text5),
|
|
176
270
|
dim: (text5) => color.dim(text5),
|
|
@@ -179,14 +273,14 @@ var typography = {
|
|
|
179
273
|
strikethrough: (text5) => color.strikethrough(text5)
|
|
180
274
|
};
|
|
181
275
|
|
|
182
|
-
// ../design
|
|
276
|
+
// ../toolcraft-design/src/tokens/widths.ts
|
|
183
277
|
var widths = {
|
|
184
278
|
header: 60,
|
|
185
279
|
helpColumn: 24,
|
|
186
280
|
maxLine: 80
|
|
187
281
|
};
|
|
188
282
|
|
|
189
|
-
// ../design
|
|
283
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
190
284
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
191
285
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
192
286
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -207,7 +301,7 @@ function resetOutputFormatCache() {
|
|
|
207
301
|
cached = void 0;
|
|
208
302
|
}
|
|
209
303
|
|
|
210
|
-
// ../design
|
|
304
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
211
305
|
function detectThemeFromEnv(env) {
|
|
212
306
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
213
307
|
if (typeof apple === "string") {
|
|
@@ -244,17 +338,30 @@ function resolveThemeName(env = process.env) {
|
|
|
244
338
|
}
|
|
245
339
|
return "dark";
|
|
246
340
|
}
|
|
247
|
-
var
|
|
341
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
342
|
+
var cachedRevision = -1;
|
|
248
343
|
function getTheme(env) {
|
|
344
|
+
const themeName = resolveThemeName(env);
|
|
345
|
+
const config2 = getThemeConfig();
|
|
346
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
347
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
348
|
+
const revision2 = getThemeRevision();
|
|
349
|
+
if (revision2 !== cachedRevision) {
|
|
350
|
+
themeCache.clear();
|
|
351
|
+
cachedRevision = revision2;
|
|
352
|
+
}
|
|
353
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
354
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
249
355
|
if (cachedTheme) {
|
|
250
356
|
return cachedTheme;
|
|
251
357
|
}
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
358
|
+
const activeBrand = brands[activeBrandName];
|
|
359
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
360
|
+
themeCache.set(cacheKey, theme);
|
|
361
|
+
return theme;
|
|
255
362
|
}
|
|
256
363
|
|
|
257
|
-
// ../design
|
|
364
|
+
// ../toolcraft-design/src/components/text.ts
|
|
258
365
|
function renderMarkdownInline(content) {
|
|
259
366
|
return content.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
260
367
|
}
|
|
@@ -370,7 +477,7 @@ var text = {
|
|
|
370
477
|
}
|
|
371
478
|
};
|
|
372
479
|
|
|
373
|
-
// ../design
|
|
480
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
374
481
|
var symbols = {
|
|
375
482
|
get info() {
|
|
376
483
|
const format = resolveOutputFormat();
|
|
@@ -424,12 +531,12 @@ var symbols = {
|
|
|
424
531
|
}
|
|
425
532
|
};
|
|
426
533
|
|
|
427
|
-
// ../design
|
|
534
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
428
535
|
function stripAnsi(value) {
|
|
429
536
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
430
537
|
}
|
|
431
538
|
|
|
432
|
-
// ../design
|
|
539
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
433
540
|
function renderMarkdownInline2(value) {
|
|
434
541
|
return stripAnsi(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
435
542
|
}
|
|
@@ -556,7 +663,7 @@ var log = {
|
|
|
556
663
|
error
|
|
557
664
|
};
|
|
558
665
|
|
|
559
|
-
// ../design
|
|
666
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
560
667
|
function createLogger(emitter) {
|
|
561
668
|
const emit = (level, message2) => {
|
|
562
669
|
if (emitter) {
|
|
@@ -617,7 +724,7 @@ function createLogger(emitter) {
|
|
|
617
724
|
}
|
|
618
725
|
var logger = createLogger();
|
|
619
726
|
|
|
620
|
-
// ../design
|
|
727
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
621
728
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
622
729
|
function normalizeInline(value) {
|
|
623
730
|
return value.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
@@ -793,7 +900,7 @@ function formatOptionList(options) {
|
|
|
793
900
|
});
|
|
794
901
|
}
|
|
795
902
|
|
|
796
|
-
// ../design
|
|
903
|
+
// ../toolcraft-design/src/components/help-formatter-plain.ts
|
|
797
904
|
var help_formatter_plain_exports = {};
|
|
798
905
|
__export(help_formatter_plain_exports, {
|
|
799
906
|
formatColumns: () => formatColumns2,
|
|
@@ -930,7 +1037,7 @@ function formatOptionList2(options) {
|
|
|
930
1037
|
});
|
|
931
1038
|
}
|
|
932
1039
|
|
|
933
|
-
// ../design
|
|
1040
|
+
// ../toolcraft-design/src/components/table.ts
|
|
934
1041
|
var reset2 = "\x1B[0m";
|
|
935
1042
|
var ellipsis = "\u2026";
|
|
936
1043
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
@@ -1214,7 +1321,7 @@ function renderTable(options) {
|
|
|
1214
1321
|
}
|
|
1215
1322
|
}
|
|
1216
1323
|
|
|
1217
|
-
// ../design
|
|
1324
|
+
// ../toolcraft-design/src/components/detail-card.ts
|
|
1218
1325
|
function wrap(value, width) {
|
|
1219
1326
|
const lines = [];
|
|
1220
1327
|
for (const paragraph of value.split("\n")) {
|
|
@@ -1277,7 +1384,8 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1277
1384
|
return blocks.join("\n\n");
|
|
1278
1385
|
}
|
|
1279
1386
|
|
|
1280
|
-
// ../design
|
|
1387
|
+
// ../toolcraft-design/src/components/template.ts
|
|
1388
|
+
var MAX_PARTIAL_DEPTH = 100;
|
|
1281
1389
|
var HTML_ESCAPE = {
|
|
1282
1390
|
"&": "&",
|
|
1283
1391
|
"<": "<",
|
|
@@ -1289,14 +1397,27 @@ var HTML_ESCAPE = {
|
|
|
1289
1397
|
"=": "="
|
|
1290
1398
|
};
|
|
1291
1399
|
function renderTemplate(template, view, options = {}) {
|
|
1292
|
-
const prepared = options.yield === void 0 ? template : template.split("{{yield}}").join(options.yield);
|
|
1400
|
+
const prepared = options.yield === void 0 ? template : resolveTemplatePartials(template, options.partials ?? {}).split("{{yield}}").join(options.yield);
|
|
1293
1401
|
const tokens = parseTemplate(prepared);
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1402
|
+
validatePartialReferences(tokens, options.partials ?? {}, []);
|
|
1403
|
+
if (options.validate === true) {
|
|
1404
|
+
const expanded = resolveTemplatePartials(prepared, options.partials ?? {});
|
|
1405
|
+
validateVariables(parseTemplate(expanded), { view });
|
|
1406
|
+
}
|
|
1407
|
+
const state = {
|
|
1408
|
+
escape: options.escape === "none" ? String : escapeHtml,
|
|
1409
|
+
partials: options.partials ?? {},
|
|
1410
|
+
partialStack: [],
|
|
1411
|
+
preserveMissing: options.yield !== void 0 && options.escape === "none",
|
|
1412
|
+
validate: options.validate === true
|
|
1413
|
+
};
|
|
1414
|
+
return renderTokens(tokens, { view }, prepared, state);
|
|
1415
|
+
}
|
|
1416
|
+
function resolveTemplatePartials(template, partials) {
|
|
1417
|
+
return expandTemplatePartials(template, partials, []);
|
|
1297
1418
|
}
|
|
1298
|
-
function renderTemplateInContext(template, context,
|
|
1299
|
-
return renderTokens(parseTemplate(template), context, template,
|
|
1419
|
+
function renderTemplateInContext(template, context, state) {
|
|
1420
|
+
return renderTokens(parseTemplate(template), context, template, state);
|
|
1300
1421
|
}
|
|
1301
1422
|
function parseTemplate(template) {
|
|
1302
1423
|
const root = [];
|
|
@@ -1319,9 +1440,6 @@ function parseTemplate(template) {
|
|
|
1319
1440
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1320
1441
|
continue;
|
|
1321
1442
|
}
|
|
1322
|
-
if (parsed.kind === "partial") {
|
|
1323
|
-
throw new Error(`Partials are not supported: "${parsed.name}"`);
|
|
1324
|
-
}
|
|
1325
1443
|
if (parsed.kind === "delimiter") {
|
|
1326
1444
|
throw new Error("Custom delimiters are not supported");
|
|
1327
1445
|
}
|
|
@@ -1339,6 +1457,15 @@ function parseTemplate(template) {
|
|
|
1339
1457
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1340
1458
|
continue;
|
|
1341
1459
|
}
|
|
1460
|
+
if (parsed.kind === "partial") {
|
|
1461
|
+
tokens.push({
|
|
1462
|
+
type: "partial",
|
|
1463
|
+
name: parsed.name,
|
|
1464
|
+
indent: standalone === void 0 ? "" : template.slice(standalone.lineStart, open)
|
|
1465
|
+
});
|
|
1466
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1467
|
+
continue;
|
|
1468
|
+
}
|
|
1342
1469
|
if (parsed.kind === "close") {
|
|
1343
1470
|
const frame2 = stack.pop();
|
|
1344
1471
|
if (frame2 === void 0) {
|
|
@@ -1409,7 +1536,7 @@ function getStandalone(template, tagStart, tagEnd, kind) {
|
|
|
1409
1536
|
}
|
|
1410
1537
|
return void 0;
|
|
1411
1538
|
}
|
|
1412
|
-
function renderTokens(tokens, context, template,
|
|
1539
|
+
function renderTokens(tokens, context, template, state) {
|
|
1413
1540
|
let output = "";
|
|
1414
1541
|
for (const token of tokens) {
|
|
1415
1542
|
switch (token.type) {
|
|
@@ -1418,32 +1545,62 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1418
1545
|
continue;
|
|
1419
1546
|
case "name":
|
|
1420
1547
|
case "unescaped": {
|
|
1421
|
-
const
|
|
1422
|
-
if (value == null) {
|
|
1423
|
-
if (
|
|
1548
|
+
const result = lookup(context, token.name);
|
|
1549
|
+
if (!result.hit || result.value == null) {
|
|
1550
|
+
if (state.validate) {
|
|
1551
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1552
|
+
}
|
|
1553
|
+
if (state.preserveMissing) {
|
|
1424
1554
|
output += token.raw;
|
|
1425
1555
|
}
|
|
1426
1556
|
continue;
|
|
1427
1557
|
}
|
|
1428
|
-
const rendered = String(value);
|
|
1429
|
-
output += token.type === "name" ? escape(rendered) : rendered;
|
|
1558
|
+
const rendered = String(result.value);
|
|
1559
|
+
output += token.type === "name" ? state.escape(rendered) : rendered;
|
|
1560
|
+
continue;
|
|
1561
|
+
}
|
|
1562
|
+
case "partial": {
|
|
1563
|
+
if (!Object.hasOwn(state.partials, token.name)) {
|
|
1564
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1565
|
+
}
|
|
1566
|
+
if (state.partialStack.includes(token.name)) {
|
|
1567
|
+
throw new Error(
|
|
1568
|
+
`Circular partial reference detected: ${[...state.partialStack, token.name].join(" -> ")}.`
|
|
1569
|
+
);
|
|
1570
|
+
}
|
|
1571
|
+
if (state.partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1572
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1573
|
+
}
|
|
1574
|
+
const partial = indentPartial(state.partials[token.name], token.indent);
|
|
1575
|
+
output += renderTokens(parseTemplate(partial), context, partial, {
|
|
1576
|
+
...state,
|
|
1577
|
+
partialStack: [...state.partialStack, token.name]
|
|
1578
|
+
});
|
|
1430
1579
|
continue;
|
|
1431
1580
|
}
|
|
1432
1581
|
case "inverted": {
|
|
1433
|
-
const
|
|
1582
|
+
const result = lookup(context, token.name);
|
|
1583
|
+
if (!result.hit && state.validate) {
|
|
1584
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1585
|
+
}
|
|
1586
|
+
const value = result.value;
|
|
1434
1587
|
if (!value || Array.isArray(value) && value.length === 0) {
|
|
1435
|
-
output += renderTokens(token.children, context, template,
|
|
1588
|
+
output += renderTokens(token.children, context, template, state);
|
|
1436
1589
|
}
|
|
1437
1590
|
continue;
|
|
1438
1591
|
}
|
|
1439
1592
|
case "section": {
|
|
1440
|
-
const
|
|
1593
|
+
const result = lookup(context, token.name);
|
|
1594
|
+
if (!result.hit && state.validate) {
|
|
1595
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1596
|
+
}
|
|
1597
|
+
const value = result.value;
|
|
1441
1598
|
if (!value) {
|
|
1442
1599
|
continue;
|
|
1443
1600
|
}
|
|
1444
1601
|
if (Array.isArray(value)) {
|
|
1445
1602
|
for (const item of value) {
|
|
1446
|
-
output += renderTokens(token.children, pushContext(context, item), template,
|
|
1603
|
+
output += renderTokens(token.children, pushContext(context, item), template, state);
|
|
1447
1604
|
}
|
|
1448
1605
|
continue;
|
|
1449
1606
|
}
|
|
@@ -1452,7 +1609,7 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1452
1609
|
const rendered = value.call(
|
|
1453
1610
|
context.view,
|
|
1454
1611
|
raw,
|
|
1455
|
-
(nextTemplate) => renderTemplateInContext(nextTemplate, context,
|
|
1612
|
+
(nextTemplate) => renderTemplateInContext(nextTemplate, context, state)
|
|
1456
1613
|
);
|
|
1457
1614
|
if (rendered != null) {
|
|
1458
1615
|
output += String(rendered);
|
|
@@ -1460,10 +1617,10 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1460
1617
|
continue;
|
|
1461
1618
|
}
|
|
1462
1619
|
if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
1463
|
-
output += renderTokens(token.children, pushContext(context, value), template,
|
|
1620
|
+
output += renderTokens(token.children, pushContext(context, value), template, state);
|
|
1464
1621
|
continue;
|
|
1465
1622
|
}
|
|
1466
|
-
output += renderTokens(token.children, context, template,
|
|
1623
|
+
output += renderTokens(token.children, context, template, state);
|
|
1467
1624
|
}
|
|
1468
1625
|
}
|
|
1469
1626
|
}
|
|
@@ -1471,17 +1628,115 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1471
1628
|
}
|
|
1472
1629
|
function lookup(context, name) {
|
|
1473
1630
|
if (name === ".") {
|
|
1474
|
-
return callLambda(context.view, context.view);
|
|
1631
|
+
return { hit: true, value: callLambda(context.view, context.view) };
|
|
1475
1632
|
}
|
|
1476
1633
|
let cursor = context;
|
|
1477
1634
|
while (cursor !== void 0) {
|
|
1478
1635
|
const result = name.includes(".") ? lookupDotted(cursor.view, name) : lookupName(cursor.view, name);
|
|
1479
1636
|
if (result.hit) {
|
|
1480
|
-
return callLambda(result.value, cursor.view);
|
|
1637
|
+
return { hit: true, value: callLambda(result.value, cursor.view) };
|
|
1481
1638
|
}
|
|
1482
1639
|
cursor = cursor.parent;
|
|
1483
1640
|
}
|
|
1484
|
-
return void 0;
|
|
1641
|
+
return { hit: false, value: void 0 };
|
|
1642
|
+
}
|
|
1643
|
+
function validateVariables(tokens, context) {
|
|
1644
|
+
for (const token of tokens) {
|
|
1645
|
+
if (token.type === "text" || token.type === "partial") {
|
|
1646
|
+
continue;
|
|
1647
|
+
}
|
|
1648
|
+
if (token.type === "name" || token.type === "unescaped") {
|
|
1649
|
+
if (!lookup(context, token.name).hit) {
|
|
1650
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1651
|
+
}
|
|
1652
|
+
continue;
|
|
1653
|
+
}
|
|
1654
|
+
if (token.type !== "section" && token.type !== "inverted") {
|
|
1655
|
+
continue;
|
|
1656
|
+
}
|
|
1657
|
+
const result = lookup(context, token.name);
|
|
1658
|
+
if (!result.hit) {
|
|
1659
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1660
|
+
}
|
|
1661
|
+
if (Array.isArray(result.value) && result.value.length > 0) {
|
|
1662
|
+
for (const item of result.value) {
|
|
1663
|
+
validateVariables(token.children, pushContext(context, item));
|
|
1664
|
+
}
|
|
1665
|
+
continue;
|
|
1666
|
+
}
|
|
1667
|
+
if (typeof result.value === "object" && result.value !== null || typeof result.value === "string" || typeof result.value === "number") {
|
|
1668
|
+
validateVariables(token.children, pushContext(context, result.value));
|
|
1669
|
+
continue;
|
|
1670
|
+
}
|
|
1671
|
+
validateVariables(token.children, context);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
function validatePartialReferences(tokens, partials, partialStack) {
|
|
1675
|
+
for (const token of tokens) {
|
|
1676
|
+
if (token.type === "section" || token.type === "inverted") {
|
|
1677
|
+
validatePartialReferences(token.children, partials, partialStack);
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
if (token.type !== "partial") {
|
|
1681
|
+
continue;
|
|
1682
|
+
}
|
|
1683
|
+
if (!Object.hasOwn(partials, token.name)) {
|
|
1684
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1685
|
+
}
|
|
1686
|
+
if (partialStack.includes(token.name)) {
|
|
1687
|
+
throw new Error(
|
|
1688
|
+
`Circular partial reference detected: ${[...partialStack, token.name].join(" -> ")}.`
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
1691
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1692
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1693
|
+
}
|
|
1694
|
+
validatePartialReferences(parseTemplate(partials[token.name]), partials, [
|
|
1695
|
+
...partialStack,
|
|
1696
|
+
token.name
|
|
1697
|
+
]);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
function indentPartial(partial, indent) {
|
|
1701
|
+
if (indent === "") {
|
|
1702
|
+
return partial;
|
|
1703
|
+
}
|
|
1704
|
+
return partial.split("\n").map((line) => line === "" ? "" : `${indent}${line}`).join("\n");
|
|
1705
|
+
}
|
|
1706
|
+
function expandTemplatePartials(template, partials, partialStack) {
|
|
1707
|
+
let output = "";
|
|
1708
|
+
let index = 0;
|
|
1709
|
+
while (index < template.length) {
|
|
1710
|
+
const open = template.indexOf("{{", index);
|
|
1711
|
+
if (open === -1) {
|
|
1712
|
+
output += template.slice(index);
|
|
1713
|
+
break;
|
|
1714
|
+
}
|
|
1715
|
+
const parsed = parseTag(template, open);
|
|
1716
|
+
if (parsed.kind !== "partial") {
|
|
1717
|
+
output += template.slice(index, parsed.end);
|
|
1718
|
+
index = parsed.end;
|
|
1719
|
+
continue;
|
|
1720
|
+
}
|
|
1721
|
+
if (!Object.hasOwn(partials, parsed.name)) {
|
|
1722
|
+
throw new Error(`Partial "${parsed.name}" not found.`);
|
|
1723
|
+
}
|
|
1724
|
+
if (partialStack.includes(parsed.name)) {
|
|
1725
|
+
throw new Error(
|
|
1726
|
+
`Circular partial reference detected: ${[...partialStack, parsed.name].join(" -> ")}.`
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1730
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1731
|
+
}
|
|
1732
|
+
const standalone = getStandalone(template, open, parsed.end, parsed.kind);
|
|
1733
|
+
const beforePartial = standalone === void 0 ? template.slice(index, open) : template.slice(index, standalone.lineStart);
|
|
1734
|
+
const indent = standalone === void 0 ? "" : template.slice(standalone.lineStart, open);
|
|
1735
|
+
const partial = indentPartial(partials[parsed.name], indent);
|
|
1736
|
+
output += beforePartial + expandTemplatePartials(partial, partials, [...partialStack, parsed.name]);
|
|
1737
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1738
|
+
}
|
|
1739
|
+
return output;
|
|
1485
1740
|
}
|
|
1486
1741
|
function lookupName(view, name) {
|
|
1487
1742
|
if (!isPropertyContainer(view) || !hasProperty(view, name)) {
|
|
@@ -1541,22 +1796,22 @@ function hasProperty(value, key2) {
|
|
|
1541
1796
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1542
1797
|
}
|
|
1543
1798
|
|
|
1544
|
-
// ../design
|
|
1799
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1545
1800
|
import { spawn } from "node:child_process";
|
|
1546
1801
|
import process2 from "node:process";
|
|
1547
1802
|
|
|
1548
|
-
// ../design
|
|
1803
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1549
1804
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1550
1805
|
var storage = new AsyncLocalStorage2();
|
|
1551
1806
|
|
|
1552
|
-
// ../design
|
|
1807
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1553
1808
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1554
1809
|
|
|
1555
|
-
// ../design
|
|
1810
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1556
1811
|
import readline from "node:readline";
|
|
1557
1812
|
import { PassThrough } from "node:stream";
|
|
1558
1813
|
|
|
1559
|
-
// ../design
|
|
1814
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1560
1815
|
var REGION_HEADER = 1 << 0;
|
|
1561
1816
|
var REGION_LIST = 1 << 1;
|
|
1562
1817
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1565,10 +1820,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1565
1820
|
var REGION_TOAST = 1 << 5;
|
|
1566
1821
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1567
1822
|
|
|
1568
|
-
// ../design
|
|
1823
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1569
1824
|
import * as clack from "@clack/prompts";
|
|
1570
1825
|
|
|
1571
|
-
// ../design
|
|
1826
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1572
1827
|
import { isCancel } from "@clack/prompts";
|
|
1573
1828
|
function cancel(msg = "") {
|
|
1574
1829
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1579,7 +1834,7 @@ function cancel(msg = "") {
|
|
|
1579
1834
|
`);
|
|
1580
1835
|
}
|
|
1581
1836
|
|
|
1582
|
-
// ../design
|
|
1837
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1583
1838
|
function getVisibleWidth(value) {
|
|
1584
1839
|
return stripAnsi(value).length;
|
|
1585
1840
|
}
|
|
@@ -1628,10 +1883,10 @@ function note(message2, title) {
|
|
|
1628
1883
|
`);
|
|
1629
1884
|
}
|
|
1630
1885
|
|
|
1631
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1632
1887
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1633
1888
|
|
|
1634
|
-
// ../design
|
|
1889
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1635
1890
|
async function select2(opts) {
|
|
1636
1891
|
return clack.select(opts);
|
|
1637
1892
|
}
|
|
@@ -1674,19 +1929,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1674
1929
|
};
|
|
1675
1930
|
|
|
1676
1931
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1677
|
-
function validateHumanInLoopOnDefine(
|
|
1678
|
-
const label = Array.isArray(
|
|
1679
|
-
if (
|
|
1680
|
-
throw new Error(`${label} '${
|
|
1932
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
1933
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
1934
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
1935
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
1681
1936
|
}
|
|
1682
|
-
if (
|
|
1937
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1683
1938
|
return;
|
|
1684
1939
|
}
|
|
1685
|
-
if (
|
|
1686
|
-
throw new Error(`${label} '${
|
|
1940
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
1941
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
1687
1942
|
}
|
|
1688
|
-
if (typeof
|
|
1689
|
-
throw new Error(`${label} '${
|
|
1943
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
1944
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1690
1945
|
}
|
|
1691
1946
|
}
|
|
1692
1947
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1762,12 +2017,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1762
2017
|
}
|
|
1763
2018
|
}
|
|
1764
2019
|
}
|
|
1765
|
-
function OneOf(
|
|
1766
|
-
assertValidBranches(
|
|
2020
|
+
function OneOf(config2) {
|
|
2021
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1767
2022
|
return {
|
|
1768
2023
|
kind: "oneOf",
|
|
1769
|
-
discriminator:
|
|
1770
|
-
branches:
|
|
2024
|
+
discriminator: config2.discriminator,
|
|
2025
|
+
branches: config2.branches
|
|
1771
2026
|
};
|
|
1772
2027
|
}
|
|
1773
2028
|
|
|
@@ -2017,22 +2272,22 @@ function cloneStringArray(values) {
|
|
|
2017
2272
|
function cloneStringRecord(values) {
|
|
2018
2273
|
return values === void 0 ? void 0 : { ...values };
|
|
2019
2274
|
}
|
|
2020
|
-
function cloneMcpServerConfig(
|
|
2021
|
-
if (
|
|
2275
|
+
function cloneMcpServerConfig(config2) {
|
|
2276
|
+
if (config2 === void 0) {
|
|
2022
2277
|
return void 0;
|
|
2023
2278
|
}
|
|
2024
|
-
if (
|
|
2279
|
+
if (config2.transport === "stdio") {
|
|
2025
2280
|
return {
|
|
2026
2281
|
transport: "stdio",
|
|
2027
|
-
command:
|
|
2028
|
-
args: cloneStringArray(
|
|
2029
|
-
env: cloneStringRecord(
|
|
2282
|
+
command: config2.command,
|
|
2283
|
+
args: cloneStringArray(config2.args),
|
|
2284
|
+
env: cloneStringRecord(config2.env)
|
|
2030
2285
|
};
|
|
2031
2286
|
}
|
|
2032
2287
|
return {
|
|
2033
2288
|
transport: "http",
|
|
2034
|
-
url:
|
|
2035
|
-
headers: cloneStringRecord(
|
|
2289
|
+
url: config2.url,
|
|
2290
|
+
headers: cloneStringRecord(config2.headers)
|
|
2036
2291
|
};
|
|
2037
2292
|
}
|
|
2038
2293
|
function cloneRenameMap(rename5) {
|
|
@@ -2273,57 +2528,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2273
2528
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2274
2529
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2275
2530
|
}
|
|
2276
|
-
function createBaseCommand(
|
|
2531
|
+
function createBaseCommand(config2) {
|
|
2277
2532
|
const command = {
|
|
2278
2533
|
kind: "command",
|
|
2279
|
-
name:
|
|
2280
|
-
description:
|
|
2281
|
-
aliases: [...
|
|
2282
|
-
positional: [...
|
|
2283
|
-
params:
|
|
2284
|
-
secrets: cloneSecrets(
|
|
2285
|
-
scope: resolveCommandScope(
|
|
2286
|
-
confirm:
|
|
2287
|
-
humanInLoop:
|
|
2288
|
-
requires: cloneRequires(
|
|
2289
|
-
handler:
|
|
2290
|
-
render:
|
|
2534
|
+
name: config2.name,
|
|
2535
|
+
description: config2.description,
|
|
2536
|
+
aliases: [...config2.aliases ?? []],
|
|
2537
|
+
positional: [...config2.positional ?? []],
|
|
2538
|
+
params: config2.params,
|
|
2539
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2540
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
2541
|
+
confirm: config2.confirm ?? false,
|
|
2542
|
+
humanInLoop: config2.humanInLoop,
|
|
2543
|
+
requires: cloneRequires(config2.requires),
|
|
2544
|
+
handler: config2.handler,
|
|
2545
|
+
render: config2.render
|
|
2291
2546
|
};
|
|
2292
2547
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2293
2548
|
value: {
|
|
2294
|
-
scope: cloneScope(
|
|
2295
|
-
humanInLoop:
|
|
2296
|
-
secrets: cloneSecrets(
|
|
2297
|
-
requires: cloneRequires(
|
|
2549
|
+
scope: cloneScope(config2.scope),
|
|
2550
|
+
humanInLoop: config2.humanInLoop,
|
|
2551
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2552
|
+
requires: cloneRequires(config2.requires),
|
|
2298
2553
|
sourcePath: inferCommandSourcePath()
|
|
2299
2554
|
}
|
|
2300
2555
|
});
|
|
2301
2556
|
return command;
|
|
2302
2557
|
}
|
|
2303
|
-
function createBaseGroup(
|
|
2558
|
+
function createBaseGroup(config2) {
|
|
2304
2559
|
const group = {
|
|
2305
2560
|
kind: "group",
|
|
2306
|
-
name:
|
|
2307
|
-
description:
|
|
2308
|
-
aliases: [...
|
|
2309
|
-
scope: resolveGroupScope(
|
|
2310
|
-
humanInLoop:
|
|
2311
|
-
secrets: cloneSecrets(
|
|
2312
|
-
requires: cloneRequires(
|
|
2561
|
+
name: config2.name,
|
|
2562
|
+
description: config2.description,
|
|
2563
|
+
aliases: [...config2.aliases ?? []],
|
|
2564
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
2565
|
+
humanInLoop: config2.humanInLoop,
|
|
2566
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2567
|
+
requires: cloneRequires(config2.requires),
|
|
2313
2568
|
children: [],
|
|
2314
2569
|
default: void 0
|
|
2315
2570
|
};
|
|
2316
2571
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2317
2572
|
value: {
|
|
2318
|
-
mcp: cloneMcpServerConfig(
|
|
2319
|
-
scope: cloneScope(
|
|
2320
|
-
humanInLoop:
|
|
2321
|
-
secrets: cloneSecrets(
|
|
2322
|
-
tools: cloneStringArray(
|
|
2323
|
-
rename: cloneRenameMap(
|
|
2324
|
-
requires: cloneRequires(
|
|
2325
|
-
children: [...
|
|
2326
|
-
default:
|
|
2573
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
2574
|
+
scope: cloneScope(config2.scope),
|
|
2575
|
+
humanInLoop: config2.humanInLoop,
|
|
2576
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2577
|
+
tools: cloneStringArray(config2.tools),
|
|
2578
|
+
rename: cloneRenameMap(config2.rename),
|
|
2579
|
+
requires: cloneRequires(config2.requires),
|
|
2580
|
+
children: [...config2.children],
|
|
2581
|
+
default: config2.default
|
|
2327
2582
|
}
|
|
2328
2583
|
});
|
|
2329
2584
|
return group;
|
|
@@ -2426,10 +2681,10 @@ function materializeNode(node, inherited) {
|
|
|
2426
2681
|
}
|
|
2427
2682
|
return materializeGroup(node, inherited);
|
|
2428
2683
|
}
|
|
2429
|
-
function defineCommand(
|
|
2430
|
-
validateHumanInLoopOnDefine(
|
|
2684
|
+
function defineCommand(config2) {
|
|
2685
|
+
validateHumanInLoopOnDefine(config2);
|
|
2431
2686
|
return materializeCommand(
|
|
2432
|
-
createBaseCommand(
|
|
2687
|
+
createBaseCommand(config2),
|
|
2433
2688
|
{
|
|
2434
2689
|
scope: void 0,
|
|
2435
2690
|
humanInLoop: void 0,
|
|
@@ -2438,10 +2693,10 @@ function defineCommand(config) {
|
|
|
2438
2693
|
}
|
|
2439
2694
|
);
|
|
2440
2695
|
}
|
|
2441
|
-
function defineGroup(
|
|
2442
|
-
validateRenameMap(
|
|
2443
|
-
validateHumanInLoopOnDefine(
|
|
2444
|
-
return materializeGroup(createBaseGroup(
|
|
2696
|
+
function defineGroup(config2) {
|
|
2697
|
+
validateRenameMap(config2.rename);
|
|
2698
|
+
validateHumanInLoopOnDefine(config2);
|
|
2699
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2445
2700
|
scope: void 0,
|
|
2446
2701
|
humanInLoop: void 0,
|
|
2447
2702
|
secrets: {},
|
|
@@ -2602,17 +2857,22 @@ import { randomBytes } from "node:crypto";
|
|
|
2602
2857
|
// ../process-runner/src/docker/args.ts
|
|
2603
2858
|
import path2 from "node:path";
|
|
2604
2859
|
|
|
2860
|
+
// ../process-runner/src/docker/env-file.ts
|
|
2861
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2862
|
+
import { tmpdir } from "node:os";
|
|
2863
|
+
import path3 from "node:path";
|
|
2864
|
+
|
|
2605
2865
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2606
2866
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2607
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
2608
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2609
|
-
import { tmpdir } from "node:os";
|
|
2610
|
-
import
|
|
2867
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2868
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2869
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
2870
|
+
import path5 from "node:path";
|
|
2611
2871
|
|
|
2612
2872
|
// ../process-runner/src/host/host-runner.ts
|
|
2613
2873
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
2614
2874
|
function createHostRunner(options = {}) {
|
|
2615
|
-
const
|
|
2875
|
+
const detachedByDefault = options.detached === true;
|
|
2616
2876
|
return {
|
|
2617
2877
|
name: "host",
|
|
2618
2878
|
exec(spec) {
|
|
@@ -2630,18 +2890,19 @@ function createHostRunner(options = {}) {
|
|
|
2630
2890
|
const stdinMode = spec.stdin ?? "ignore";
|
|
2631
2891
|
const stdoutMode = spec.stdout ?? "pipe";
|
|
2632
2892
|
const stderrMode = spec.stderr ?? "pipe";
|
|
2893
|
+
const killProcessGroup = detachedByDefault || spec.killProcessGroup === true;
|
|
2633
2894
|
const stdio = stdinMode === "inherit" && stdoutMode === "inherit" && stderrMode === "inherit" ? "inherit" : [stdinMode, stdoutMode, stderrMode];
|
|
2634
2895
|
const child = spawnChildProcess(spec.command, spec.args ?? [], {
|
|
2635
2896
|
cwd: spec.cwd,
|
|
2636
2897
|
env: spec.env,
|
|
2637
2898
|
stdio,
|
|
2638
|
-
...
|
|
2899
|
+
...killProcessGroup ? { detached: true } : {}
|
|
2639
2900
|
});
|
|
2640
|
-
if (
|
|
2901
|
+
if (killProcessGroup) {
|
|
2641
2902
|
child.unref();
|
|
2642
2903
|
}
|
|
2643
2904
|
const kill = (signal) => {
|
|
2644
|
-
if (
|
|
2905
|
+
if (killProcessGroup && process.platform !== "win32" && child.pid !== void 0) {
|
|
2645
2906
|
process.kill(-child.pid, signal);
|
|
2646
2907
|
return;
|
|
2647
2908
|
}
|
|
@@ -2699,9 +2960,9 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
2699
2960
|
}
|
|
2700
2961
|
|
|
2701
2962
|
// ../process-runner/src/workspace-transfer.ts
|
|
2702
|
-
import { createHash } from "node:crypto";
|
|
2963
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2703
2964
|
import { promises as nodeFs } from "node:fs";
|
|
2704
|
-
import
|
|
2965
|
+
import path4 from "node:path";
|
|
2705
2966
|
|
|
2706
2967
|
// ../process-runner/src/testing/mock-runner.ts
|
|
2707
2968
|
import { Readable, Writable } from "node:stream";
|
|
@@ -2772,7 +3033,7 @@ function resolveEndpoint(options = {}) {
|
|
|
2772
3033
|
}
|
|
2773
3034
|
|
|
2774
3035
|
// ../task-list/src/backends/utils.ts
|
|
2775
|
-
import
|
|
3036
|
+
import path6 from "node:path";
|
|
2776
3037
|
function compareCreated(left, right) {
|
|
2777
3038
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
2778
3039
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -2822,12 +3083,12 @@ async function statIfExists(fs4, filePath) {
|
|
|
2822
3083
|
}
|
|
2823
3084
|
}
|
|
2824
3085
|
async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
2825
|
-
const resolvedPath =
|
|
2826
|
-
const rootPath =
|
|
2827
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
3086
|
+
const resolvedPath = path6.resolve(filePath);
|
|
3087
|
+
const rootPath = path6.parse(resolvedPath).root;
|
|
3088
|
+
const components = resolvedPath.slice(rootPath.length).split(path6.sep).filter(Boolean);
|
|
2828
3089
|
let currentPath = rootPath;
|
|
2829
3090
|
for (const component of components) {
|
|
2830
|
-
currentPath =
|
|
3091
|
+
currentPath = path6.join(currentPath, component);
|
|
2831
3092
|
try {
|
|
2832
3093
|
if ((await fs4.lstat(currentPath)).isSymbolicLink()) {
|
|
2833
3094
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
@@ -2843,7 +3104,7 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
2843
3104
|
async function writeAtomically(fs4, filePath, content) {
|
|
2844
3105
|
const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
|
|
2845
3106
|
tmpFileCounter += 1;
|
|
2846
|
-
await fs4.mkdir(
|
|
3107
|
+
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
2847
3108
|
try {
|
|
2848
3109
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
2849
3110
|
await fs4.rename(tempPath, filePath);
|
|
@@ -2859,7 +3120,7 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
2859
3120
|
}
|
|
2860
3121
|
}
|
|
2861
3122
|
async function withFileLock(fs4, lockPath, operation) {
|
|
2862
|
-
await fs4.mkdir(
|
|
3123
|
+
await fs4.mkdir(path6.dirname(lockPath), { recursive: true });
|
|
2863
3124
|
for (; ; ) {
|
|
2864
3125
|
try {
|
|
2865
3126
|
await fs4.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
@@ -3946,7 +4207,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
3946
4207
|
}
|
|
3947
4208
|
|
|
3948
4209
|
// ../task-list/src/backends/markdown-dir.ts
|
|
3949
|
-
import
|
|
4210
|
+
import path7 from "node:path";
|
|
3950
4211
|
import { parseDocument, stringify } from "yaml";
|
|
3951
4212
|
|
|
3952
4213
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -4065,16 +4326,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
4065
4326
|
};
|
|
4066
4327
|
}
|
|
4067
4328
|
function listPath(rootPath, layout, list) {
|
|
4068
|
-
return layout.kind === "single" ? rootPath :
|
|
4329
|
+
return layout.kind === "single" ? rootPath : path7.join(rootPath, list);
|
|
4069
4330
|
}
|
|
4070
4331
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
4071
|
-
return layout.kind === "single" ?
|
|
4332
|
+
return layout.kind === "single" ? path7.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path7.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
4072
4333
|
}
|
|
4073
4334
|
function activeTaskFilename(id, order, width) {
|
|
4074
4335
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
4075
4336
|
}
|
|
4076
4337
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
4077
|
-
return
|
|
4338
|
+
return path7.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
4078
4339
|
}
|
|
4079
4340
|
function isMarkdownFile(entryName) {
|
|
4080
4341
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -4200,7 +4461,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
4200
4461
|
state: frontmatter.state,
|
|
4201
4462
|
description: body,
|
|
4202
4463
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
4203
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
4464
|
+
...sourcePath !== void 0 && { sourcePath: path7.resolve(sourcePath) }
|
|
4204
4465
|
};
|
|
4205
4466
|
}
|
|
4206
4467
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -4240,7 +4501,7 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
4240
4501
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
4241
4502
|
};
|
|
4242
4503
|
}
|
|
4243
|
-
const parsedFilename = parseActiveFilename(
|
|
4504
|
+
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
4244
4505
|
const defaultName = parsedFilename?.id ?? id;
|
|
4245
4506
|
const effectiveFrontmatter = {
|
|
4246
4507
|
...frontmatter,
|
|
@@ -4269,7 +4530,7 @@ async function findTaskLocation(fs4, rootPath, layout, list, id) {
|
|
|
4269
4530
|
await rejectSymbolicLinkComponents(fs4, listDirectoryPath);
|
|
4270
4531
|
const activeName = await findActiveTaskFilename(fs4, listDirectoryPath, id);
|
|
4271
4532
|
if (activeName) {
|
|
4272
|
-
const activePath =
|
|
4533
|
+
const activePath = path7.join(listDirectoryPath, activeName);
|
|
4273
4534
|
await rejectSymbolicLinkComponents(fs4, activePath);
|
|
4274
4535
|
const activeStat = await statIfExists(fs4, activePath);
|
|
4275
4536
|
if (activeStat?.isFile()) {
|
|
@@ -4292,7 +4553,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4292
4553
|
}
|
|
4293
4554
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4294
4555
|
}
|
|
4295
|
-
function createdFrontmatter(
|
|
4556
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4296
4557
|
const frontmatter = mode !== "passthrough" ? {
|
|
4297
4558
|
$schema: TASK_SCHEMA_ID,
|
|
4298
4559
|
kind: TASK_KIND,
|
|
@@ -4304,7 +4565,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4304
4565
|
state: initialState
|
|
4305
4566
|
};
|
|
4306
4567
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4307
|
-
for (const [key2, value] of Object.entries(
|
|
4568
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4308
4569
|
if (!reservedKeys.has(key2)) {
|
|
4309
4570
|
setOwnValue(frontmatter, key2, value);
|
|
4310
4571
|
}
|
|
@@ -4391,7 +4652,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4391
4652
|
if (isHiddenEntry(entryName)) continue;
|
|
4392
4653
|
const parsed = parseActiveFilename(entryName);
|
|
4393
4654
|
if (!parsed) continue;
|
|
4394
|
-
const entryPath =
|
|
4655
|
+
const entryPath = path7.join(listDirectoryPath, entryName);
|
|
4395
4656
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4396
4657
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4397
4658
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4409,7 +4670,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4409
4670
|
const entries = await readActiveEntries();
|
|
4410
4671
|
const tasks = /* @__PURE__ */ new Map();
|
|
4411
4672
|
for (const entry of entries) {
|
|
4412
|
-
const filePath =
|
|
4673
|
+
const filePath = path7.join(listDirectoryPath, entry.filename);
|
|
4413
4674
|
const file = await readTaskFile(
|
|
4414
4675
|
deps.fs,
|
|
4415
4676
|
list,
|
|
@@ -4430,7 +4691,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4430
4691
|
const result = [];
|
|
4431
4692
|
for (const entryName of entries) {
|
|
4432
4693
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
4433
|
-
const entryPath =
|
|
4694
|
+
const entryPath = path7.join(archivePath, entryName);
|
|
4434
4695
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4435
4696
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4436
4697
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4460,12 +4721,12 @@ function createTasksView2(deps, layout, list) {
|
|
|
4460
4721
|
if (desiredOrder === void 0) continue;
|
|
4461
4722
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
4462
4723
|
if (entry.filename !== desiredFilename) {
|
|
4463
|
-
const fromPath =
|
|
4464
|
-
const stagingPath =
|
|
4724
|
+
const fromPath = path7.join(listDirectoryPath, entry.filename);
|
|
4725
|
+
const stagingPath = path7.join(
|
|
4465
4726
|
listDirectoryPath,
|
|
4466
4727
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
4467
4728
|
);
|
|
4468
|
-
const targetPath =
|
|
4729
|
+
const targetPath = path7.join(listDirectoryPath, desiredFilename);
|
|
4469
4730
|
try {
|
|
4470
4731
|
await deps.fs.rename(fromPath, stagingPath);
|
|
4471
4732
|
staged.push({ original: fromPath, staging: stagingPath, target: targetPath, finalized: false });
|
|
@@ -4614,7 +4875,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4614
4875
|
assertCreateHasId(input);
|
|
4615
4876
|
validateTaskId(input.id);
|
|
4616
4877
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
4617
|
-
return withFileLock(deps.fs,
|
|
4878
|
+
return withFileLock(deps.fs, path7.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
4618
4879
|
const existing = await findTaskLocation(deps.fs, deps.path, layout, list, input.id);
|
|
4619
4880
|
if (existing) {
|
|
4620
4881
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -4627,7 +4888,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4627
4888
|
const nextOrder = maxOrder + 1;
|
|
4628
4889
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
4629
4890
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
4630
|
-
const targetPath =
|
|
4891
|
+
const targetPath = path7.join(listDirectoryPath, filename);
|
|
4631
4892
|
const frontmatter = createdFrontmatter(
|
|
4632
4893
|
deps.defaults,
|
|
4633
4894
|
input,
|
|
@@ -4735,7 +4996,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4735
4996
|
validateTaskId(id);
|
|
4736
4997
|
const { event, nextTask } = await withFileLock(
|
|
4737
4998
|
deps.fs,
|
|
4738
|
-
|
|
4999
|
+
path7.join(listDirectoryPath, ".transition.lock"),
|
|
4739
5000
|
fireTask
|
|
4740
5001
|
);
|
|
4741
5002
|
await event.onEnter?.(nextTask);
|
|
@@ -4828,7 +5089,7 @@ async function markdownDirBackend(deps) {
|
|
|
4828
5089
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
4829
5090
|
continue;
|
|
4830
5091
|
}
|
|
4831
|
-
const entryPath =
|
|
5092
|
+
const entryPath = path7.join(deps.path, entryName);
|
|
4832
5093
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4833
5094
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4834
5095
|
if (entryStat?.isDirectory()) {
|
|
@@ -4870,7 +5131,7 @@ async function markdownDirBackend(deps) {
|
|
|
4870
5131
|
}
|
|
4871
5132
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
4872
5133
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
4873
|
-
return withFileLock(deps.fs,
|
|
5134
|
+
return withFileLock(deps.fs, path7.join(targetListDir, ".transition.lock"), async () => {
|
|
4874
5135
|
const targetExisting = await findTaskLocation(deps.fs, deps.path, layout, targetListName, id);
|
|
4875
5136
|
if (targetExisting) {
|
|
4876
5137
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
@@ -4920,7 +5181,7 @@ async function markdownDirBackend(deps) {
|
|
|
4920
5181
|
);
|
|
4921
5182
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
4922
5183
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
4923
|
-
const targetPath =
|
|
5184
|
+
const targetPath = path7.join(targetListDir, targetFilename);
|
|
4924
5185
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
4925
5186
|
return createTask(
|
|
4926
5187
|
targetListName,
|
|
@@ -4942,7 +5203,7 @@ async function markdownDirBackend(deps) {
|
|
|
4942
5203
|
}
|
|
4943
5204
|
|
|
4944
5205
|
// ../task-list/src/backends/yaml-file.ts
|
|
4945
|
-
import
|
|
5206
|
+
import path8 from "node:path";
|
|
4946
5207
|
import { isMap, parseDocument as parseDocument2 } from "yaml";
|
|
4947
5208
|
|
|
4948
5209
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -5038,7 +5299,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5038
5299
|
state: taskRecord.state,
|
|
5039
5300
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5040
5301
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5041
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5302
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5042
5303
|
};
|
|
5043
5304
|
}
|
|
5044
5305
|
function matchesFilter(task, filter) {
|
|
@@ -5050,13 +5311,13 @@ function matchesFilter(task, filter) {
|
|
|
5050
5311
|
}
|
|
5051
5312
|
return true;
|
|
5052
5313
|
}
|
|
5053
|
-
function createTaskRecord(
|
|
5314
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5054
5315
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5055
5316
|
name: input.name,
|
|
5056
5317
|
state: initialState,
|
|
5057
5318
|
description: input.description ?? ""
|
|
5058
5319
|
});
|
|
5059
|
-
for (const [key2, value] of Object.entries(
|
|
5320
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5060
5321
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5061
5322
|
taskRecord[key2] = value;
|
|
5062
5323
|
}
|
|
@@ -5603,7 +5864,7 @@ async function openGhIssuesBackend(options) {
|
|
|
5603
5864
|
|
|
5604
5865
|
// ../task-list/src/move.ts
|
|
5605
5866
|
import * as fsPromises2 from "node:fs/promises";
|
|
5606
|
-
import
|
|
5867
|
+
import path9 from "node:path";
|
|
5607
5868
|
|
|
5608
5869
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
5609
5870
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6099,13 +6360,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
6099
6360
|
}
|
|
6100
6361
|
function enumerateApprovalCommandPaths(root) {
|
|
6101
6362
|
const paths = [];
|
|
6102
|
-
const visit = (node,
|
|
6363
|
+
const visit = (node, path24) => {
|
|
6103
6364
|
if (node.kind === "command") {
|
|
6104
|
-
paths.push(
|
|
6365
|
+
paths.push(path24.join("."));
|
|
6105
6366
|
return;
|
|
6106
6367
|
}
|
|
6107
6368
|
for (const child of getVisibleCliChildren(node)) {
|
|
6108
|
-
visit(child, [...
|
|
6369
|
+
visit(child, [...path24, child.name]);
|
|
6109
6370
|
}
|
|
6110
6371
|
};
|
|
6111
6372
|
if (root.kind === "command") {
|
|
@@ -6140,21 +6401,21 @@ function createHandlerContext(command, params17) {
|
|
|
6140
6401
|
}
|
|
6141
6402
|
function createFs() {
|
|
6142
6403
|
return {
|
|
6143
|
-
readFile: async (
|
|
6144
|
-
writeFile: async (
|
|
6145
|
-
await writeFile2(
|
|
6404
|
+
readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
|
|
6405
|
+
writeFile: async (path24, contents) => {
|
|
6406
|
+
await writeFile2(path24, contents);
|
|
6146
6407
|
},
|
|
6147
|
-
exists: async (
|
|
6408
|
+
exists: async (path24) => {
|
|
6148
6409
|
try {
|
|
6149
|
-
await access(
|
|
6410
|
+
await access(path24);
|
|
6150
6411
|
return true;
|
|
6151
6412
|
} catch {
|
|
6152
6413
|
return false;
|
|
6153
6414
|
}
|
|
6154
6415
|
},
|
|
6155
|
-
lstat: async (
|
|
6416
|
+
lstat: async (path24) => lstat(path24),
|
|
6156
6417
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
6157
|
-
unlink: async (
|
|
6418
|
+
unlink: async (path24) => unlink(path24)
|
|
6158
6419
|
};
|
|
6159
6420
|
}
|
|
6160
6421
|
function createEnv(values = process.env) {
|
|
@@ -6430,17 +6691,17 @@ function isMissingStateError(error3) {
|
|
|
6430
6691
|
}
|
|
6431
6692
|
|
|
6432
6693
|
// ../toolcraft/src/error-report.ts
|
|
6433
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6434
|
-
import { randomUUID as
|
|
6694
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6695
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6435
6696
|
import os from "node:os";
|
|
6436
|
-
import
|
|
6697
|
+
import path13 from "node:path";
|
|
6437
6698
|
import { CommanderError } from "commander";
|
|
6438
6699
|
|
|
6439
6700
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6440
6701
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6441
6702
|
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6442
|
-
import
|
|
6443
|
-
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
6703
|
+
import path12 from "node:path";
|
|
6704
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
6444
6705
|
|
|
6445
6706
|
// ../tiny-mcp-client/src/internal.ts
|
|
6446
6707
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6448,13 +6709,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
6448
6709
|
|
|
6449
6710
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
6450
6711
|
import crypto from "node:crypto";
|
|
6451
|
-
import
|
|
6712
|
+
import path11 from "node:path";
|
|
6452
6713
|
|
|
6453
6714
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6454
6715
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6455
6716
|
import { promises as fs } from "node:fs";
|
|
6456
6717
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6457
|
-
import
|
|
6718
|
+
import path10 from "node:path";
|
|
6458
6719
|
var derivedKeyCache = /* @__PURE__ */ new Map();
|
|
6459
6720
|
var ENCRYPTION_ALGORITHM = "aes-256-gcm";
|
|
6460
6721
|
var ENCRYPTION_VERSION = 1;
|
|
@@ -6466,6 +6727,7 @@ var temporaryFileSequence = 0;
|
|
|
6466
6727
|
var EncryptedFileStore = class {
|
|
6467
6728
|
fs;
|
|
6468
6729
|
filePath;
|
|
6730
|
+
symbolicLinkCheckStartPath;
|
|
6469
6731
|
salt;
|
|
6470
6732
|
getMachineIdentity;
|
|
6471
6733
|
getRandomBytes;
|
|
@@ -6473,11 +6735,22 @@ var EncryptedFileStore = class {
|
|
|
6473
6735
|
constructor(input) {
|
|
6474
6736
|
this.fs = input.fs ?? fs;
|
|
6475
6737
|
this.salt = input.salt;
|
|
6476
|
-
|
|
6477
|
-
(input.getHomeDirectory ?? homedir)()
|
|
6478
|
-
input.defaultDirectory ?? ".auth-store"
|
|
6479
|
-
|
|
6480
|
-
|
|
6738
|
+
if (input.filePath === void 0) {
|
|
6739
|
+
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
6740
|
+
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
6741
|
+
this.filePath = path10.join(
|
|
6742
|
+
homeDirectory,
|
|
6743
|
+
defaultDirectory,
|
|
6744
|
+
input.defaultFileName ?? "credentials.enc"
|
|
6745
|
+
);
|
|
6746
|
+
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
6747
|
+
homeDirectory,
|
|
6748
|
+
defaultDirectory
|
|
6749
|
+
);
|
|
6750
|
+
} else {
|
|
6751
|
+
this.filePath = input.filePath;
|
|
6752
|
+
this.symbolicLinkCheckStartPath = null;
|
|
6753
|
+
}
|
|
6481
6754
|
this.getMachineIdentity = input.getMachineIdentity ?? defaultMachineIdentity;
|
|
6482
6755
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6483
6756
|
}
|
|
@@ -6528,7 +6801,7 @@ var EncryptedFileStore = class {
|
|
|
6528
6801
|
authTag: authTag.toString("base64"),
|
|
6529
6802
|
ciphertext: ciphertext.toString("base64")
|
|
6530
6803
|
};
|
|
6531
|
-
await this.fs.mkdir(
|
|
6804
|
+
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6532
6805
|
await this.assertRegularCredentialPath();
|
|
6533
6806
|
const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
|
|
6534
6807
|
try {
|
|
@@ -6557,8 +6830,11 @@ var EncryptedFileStore = class {
|
|
|
6557
6830
|
}
|
|
6558
6831
|
}
|
|
6559
6832
|
async assertRegularCredentialPath() {
|
|
6560
|
-
const resolvedPath =
|
|
6561
|
-
const protectedPaths =
|
|
6833
|
+
const resolvedPath = path10.resolve(this.filePath);
|
|
6834
|
+
const protectedPaths = getProtectedCredentialPaths(
|
|
6835
|
+
resolvedPath,
|
|
6836
|
+
this.symbolicLinkCheckStartPath
|
|
6837
|
+
);
|
|
6562
6838
|
for (const currentPath of protectedPaths) {
|
|
6563
6839
|
try {
|
|
6564
6840
|
const stats = await this.fs.lstat(currentPath);
|
|
@@ -6586,6 +6862,30 @@ var EncryptedFileStore = class {
|
|
|
6586
6862
|
return this.keyPromise;
|
|
6587
6863
|
}
|
|
6588
6864
|
};
|
|
6865
|
+
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
6866
|
+
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
6867
|
+
return path10.resolve(homeDirectory, firstSegment ?? ".");
|
|
6868
|
+
}
|
|
6869
|
+
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
6870
|
+
if (symbolicLinkCheckStartPath === null) {
|
|
6871
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6872
|
+
}
|
|
6873
|
+
const resolvedStartPath = path10.resolve(symbolicLinkCheckStartPath);
|
|
6874
|
+
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
6875
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6876
|
+
}
|
|
6877
|
+
const protectedPaths = [resolvedStartPath];
|
|
6878
|
+
let currentPath = resolvedStartPath;
|
|
6879
|
+
for (const segment of path10.relative(resolvedStartPath, resolvedPath).split(path10.sep).filter(Boolean)) {
|
|
6880
|
+
currentPath = path10.join(currentPath, segment);
|
|
6881
|
+
protectedPaths.push(currentPath);
|
|
6882
|
+
}
|
|
6883
|
+
return protectedPaths;
|
|
6884
|
+
}
|
|
6885
|
+
function isPathInsideOrEqual(childPath, parentPath) {
|
|
6886
|
+
const relativePath = path10.relative(parentPath, childPath);
|
|
6887
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
|
|
6888
|
+
}
|
|
6589
6889
|
async function removeIfPresent(fileSystem, filePath) {
|
|
6590
6890
|
try {
|
|
6591
6891
|
await fileSystem.unlink(filePath);
|
|
@@ -6736,6 +7036,17 @@ function runSecurityCommand(command, args, options) {
|
|
|
6736
7036
|
});
|
|
6737
7037
|
let stdout = "";
|
|
6738
7038
|
let stderr = "";
|
|
7039
|
+
let stdinErrorMessage;
|
|
7040
|
+
const appendStderr = (message2) => {
|
|
7041
|
+
stderr = stderr.length === 0 ? message2 : `${stderr}${stderr.endsWith("\n") ? "" : "\n"}${message2}`;
|
|
7042
|
+
};
|
|
7043
|
+
const appendStdinError = () => {
|
|
7044
|
+
if (stdinErrorMessage === void 0) {
|
|
7045
|
+
return;
|
|
7046
|
+
}
|
|
7047
|
+
appendStderr(stdinErrorMessage);
|
|
7048
|
+
stdinErrorMessage = void 0;
|
|
7049
|
+
};
|
|
6739
7050
|
child.stdout?.setEncoding("utf8");
|
|
6740
7051
|
child.stdout?.on("data", (chunk) => {
|
|
6741
7052
|
stdout += chunk.toString();
|
|
@@ -6745,17 +7056,23 @@ function runSecurityCommand(command, args, options) {
|
|
|
6745
7056
|
stderr += chunk.toString();
|
|
6746
7057
|
});
|
|
6747
7058
|
if (options?.stdin !== void 0) {
|
|
7059
|
+
child.stdin?.once("error", (error3) => {
|
|
7060
|
+
stdinErrorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
7061
|
+
});
|
|
6748
7062
|
child.stdin?.end(options.stdin);
|
|
6749
7063
|
}
|
|
6750
7064
|
child.on("error", (error3) => {
|
|
6751
7065
|
const message2 = error3 instanceof Error ? error3.message : String(error3 ?? "Unknown error");
|
|
7066
|
+
appendStdinError();
|
|
7067
|
+
appendStderr(message2);
|
|
6752
7068
|
resolve({
|
|
6753
7069
|
stdout,
|
|
6754
|
-
stderr
|
|
7070
|
+
stderr,
|
|
6755
7071
|
exitCode: 127
|
|
6756
7072
|
});
|
|
6757
7073
|
});
|
|
6758
7074
|
child.on("close", (code) => {
|
|
7075
|
+
appendStdinError();
|
|
6759
7076
|
resolve({
|
|
6760
7077
|
stdout,
|
|
6761
7078
|
stderr,
|
|
@@ -6893,19 +7210,24 @@ function createAuthStoreClientStore(options) {
|
|
|
6893
7210
|
}
|
|
6894
7211
|
};
|
|
6895
7212
|
}
|
|
6896
|
-
function createNamedSecretStore(key2, options,
|
|
7213
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
6897
7214
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
6898
|
-
const
|
|
7215
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7216
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
6899
7217
|
const fileStore = {
|
|
6900
7218
|
...options.fileStore,
|
|
6901
|
-
|
|
6902
|
-
|
|
7219
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7220
|
+
parsedFilePath.dir,
|
|
7221
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7222
|
+
),
|
|
7223
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7224
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
6903
7225
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
6904
7226
|
};
|
|
6905
7227
|
const keychainStore = {
|
|
6906
7228
|
...options.keychainStore,
|
|
6907
|
-
service: options.keychainStore?.service ??
|
|
6908
|
-
account: `${options.keychainStore?.account ??
|
|
7229
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7230
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
6909
7231
|
};
|
|
6910
7232
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
6911
7233
|
}
|
|
@@ -8478,10 +8800,19 @@ var McpClient = class {
|
|
|
8478
8800
|
}
|
|
8479
8801
|
try {
|
|
8480
8802
|
let requestId;
|
|
8803
|
+
let cancellationSent = false;
|
|
8804
|
+
const sendCancellationNotification = () => {
|
|
8805
|
+
if (requestId === void 0 || cancellationSent) {
|
|
8806
|
+
return;
|
|
8807
|
+
}
|
|
8808
|
+
cancellationSent = true;
|
|
8809
|
+
messageLayer.sendNotification("notifications/cancelled", { requestId });
|
|
8810
|
+
};
|
|
8481
8811
|
const requestPromise = messageLayer.sendRequest("tools/call", requestParams, {
|
|
8482
8812
|
onRequestId: (nextRequestId) => {
|
|
8483
8813
|
requestId = nextRequestId;
|
|
8484
|
-
}
|
|
8814
|
+
},
|
|
8815
|
+
onTimeout: sendCancellationNotification
|
|
8485
8816
|
}).then((result) => {
|
|
8486
8817
|
if (!isCallToolResult(result)) {
|
|
8487
8818
|
throw new McpError(ERROR_INVALID_REQUEST, "Invalid tool result");
|
|
@@ -8495,8 +8826,9 @@ var McpClient = class {
|
|
|
8495
8826
|
let abortListener;
|
|
8496
8827
|
const abortPromise = new Promise((_, reject) => {
|
|
8497
8828
|
const rejectWithAbortReason = () => {
|
|
8829
|
+
sendCancellationNotification();
|
|
8498
8830
|
if (requestId !== void 0) {
|
|
8499
|
-
messageLayer.
|
|
8831
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
8500
8832
|
}
|
|
8501
8833
|
reject(signal.reason);
|
|
8502
8834
|
};
|
|
@@ -8672,11 +9004,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8672
9004
|
const child = this.child;
|
|
8673
9005
|
this.readable = child.stdout;
|
|
8674
9006
|
this.writable = child.stdin;
|
|
9007
|
+
const stderrDecoder = new TextDecoder();
|
|
8675
9008
|
child.stderr.on("data", (chunk) => {
|
|
8676
|
-
|
|
8677
|
-
|
|
8678
|
-
|
|
8679
|
-
|
|
9009
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9010
|
+
this.appendStderrOutput(decoded);
|
|
9011
|
+
});
|
|
9012
|
+
child.stderr.once("end", () => {
|
|
9013
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8680
9014
|
});
|
|
8681
9015
|
this.closed = new Promise((resolve) => {
|
|
8682
9016
|
let settled = false;
|
|
@@ -8716,6 +9050,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
8716
9050
|
getStderrOutput() {
|
|
8717
9051
|
return this.stderrOutput;
|
|
8718
9052
|
}
|
|
9053
|
+
appendStderrOutput(chunk) {
|
|
9054
|
+
if (chunk.length === 0) {
|
|
9055
|
+
return;
|
|
9056
|
+
}
|
|
9057
|
+
this.stderrOutput += chunk;
|
|
9058
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9059
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9060
|
+
}
|
|
9061
|
+
}
|
|
8719
9062
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
8720
9063
|
void reason;
|
|
8721
9064
|
if (this.disposed) {
|
|
@@ -9123,15 +9466,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9123
9466
|
return `${JSON.stringify(message2)}
|
|
9124
9467
|
`;
|
|
9125
9468
|
}
|
|
9126
|
-
function chunkToString(chunk) {
|
|
9127
|
-
if (typeof chunk === "string") {
|
|
9128
|
-
return chunk;
|
|
9129
|
-
}
|
|
9130
|
-
if (chunk instanceof Uint8Array) {
|
|
9131
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9132
|
-
}
|
|
9133
|
-
return String(chunk);
|
|
9134
|
-
}
|
|
9135
9469
|
function normalizeLine(line) {
|
|
9136
9470
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9137
9471
|
}
|
|
@@ -9308,6 +9642,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9308
9642
|
return new Promise((resolve, reject) => {
|
|
9309
9643
|
const timeout = setTimeout(() => {
|
|
9310
9644
|
this.pendingRequests.delete(id);
|
|
9645
|
+
options.onTimeout?.(id);
|
|
9311
9646
|
reject(new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`));
|
|
9312
9647
|
}, timeoutMs);
|
|
9313
9648
|
this.pendingRequests.set(id, { resolve, reject, timeout });
|
|
@@ -9320,6 +9655,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9320
9655
|
}
|
|
9321
9656
|
});
|
|
9322
9657
|
}
|
|
9658
|
+
cancelRequest(requestId, reason) {
|
|
9659
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9660
|
+
if (pending === void 0) {
|
|
9661
|
+
return false;
|
|
9662
|
+
}
|
|
9663
|
+
this.pendingRequests.delete(requestId);
|
|
9664
|
+
clearTimeout(pending.timeout);
|
|
9665
|
+
pending.reject(reason);
|
|
9666
|
+
return true;
|
|
9667
|
+
}
|
|
9323
9668
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9324
9669
|
if (this.disposedError !== void 0) {
|
|
9325
9670
|
return;
|
|
@@ -9720,13 +10065,13 @@ function convertJsonSchema(schema) {
|
|
|
9720
10065
|
}
|
|
9721
10066
|
return convertSchema(schema, schema, []);
|
|
9722
10067
|
}
|
|
9723
|
-
function convertSchema(schema, root,
|
|
9724
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
10068
|
+
function convertSchema(schema, root, path24) {
|
|
10069
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path24);
|
|
9725
10070
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
9726
10071
|
const composition = getComposition(normalizedSchema.schema);
|
|
9727
10072
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
9728
10073
|
throw new Error(
|
|
9729
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10074
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
|
|
9730
10075
|
normalizedSchema.schema.type
|
|
9731
10076
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9732
10077
|
);
|
|
@@ -9738,13 +10083,13 @@ function convertSchema(schema, root, path23) {
|
|
|
9738
10083
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
9739
10084
|
}
|
|
9740
10085
|
if (composition !== void 0) {
|
|
9741
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
10086
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path24);
|
|
9742
10087
|
}
|
|
9743
10088
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
9744
10089
|
return applyMetadata(
|
|
9745
10090
|
S.Record(
|
|
9746
10091
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
9747
|
-
...
|
|
10092
|
+
...path24,
|
|
9748
10093
|
"additionalProperties"
|
|
9749
10094
|
])
|
|
9750
10095
|
),
|
|
@@ -9793,12 +10138,12 @@ function convertSchema(schema, root, path23) {
|
|
|
9793
10138
|
if (normalizedSchema.schema.items === void 0) {
|
|
9794
10139
|
throw new Error(
|
|
9795
10140
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9796
|
-
|
|
10141
|
+
path24
|
|
9797
10142
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
9798
10143
|
);
|
|
9799
10144
|
}
|
|
9800
10145
|
return S.Array(
|
|
9801
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
10146
|
+
convertSchema(normalizedSchema.schema.items, root, [...path24, "items"]),
|
|
9802
10147
|
createCommonOptions(
|
|
9803
10148
|
normalizedSchema.schema,
|
|
9804
10149
|
normalizedSchema.nullable,
|
|
@@ -9808,7 +10153,7 @@ function convertSchema(schema, root, path23) {
|
|
|
9808
10153
|
case "object":
|
|
9809
10154
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
9810
10155
|
nullable: normalizedSchema.nullable,
|
|
9811
|
-
path:
|
|
10156
|
+
path: path24
|
|
9812
10157
|
});
|
|
9813
10158
|
case "null":
|
|
9814
10159
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -9823,12 +10168,12 @@ function convertSchema(schema, root, path23) {
|
|
|
9823
10168
|
}
|
|
9824
10169
|
throw new Error(
|
|
9825
10170
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9826
|
-
|
|
10171
|
+
path24
|
|
9827
10172
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
9828
10173
|
);
|
|
9829
10174
|
}
|
|
9830
10175
|
throw new Error(
|
|
9831
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10176
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
|
|
9832
10177
|
normalizedSchema.schema.type
|
|
9833
10178
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9834
10179
|
);
|
|
@@ -9872,21 +10217,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
9872
10217
|
)
|
|
9873
10218
|
});
|
|
9874
10219
|
}
|
|
9875
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
10220
|
+
function convertCompositionSchema(schema, root, nullable, path24) {
|
|
9876
10221
|
const composition = getComposition(schema);
|
|
9877
10222
|
const branchSchemas = composition?.branches ?? [];
|
|
9878
10223
|
const keyword = composition?.keyword ?? "oneOf";
|
|
9879
10224
|
const branches = branchSchemas.map(
|
|
9880
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
10225
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path24, keyword, String(index)])
|
|
9881
10226
|
);
|
|
9882
|
-
const discriminator = findDiscriminator(branches, root,
|
|
10227
|
+
const discriminator = findDiscriminator(branches, root, path24);
|
|
9883
10228
|
if (discriminator !== void 0) {
|
|
9884
10229
|
const convertedBranches = Object.fromEntries(
|
|
9885
10230
|
branches.map((branch, index) => [
|
|
9886
10231
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
9887
10232
|
convertObjectSchema(branch, root, {
|
|
9888
10233
|
omitProperty: discriminator,
|
|
9889
|
-
path: [...
|
|
10234
|
+
path: [...path24, keyword, String(index)]
|
|
9890
10235
|
})
|
|
9891
10236
|
])
|
|
9892
10237
|
);
|
|
@@ -9905,7 +10250,7 @@ function convertCompositionSchema(schema, root, nullable, path23) {
|
|
|
9905
10250
|
S.Union(
|
|
9906
10251
|
branches.map(
|
|
9907
10252
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
9908
|
-
path: [...
|
|
10253
|
+
path: [...path24, keyword, String(index)]
|
|
9909
10254
|
})
|
|
9910
10255
|
)
|
|
9911
10256
|
),
|
|
@@ -10007,11 +10352,11 @@ function getComposition(schema) {
|
|
|
10007
10352
|
}
|
|
10008
10353
|
return void 0;
|
|
10009
10354
|
}
|
|
10010
|
-
function formatJsonSchemaPath(
|
|
10011
|
-
if (
|
|
10355
|
+
function formatJsonSchemaPath(path24) {
|
|
10356
|
+
if (path24.length === 0) {
|
|
10012
10357
|
return "#";
|
|
10013
10358
|
}
|
|
10014
|
-
return `#/${
|
|
10359
|
+
return `#/${path24.map(escapeJsonPointerSegment).join("/")}`;
|
|
10015
10360
|
}
|
|
10016
10361
|
function formatJsonSchemaType(type2) {
|
|
10017
10362
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -10027,11 +10372,11 @@ function isRecordSchema(schema) {
|
|
|
10027
10372
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
10028
10373
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
10029
10374
|
}
|
|
10030
|
-
function findDiscriminator(branches, root,
|
|
10375
|
+
function findDiscriminator(branches, root, path24) {
|
|
10031
10376
|
const [firstBranch] = branches;
|
|
10032
10377
|
if (firstBranch === void 0) {
|
|
10033
10378
|
throw new Error(
|
|
10034
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10379
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
10035
10380
|
);
|
|
10036
10381
|
}
|
|
10037
10382
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -10071,19 +10416,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
10071
10416
|
}
|
|
10072
10417
|
return void 0;
|
|
10073
10418
|
}
|
|
10074
|
-
function resolveReferencedSchema(schema, root,
|
|
10419
|
+
function resolveReferencedSchema(schema, root, path24) {
|
|
10075
10420
|
if (schema.$ref === void 0) {
|
|
10076
10421
|
return schema;
|
|
10077
10422
|
}
|
|
10078
10423
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
10079
10424
|
if (resolvedTarget === void 0) {
|
|
10080
10425
|
throw new Error(
|
|
10081
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10426
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
10082
10427
|
);
|
|
10083
10428
|
}
|
|
10084
10429
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
10085
10430
|
void ignoredRef;
|
|
10086
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
10431
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path24);
|
|
10087
10432
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
10088
10433
|
return resolvedSchema;
|
|
10089
10434
|
}
|
|
@@ -10107,9 +10452,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
10107
10452
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
10108
10453
|
};
|
|
10109
10454
|
}
|
|
10110
|
-
function hasSelfReferencingRef(schema, root,
|
|
10455
|
+
function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
10111
10456
|
const nextActivePaths = new Set(activePaths);
|
|
10112
|
-
nextActivePaths.add(
|
|
10457
|
+
nextActivePaths.add(path24);
|
|
10113
10458
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
10114
10459
|
if (localRefPath !== void 0) {
|
|
10115
10460
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -10120,13 +10465,13 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10120
10465
|
return true;
|
|
10121
10466
|
}
|
|
10122
10467
|
}
|
|
10123
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
10468
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path24}/items`, nextActivePaths)) {
|
|
10124
10469
|
return true;
|
|
10125
10470
|
}
|
|
10126
10471
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
10127
10472
|
schema.additionalProperties,
|
|
10128
10473
|
root,
|
|
10129
|
-
`${
|
|
10474
|
+
`${path24}/additionalProperties`,
|
|
10130
10475
|
nextActivePaths
|
|
10131
10476
|
)) {
|
|
10132
10477
|
return true;
|
|
@@ -10135,7 +10480,7 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10135
10480
|
if (hasSelfReferencingRef(
|
|
10136
10481
|
childSchema,
|
|
10137
10482
|
root,
|
|
10138
|
-
`${
|
|
10483
|
+
`${path24}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
10139
10484
|
nextActivePaths
|
|
10140
10485
|
)) {
|
|
10141
10486
|
return true;
|
|
@@ -10145,24 +10490,24 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10145
10490
|
if (hasSelfReferencingRef(
|
|
10146
10491
|
childSchema,
|
|
10147
10492
|
root,
|
|
10148
|
-
`${
|
|
10493
|
+
`${path24}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
10149
10494
|
nextActivePaths
|
|
10150
10495
|
)) {
|
|
10151
10496
|
return true;
|
|
10152
10497
|
}
|
|
10153
10498
|
}
|
|
10154
10499
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
10155
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10500
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/oneOf/${index}`, nextActivePaths)) {
|
|
10156
10501
|
return true;
|
|
10157
10502
|
}
|
|
10158
10503
|
}
|
|
10159
10504
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
10160
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10505
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/anyOf/${index}`, nextActivePaths)) {
|
|
10161
10506
|
return true;
|
|
10162
10507
|
}
|
|
10163
10508
|
}
|
|
10164
10509
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
10165
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10510
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/allOf/${index}`, nextActivePaths)) {
|
|
10166
10511
|
return true;
|
|
10167
10512
|
}
|
|
10168
10513
|
}
|
|
@@ -10178,14 +10523,14 @@ function getLocalRefPath(ref) {
|
|
|
10178
10523
|
return ref.startsWith("#/") ? ref : void 0;
|
|
10179
10524
|
}
|
|
10180
10525
|
function resolveLocalRef(root, ref) {
|
|
10181
|
-
const
|
|
10182
|
-
if (
|
|
10526
|
+
const path24 = getLocalRefPath(ref);
|
|
10527
|
+
if (path24 === void 0) {
|
|
10183
10528
|
return void 0;
|
|
10184
10529
|
}
|
|
10185
|
-
if (
|
|
10530
|
+
if (path24 === "#") {
|
|
10186
10531
|
return root;
|
|
10187
10532
|
}
|
|
10188
|
-
const segments =
|
|
10533
|
+
const segments = path24.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
10189
10534
|
let current = root;
|
|
10190
10535
|
for (const segment of segments) {
|
|
10191
10536
|
if (Array.isArray(current)) {
|
|
@@ -10388,10 +10733,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10388
10733
|
}
|
|
10389
10734
|
}
|
|
10390
10735
|
}
|
|
10391
|
-
function createConnection(name,
|
|
10736
|
+
function createConnection(name, config2) {
|
|
10392
10737
|
const connection = {
|
|
10393
10738
|
name,
|
|
10394
|
-
config,
|
|
10739
|
+
config: config2,
|
|
10395
10740
|
async dispose() {
|
|
10396
10741
|
shutdownDisposers.delete(connection.dispose);
|
|
10397
10742
|
connection.connecting = void 0;
|
|
@@ -10446,8 +10791,8 @@ async function readCache(cachePath) {
|
|
|
10446
10791
|
}
|
|
10447
10792
|
}
|
|
10448
10793
|
async function writeCache(cachePath, cache) {
|
|
10449
|
-
const directory =
|
|
10450
|
-
const tempPath = `${cachePath}.tmp-${
|
|
10794
|
+
const directory = path12.dirname(cachePath);
|
|
10795
|
+
const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
|
|
10451
10796
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10452
10797
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10453
10798
|
await mkdir(directory, { recursive: true });
|
|
@@ -10458,13 +10803,13 @@ async function writeCache(cachePath, cache) {
|
|
|
10458
10803
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10459
10804
|
await rename2(tempPath, cachePath);
|
|
10460
10805
|
}
|
|
10461
|
-
async function fetchCache(name,
|
|
10806
|
+
async function fetchCache(name, config2) {
|
|
10462
10807
|
const logger2 = createLogger((message2) => {
|
|
10463
10808
|
process.stderr.write(`${message2}
|
|
10464
10809
|
`);
|
|
10465
10810
|
});
|
|
10466
10811
|
logger2.info(`MCP ${name}: connecting`);
|
|
10467
|
-
const client = await dialUpstream(name,
|
|
10812
|
+
const client = await dialUpstream(name, config2);
|
|
10468
10813
|
try {
|
|
10469
10814
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10470
10815
|
const tools = [];
|
|
@@ -10483,7 +10828,7 @@ async function fetchCache(name, config) {
|
|
|
10483
10828
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10484
10829
|
version: 1,
|
|
10485
10830
|
upstream,
|
|
10486
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
10831
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10487
10832
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10488
10833
|
tools
|
|
10489
10834
|
};
|
|
@@ -10553,8 +10898,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10553
10898
|
}
|
|
10554
10899
|
async function resolveSingleProxy(group, options) {
|
|
10555
10900
|
const internal = getInternalGroupConfig2(group);
|
|
10556
|
-
const
|
|
10557
|
-
if (
|
|
10901
|
+
const config2 = internal.mcp;
|
|
10902
|
+
if (config2 === void 0) {
|
|
10558
10903
|
return;
|
|
10559
10904
|
}
|
|
10560
10905
|
const name = group.name;
|
|
@@ -10564,21 +10909,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10564
10909
|
let cache;
|
|
10565
10910
|
let shouldWriteCache = false;
|
|
10566
10911
|
if (isRefreshRequested(name, refresh)) {
|
|
10567
|
-
cache = await fetchCache(name,
|
|
10912
|
+
cache = await fetchCache(name, config2);
|
|
10568
10913
|
shouldWriteCache = true;
|
|
10569
10914
|
} else {
|
|
10570
10915
|
const storedCache = await readCache(cachePath);
|
|
10571
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
10916
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10572
10917
|
cache = storedCache;
|
|
10573
10918
|
} else {
|
|
10574
|
-
cache = await fetchCache(name,
|
|
10919
|
+
cache = await fetchCache(name, config2);
|
|
10575
10920
|
shouldWriteCache = true;
|
|
10576
10921
|
}
|
|
10577
10922
|
}
|
|
10578
10923
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10579
10924
|
validateRenameMap2(name, tools, internal.rename);
|
|
10580
10925
|
const previousConnection = getProxyConnection(group);
|
|
10581
|
-
const nextConnection = createConnection(name,
|
|
10926
|
+
const nextConnection = createConnection(name, config2);
|
|
10582
10927
|
try {
|
|
10583
10928
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10584
10929
|
if (shouldWriteCache) {
|
|
@@ -10603,11 +10948,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10603
10948
|
);
|
|
10604
10949
|
}
|
|
10605
10950
|
}
|
|
10606
|
-
function cacheMatchesConfig(cache,
|
|
10607
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
10951
|
+
function cacheMatchesConfig(cache, config2) {
|
|
10952
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10608
10953
|
}
|
|
10609
|
-
function fingerprintMcpServerConfig(
|
|
10610
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
10954
|
+
function fingerprintMcpServerConfig(config2) {
|
|
10955
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10611
10956
|
}
|
|
10612
10957
|
function collectProxyGroups(root) {
|
|
10613
10958
|
const groups = [];
|
|
@@ -10627,13 +10972,13 @@ function collectProxyGroups(root) {
|
|
|
10627
10972
|
function findProjectRoot(from = process.cwd()) {
|
|
10628
10973
|
let current = process.cwd();
|
|
10629
10974
|
if (from !== current) {
|
|
10630
|
-
current =
|
|
10975
|
+
current = path12.resolve(from);
|
|
10631
10976
|
}
|
|
10632
10977
|
while (true) {
|
|
10633
|
-
if (existsSync2(
|
|
10978
|
+
if (existsSync2(path12.join(current, "package.json"))) {
|
|
10634
10979
|
return current;
|
|
10635
10980
|
}
|
|
10636
|
-
const parent =
|
|
10981
|
+
const parent = path12.dirname(current);
|
|
10637
10982
|
if (parent === current) {
|
|
10638
10983
|
return void 0;
|
|
10639
10984
|
}
|
|
@@ -10650,7 +10995,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
10650
10995
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
10651
10996
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
10652
10997
|
}
|
|
10653
|
-
return
|
|
10998
|
+
return path12.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
10654
10999
|
}
|
|
10655
11000
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
10656
11001
|
let currentPath = filePath;
|
|
@@ -10664,10 +11009,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
10664
11009
|
throw error3;
|
|
10665
11010
|
}
|
|
10666
11011
|
}
|
|
10667
|
-
if (
|
|
11012
|
+
if (path12.basename(currentPath) === ".toolcraft") {
|
|
10668
11013
|
return;
|
|
10669
11014
|
}
|
|
10670
|
-
const parentPath =
|
|
11015
|
+
const parentPath = path12.dirname(currentPath);
|
|
10671
11016
|
if (parentPath === currentPath) {
|
|
10672
11017
|
return;
|
|
10673
11018
|
}
|
|
@@ -10685,20 +11030,20 @@ function parseRefreshEnv(value) {
|
|
|
10685
11030
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10686
11031
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10687
11032
|
}
|
|
10688
|
-
async function dialUpstream(name,
|
|
11033
|
+
async function dialUpstream(name, config2) {
|
|
10689
11034
|
const client = new McpClient({
|
|
10690
11035
|
clientInfo: {
|
|
10691
11036
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10692
11037
|
version: DEFAULT_CLIENT_INFO.version
|
|
10693
11038
|
}
|
|
10694
11039
|
});
|
|
10695
|
-
const transport =
|
|
10696
|
-
command:
|
|
10697
|
-
...
|
|
10698
|
-
...
|
|
11040
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11041
|
+
command: config2.command,
|
|
11042
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11043
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10699
11044
|
}) : new HttpTransport({
|
|
10700
|
-
url:
|
|
10701
|
-
...
|
|
11045
|
+
url: config2.url,
|
|
11046
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10702
11047
|
});
|
|
10703
11048
|
await client.connect(transport);
|
|
10704
11049
|
return client;
|
|
@@ -10708,10 +11053,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
10708
11053
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
10709
11054
|
}
|
|
10710
11055
|
|
|
11056
|
+
// ../toolcraft/src/redaction.ts
|
|
11057
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11058
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11059
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11060
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11061
|
+
function isPlainObject2(value) {
|
|
11062
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11063
|
+
}
|
|
11064
|
+
function normalizeName(name) {
|
|
11065
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11066
|
+
}
|
|
11067
|
+
function isSensitiveName(name) {
|
|
11068
|
+
const normalized = normalizeName(name);
|
|
11069
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11070
|
+
}
|
|
11071
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11072
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11073
|
+
return REDACTED_VALUE;
|
|
11074
|
+
}
|
|
11075
|
+
if (Array.isArray(value)) {
|
|
11076
|
+
if (seen.has(value)) {
|
|
11077
|
+
return "[Circular]";
|
|
11078
|
+
}
|
|
11079
|
+
seen.add(value);
|
|
11080
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11081
|
+
}
|
|
11082
|
+
if (isPlainObject2(value)) {
|
|
11083
|
+
if (seen.has(value)) {
|
|
11084
|
+
return "[Circular]";
|
|
11085
|
+
}
|
|
11086
|
+
seen.add(value);
|
|
11087
|
+
return Object.fromEntries(
|
|
11088
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11089
|
+
key2,
|
|
11090
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11091
|
+
])
|
|
11092
|
+
);
|
|
11093
|
+
}
|
|
11094
|
+
return value;
|
|
11095
|
+
}
|
|
11096
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11097
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11098
|
+
}
|
|
11099
|
+
function parseJsonObjectOrArray(value) {
|
|
11100
|
+
const trimmed = value.trim();
|
|
11101
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11102
|
+
return void 0;
|
|
11103
|
+
}
|
|
11104
|
+
try {
|
|
11105
|
+
const parsed = JSON.parse(trimmed);
|
|
11106
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11107
|
+
} catch {
|
|
11108
|
+
return void 0;
|
|
11109
|
+
}
|
|
11110
|
+
}
|
|
11111
|
+
function redactHttpBody(body) {
|
|
11112
|
+
if (typeof body === "string") {
|
|
11113
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11114
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11115
|
+
}
|
|
11116
|
+
return redactSecretLikeFields(body);
|
|
11117
|
+
}
|
|
11118
|
+
function redactHttpHeaderValue(name, value) {
|
|
11119
|
+
const normalized = normalizeName(name);
|
|
11120
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11121
|
+
return "Bearer ****";
|
|
11122
|
+
}
|
|
11123
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11124
|
+
return REDACTED_VALUE;
|
|
11125
|
+
}
|
|
11126
|
+
return value;
|
|
11127
|
+
}
|
|
11128
|
+
|
|
10711
11129
|
// ../toolcraft/src/error-report.ts
|
|
10712
11130
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
10713
|
-
|
|
10714
|
-
function isPlainObject2(value) {
|
|
11131
|
+
function isPlainObject3(value) {
|
|
10715
11132
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10716
11133
|
}
|
|
10717
11134
|
function unwrapOptional(schema) {
|
|
@@ -10721,7 +11138,7 @@ function unwrapOptional(schema) {
|
|
|
10721
11138
|
return schema;
|
|
10722
11139
|
}
|
|
10723
11140
|
function hasHttpContext(error3) {
|
|
10724
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11141
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
10725
11142
|
}
|
|
10726
11143
|
function isSkippedError(error3) {
|
|
10727
11144
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -10741,25 +11158,25 @@ function reportsEnabled(option, env) {
|
|
|
10741
11158
|
function resolveReportDir(option, projectRoot) {
|
|
10742
11159
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10743
11160
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
10744
|
-
return
|
|
11161
|
+
return path13.join(projectRoot, ".toolcraft", "errors");
|
|
10745
11162
|
}
|
|
10746
|
-
return
|
|
11163
|
+
return path13.isAbsolute(configuredDir) ? configuredDir : path13.join(projectRoot, configuredDir);
|
|
10747
11164
|
}
|
|
10748
11165
|
function reportDirMustStayWithinProject(option) {
|
|
10749
11166
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10750
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
11167
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path13.isAbsolute(configuredDir);
|
|
10751
11168
|
}
|
|
10752
11169
|
function isWithinDirectory(parent, child) {
|
|
10753
|
-
const relative =
|
|
10754
|
-
return relative === "" || !
|
|
11170
|
+
const relative = path13.relative(parent, child);
|
|
11171
|
+
return relative === "" || !path13.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path13.sep}`);
|
|
10755
11172
|
}
|
|
10756
11173
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
10757
|
-
if (!isWithinDirectory(
|
|
11174
|
+
if (!isWithinDirectory(path13.resolve(projectRoot), path13.resolve(reportDir))) {
|
|
10758
11175
|
throw new Error("Error report directory resolves outside project root.");
|
|
10759
11176
|
}
|
|
10760
11177
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
10761
|
-
|
|
10762
|
-
|
|
11178
|
+
realpath2(projectRoot),
|
|
11179
|
+
realpath2(reportDir)
|
|
10763
11180
|
]);
|
|
10764
11181
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
10765
11182
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -10805,7 +11222,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
10805
11222
|
return output.length === 0 ? "root" : output;
|
|
10806
11223
|
}
|
|
10807
11224
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
10808
|
-
const relative =
|
|
11225
|
+
const relative = path13.relative(projectRoot, absolutePath);
|
|
10809
11226
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
10810
11227
|
}
|
|
10811
11228
|
function redactValue(value) {
|
|
@@ -10814,9 +11231,24 @@ function redactValue(value) {
|
|
|
10814
11231
|
}
|
|
10815
11232
|
return `<set, ${value.length} chars>`;
|
|
10816
11233
|
}
|
|
10817
|
-
function
|
|
10818
|
-
|
|
10819
|
-
|
|
11234
|
+
function collectStringLeaves(value, output) {
|
|
11235
|
+
if (typeof value === "string") {
|
|
11236
|
+
if (value.length > 0) {
|
|
11237
|
+
output.add(value);
|
|
11238
|
+
}
|
|
11239
|
+
return;
|
|
11240
|
+
}
|
|
11241
|
+
if (Array.isArray(value)) {
|
|
11242
|
+
for (const entry of value) {
|
|
11243
|
+
collectStringLeaves(entry, output);
|
|
11244
|
+
}
|
|
11245
|
+
return;
|
|
11246
|
+
}
|
|
11247
|
+
if (isPlainObject3(value)) {
|
|
11248
|
+
for (const entry of Object.values(value)) {
|
|
11249
|
+
collectStringLeaves(entry, output);
|
|
11250
|
+
}
|
|
11251
|
+
}
|
|
10820
11252
|
}
|
|
10821
11253
|
function schemaSecretValue(schema) {
|
|
10822
11254
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -10837,7 +11269,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
10837
11269
|
return "<redacted>";
|
|
10838
11270
|
}
|
|
10839
11271
|
const unwrapped = unwrapOptional(schema);
|
|
10840
|
-
if (unwrapped.kind === "object" &&
|
|
11272
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
10841
11273
|
return Object.fromEntries(
|
|
10842
11274
|
Object.entries(value).map(([key2, childValue]) => {
|
|
10843
11275
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -10859,6 +11291,52 @@ function redactParams(params17, command) {
|
|
|
10859
11291
|
}
|
|
10860
11292
|
return redactParamsValue(params17, command.params, "");
|
|
10861
11293
|
}
|
|
11294
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11295
|
+
if (shouldRedactParam(name, schema)) {
|
|
11296
|
+
collectStringLeaves(value, output);
|
|
11297
|
+
return;
|
|
11298
|
+
}
|
|
11299
|
+
const unwrapped = unwrapOptional(schema);
|
|
11300
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11301
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11302
|
+
const childSchema = unwrapped.shape[key2];
|
|
11303
|
+
if (childSchema !== void 0) {
|
|
11304
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11305
|
+
}
|
|
11306
|
+
}
|
|
11307
|
+
return;
|
|
11308
|
+
}
|
|
11309
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11310
|
+
for (const entry of value) {
|
|
11311
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11312
|
+
}
|
|
11313
|
+
}
|
|
11314
|
+
}
|
|
11315
|
+
function createReportStringRedactor(context, env) {
|
|
11316
|
+
const values = /* @__PURE__ */ new Set();
|
|
11317
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11318
|
+
if (value !== void 0 && value.length > 0) {
|
|
11319
|
+
values.add(value);
|
|
11320
|
+
}
|
|
11321
|
+
}
|
|
11322
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11323
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11324
|
+
if (value !== void 0 && value.length > 0) {
|
|
11325
|
+
values.add(value);
|
|
11326
|
+
}
|
|
11327
|
+
}
|
|
11328
|
+
if (context.command !== void 0) {
|
|
11329
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11330
|
+
}
|
|
11331
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11332
|
+
return (value) => {
|
|
11333
|
+
let redacted = value;
|
|
11334
|
+
for (const secretValue of orderedValues) {
|
|
11335
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11336
|
+
}
|
|
11337
|
+
return redacted;
|
|
11338
|
+
};
|
|
11339
|
+
}
|
|
10862
11340
|
function commandSecretEnvNames(secrets) {
|
|
10863
11341
|
if (secrets === void 0) {
|
|
10864
11342
|
return [];
|
|
@@ -10912,28 +11390,42 @@ function redactArgv(argv, options) {
|
|
|
10912
11390
|
function stableJson(value) {
|
|
10913
11391
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
10914
11392
|
}
|
|
10915
|
-
function redactStructuredErrorField(name, value) {
|
|
10916
|
-
if (typeof value === "string"
|
|
10917
|
-
|
|
11393
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11394
|
+
if (typeof value === "string") {
|
|
11395
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11396
|
+
if (redactedHeaderValue !== value) {
|
|
11397
|
+
return redactedHeaderValue;
|
|
11398
|
+
}
|
|
11399
|
+
if (isSensitiveName(name)) {
|
|
11400
|
+
return "<redacted>";
|
|
11401
|
+
}
|
|
11402
|
+
return redactString(value);
|
|
10918
11403
|
}
|
|
10919
11404
|
if (Array.isArray(value)) {
|
|
10920
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11405
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
10921
11406
|
}
|
|
10922
|
-
if (
|
|
11407
|
+
if (isPlainObject3(value)) {
|
|
10923
11408
|
return Object.fromEntries(
|
|
10924
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11409
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11410
|
+
key2,
|
|
11411
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11412
|
+
])
|
|
10925
11413
|
);
|
|
10926
11414
|
}
|
|
10927
11415
|
return value;
|
|
10928
11416
|
}
|
|
10929
|
-
function ownStructuredFields(error3) {
|
|
11417
|
+
function ownStructuredFields(error3, redactString) {
|
|
10930
11418
|
const fields = {};
|
|
10931
11419
|
for (const key2 of Object.keys(error3)) {
|
|
10932
11420
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
10933
11421
|
continue;
|
|
10934
11422
|
}
|
|
10935
11423
|
Object.defineProperty(fields, key2, {
|
|
10936
|
-
value: redactStructuredErrorField(
|
|
11424
|
+
value: redactStructuredErrorField(
|
|
11425
|
+
key2,
|
|
11426
|
+
error3[key2],
|
|
11427
|
+
redactString
|
|
11428
|
+
),
|
|
10937
11429
|
enumerable: true,
|
|
10938
11430
|
configurable: true,
|
|
10939
11431
|
writable: true
|
|
@@ -10941,43 +11433,44 @@ function ownStructuredFields(error3) {
|
|
|
10941
11433
|
}
|
|
10942
11434
|
return fields;
|
|
10943
11435
|
}
|
|
10944
|
-
function formatStackChain(error3) {
|
|
11436
|
+
function formatStackChain(error3, redactString) {
|
|
10945
11437
|
const lines = [];
|
|
10946
11438
|
let current = error3;
|
|
10947
11439
|
let index = 0;
|
|
10948
11440
|
while (current !== void 0) {
|
|
10949
11441
|
if (current instanceof Error) {
|
|
10950
|
-
|
|
10951
|
-
|
|
10952
|
-
);
|
|
11442
|
+
const stack = current.stack ?? String(current);
|
|
11443
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
10953
11444
|
current = current.cause;
|
|
10954
11445
|
} else {
|
|
10955
|
-
|
|
11446
|
+
const message2 = String(current);
|
|
11447
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
10956
11448
|
current = void 0;
|
|
10957
11449
|
}
|
|
10958
11450
|
index += 1;
|
|
10959
11451
|
}
|
|
10960
11452
|
return lines.join("\n");
|
|
10961
11453
|
}
|
|
10962
|
-
function formatHeaderValue(name, value) {
|
|
10963
|
-
return name
|
|
11454
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11455
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
10964
11456
|
}
|
|
10965
|
-
function formatHeaders(headers) {
|
|
10966
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11457
|
+
function formatHeaders(headers, redactString) {
|
|
11458
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
10967
11459
|
}
|
|
10968
|
-
function formatBody(body) {
|
|
10969
|
-
|
|
10970
|
-
|
|
11460
|
+
function formatBody(body, redactString) {
|
|
11461
|
+
const redactedBody = redactHttpBody(body);
|
|
11462
|
+
if (typeof redactedBody === "string") {
|
|
11463
|
+
return redactString(redactedBody);
|
|
10971
11464
|
}
|
|
10972
|
-
return stableJson(
|
|
11465
|
+
return redactString(stableJson(redactedBody));
|
|
10973
11466
|
}
|
|
10974
|
-
function formatHttpTranscript(error3) {
|
|
11467
|
+
function formatHttpTranscript(error3, redactString) {
|
|
10975
11468
|
const requestLines = [
|
|
10976
11469
|
`${error3.request.method} ${error3.request.url}`,
|
|
10977
|
-
formatHeaders(error3.request.headers)
|
|
11470
|
+
formatHeaders(error3.request.headers, redactString)
|
|
10978
11471
|
].filter((line) => line.length > 0);
|
|
10979
11472
|
if (error3.request.body !== void 0) {
|
|
10980
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11473
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
10981
11474
|
}
|
|
10982
11475
|
return [
|
|
10983
11476
|
"Request:",
|
|
@@ -10985,9 +11478,9 @@ function formatHttpTranscript(error3) {
|
|
|
10985
11478
|
"",
|
|
10986
11479
|
"Response:",
|
|
10987
11480
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
10988
|
-
formatHeaders(error3.response.headers),
|
|
11481
|
+
formatHeaders(error3.response.headers, redactString),
|
|
10989
11482
|
"",
|
|
10990
|
-
formatBody(error3.response.body)
|
|
11483
|
+
formatBody(error3.response.body, redactString)
|
|
10991
11484
|
].join("\n");
|
|
10992
11485
|
}
|
|
10993
11486
|
function resolveToolcraftVersion(version) {
|
|
@@ -10996,9 +11489,10 @@ function resolveToolcraftVersion(version) {
|
|
|
10996
11489
|
function buildReport(context) {
|
|
10997
11490
|
const env = context.env ?? process.env;
|
|
10998
11491
|
const error3 = context.error;
|
|
11492
|
+
const redactString = createReportStringRedactor(context, env);
|
|
10999
11493
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11000
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11001
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11494
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11495
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11002
11496
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11003
11497
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11004
11498
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11012,7 +11506,9 @@ function buildReport(context) {
|
|
|
11012
11506
|
`platform: ${process.platform} ${process.arch}`,
|
|
11013
11507
|
"",
|
|
11014
11508
|
"Argv",
|
|
11015
|
-
|
|
11509
|
+
redactString(
|
|
11510
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11511
|
+
),
|
|
11016
11512
|
"",
|
|
11017
11513
|
"Resolved Secrets",
|
|
11018
11514
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11021,19 +11517,19 @@ function buildReport(context) {
|
|
|
11021
11517
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11022
11518
|
"",
|
|
11023
11519
|
"Parsed Params",
|
|
11024
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11520
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11025
11521
|
"",
|
|
11026
11522
|
"Error",
|
|
11027
11523
|
`name: ${errorName}`,
|
|
11028
11524
|
`message: ${errorMessage}`,
|
|
11029
11525
|
"structured fields:",
|
|
11030
|
-
stableJson(structuredFields),
|
|
11526
|
+
redactString(stableJson(structuredFields)),
|
|
11031
11527
|
"",
|
|
11032
11528
|
"Stack",
|
|
11033
|
-
formatStackChain(error3)
|
|
11529
|
+
formatStackChain(error3, redactString)
|
|
11034
11530
|
];
|
|
11035
11531
|
if (hasHttpContext(error3)) {
|
|
11036
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11532
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11037
11533
|
}
|
|
11038
11534
|
return `${lines.join("\n")}
|
|
11039
11535
|
`;
|
|
@@ -11045,8 +11541,8 @@ async function writeErrorReport(context) {
|
|
|
11045
11541
|
}
|
|
11046
11542
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11047
11543
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11048
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11049
|
-
const absolutePath =
|
|
11544
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
|
|
11545
|
+
const absolutePath = path13.join(reportDir, fileName);
|
|
11050
11546
|
await mkdir2(reportDir, { recursive: true });
|
|
11051
11547
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
11052
11548
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -11493,6 +11989,7 @@ ${rendered.join("\n")}`);
|
|
|
11493
11989
|
}
|
|
11494
11990
|
|
|
11495
11991
|
// ../toolcraft/src/cli.ts
|
|
11992
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11496
11993
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11497
11994
|
"params",
|
|
11498
11995
|
"secrets",
|
|
@@ -11510,7 +12007,7 @@ function inferProgramName(argv) {
|
|
|
11510
12007
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
11511
12008
|
return "toolcraft";
|
|
11512
12009
|
}
|
|
11513
|
-
const parsed =
|
|
12010
|
+
const parsed = path14.parse(entrypoint);
|
|
11514
12011
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
11515
12012
|
}
|
|
11516
12013
|
function normalizeRoots(roots, argv) {
|
|
@@ -11568,11 +12065,11 @@ function formatSegment(segment, casing) {
|
|
|
11568
12065
|
const separator = casing === "snake" ? "_" : "-";
|
|
11569
12066
|
return splitWords3(segment).join(separator);
|
|
11570
12067
|
}
|
|
11571
|
-
function toOptionFlag(
|
|
11572
|
-
return `--${
|
|
12068
|
+
function toOptionFlag(path24, casing) {
|
|
12069
|
+
return `--${path24.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
11573
12070
|
}
|
|
11574
|
-
function toOptionAttribute(
|
|
11575
|
-
return
|
|
12071
|
+
function toOptionAttribute(path24, casing) {
|
|
12072
|
+
return path24.map((segment) => {
|
|
11576
12073
|
const formatted = formatSegment(segment, casing);
|
|
11577
12074
|
if (casing === "snake") {
|
|
11578
12075
|
return formatted;
|
|
@@ -11583,23 +12080,23 @@ function toOptionAttribute(path23, casing) {
|
|
|
11583
12080
|
).join("");
|
|
11584
12081
|
}).join(".");
|
|
11585
12082
|
}
|
|
11586
|
-
function toDisplayPath(
|
|
11587
|
-
return
|
|
12083
|
+
function toDisplayPath(path24) {
|
|
12084
|
+
return path24.join(".");
|
|
11588
12085
|
}
|
|
11589
|
-
function toUnionKindControlPath(
|
|
11590
|
-
if (
|
|
12086
|
+
function toUnionKindControlPath(path24) {
|
|
12087
|
+
if (path24.length === 0) {
|
|
11591
12088
|
return ["kind"];
|
|
11592
12089
|
}
|
|
11593
|
-
const head =
|
|
11594
|
-
const tail =
|
|
12090
|
+
const head = path24.slice(0, -1);
|
|
12091
|
+
const tail = path24[path24.length - 1] ?? "";
|
|
11595
12092
|
return [...head, `${tail}Kind`];
|
|
11596
12093
|
}
|
|
11597
|
-
function toUnionKindDisplayPath(
|
|
11598
|
-
if (
|
|
12094
|
+
function toUnionKindDisplayPath(path24) {
|
|
12095
|
+
if (path24.length === 0) {
|
|
11599
12096
|
return "kind";
|
|
11600
12097
|
}
|
|
11601
|
-
const head =
|
|
11602
|
-
const tail =
|
|
12098
|
+
const head = path24.slice(0, -1);
|
|
12099
|
+
const tail = path24[path24.length - 1] ?? "";
|
|
11603
12100
|
return [...head, `${tail}-kind`].join(".");
|
|
11604
12101
|
}
|
|
11605
12102
|
function createSyntheticEnumSchema(values) {
|
|
@@ -11615,14 +12112,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
11615
12112
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
11616
12113
|
return requiredKeys.join("+");
|
|
11617
12114
|
}
|
|
11618
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
12115
|
+
function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inheritedOptional = false, variantContext) {
|
|
11619
12116
|
const collected = {
|
|
11620
12117
|
dynamicFields: [],
|
|
11621
12118
|
fields: [],
|
|
11622
12119
|
variants: []
|
|
11623
12120
|
};
|
|
11624
12121
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
11625
|
-
const nextPath = [...
|
|
12122
|
+
const nextPath = [...path24, key2];
|
|
11626
12123
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
11627
12124
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
11628
12125
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -11803,9 +12300,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path23 = [], inher
|
|
|
11803
12300
|
}
|
|
11804
12301
|
return collected;
|
|
11805
12302
|
}
|
|
11806
|
-
function toCommanderOptionAttribute(
|
|
11807
|
-
const optionAttribute = toOptionAttribute(
|
|
11808
|
-
const optionFlag = toOptionFlag(
|
|
12303
|
+
function toCommanderOptionAttribute(path24, casing, globalLongOptionFlags) {
|
|
12304
|
+
const optionAttribute = toOptionAttribute(path24, casing);
|
|
12305
|
+
const optionFlag = toOptionFlag(path24, casing);
|
|
11809
12306
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
11810
12307
|
return optionAttribute;
|
|
11811
12308
|
}
|
|
@@ -12774,10 +13271,10 @@ function parseDebugStackMode(value) {
|
|
|
12774
13271
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
12775
13272
|
);
|
|
12776
13273
|
}
|
|
12777
|
-
function setNestedValue(target,
|
|
13274
|
+
function setNestedValue(target, path24, value) {
|
|
12778
13275
|
let cursor = target;
|
|
12779
|
-
for (let index = 0; index <
|
|
12780
|
-
const segment =
|
|
13276
|
+
for (let index = 0; index < path24.length - 1; index += 1) {
|
|
13277
|
+
const segment = path24[index] ?? "";
|
|
12781
13278
|
const existing = Object.prototype.hasOwnProperty.call(cursor, segment) ? cursor[segment] : void 0;
|
|
12782
13279
|
if (typeof existing === "object" && existing !== null) {
|
|
12783
13280
|
cursor = existing;
|
|
@@ -12792,7 +13289,7 @@ function setNestedValue(target, path23, value) {
|
|
|
12792
13289
|
});
|
|
12793
13290
|
cursor = next;
|
|
12794
13291
|
}
|
|
12795
|
-
const leaf =
|
|
13292
|
+
const leaf = path24[path24.length - 1];
|
|
12796
13293
|
if (leaf !== void 0) {
|
|
12797
13294
|
Object.defineProperty(cursor, leaf, {
|
|
12798
13295
|
value,
|
|
@@ -12902,21 +13399,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
12902
13399
|
}
|
|
12903
13400
|
function createFs2() {
|
|
12904
13401
|
return {
|
|
12905
|
-
readFile: async (
|
|
12906
|
-
writeFile: async (
|
|
12907
|
-
await writeFile5(
|
|
13402
|
+
readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
|
|
13403
|
+
writeFile: async (path24, contents) => {
|
|
13404
|
+
await writeFile5(path24, contents);
|
|
12908
13405
|
},
|
|
12909
|
-
exists: async (
|
|
13406
|
+
exists: async (path24) => {
|
|
12910
13407
|
try {
|
|
12911
|
-
await access2(
|
|
13408
|
+
await access2(path24);
|
|
12912
13409
|
return true;
|
|
12913
13410
|
} catch {
|
|
12914
13411
|
return false;
|
|
12915
13412
|
}
|
|
12916
13413
|
},
|
|
12917
|
-
lstat: async (
|
|
13414
|
+
lstat: async (path24) => lstat3(path24),
|
|
12918
13415
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
12919
|
-
unlink: async (
|
|
13416
|
+
unlink: async (path24) => unlink2(path24)
|
|
12920
13417
|
};
|
|
12921
13418
|
}
|
|
12922
13419
|
function createEnv2(values = process.env) {
|
|
@@ -12926,15 +13423,15 @@ function createEnv2(values = process.env) {
|
|
|
12926
13423
|
}
|
|
12927
13424
|
};
|
|
12928
13425
|
}
|
|
12929
|
-
function
|
|
13426
|
+
function isPlainObject4(value) {
|
|
12930
13427
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12931
13428
|
}
|
|
12932
13429
|
function hasFieldValue(value) {
|
|
12933
13430
|
return value !== void 0;
|
|
12934
13431
|
}
|
|
12935
|
-
function hasNestedField(fields,
|
|
13432
|
+
function hasNestedField(fields, path24) {
|
|
12936
13433
|
return fields.some(
|
|
12937
|
-
(field) =>
|
|
13434
|
+
(field) => path24.length < field.path.length && path24.every((segment, index) => field.path[index] === segment)
|
|
12938
13435
|
);
|
|
12939
13436
|
}
|
|
12940
13437
|
function describeExpectedPresetValue(schema) {
|
|
@@ -13035,14 +13532,14 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13035
13532
|
{ cause: error3 }
|
|
13036
13533
|
);
|
|
13037
13534
|
}
|
|
13038
|
-
if (!
|
|
13535
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13039
13536
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13040
13537
|
}
|
|
13041
13538
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
13042
13539
|
const presetValues = {};
|
|
13043
|
-
function visitObject(current,
|
|
13540
|
+
function visitObject(current, path24) {
|
|
13044
13541
|
for (const [key2, value] of Object.entries(current)) {
|
|
13045
|
-
const nextPath = [...
|
|
13542
|
+
const nextPath = [...path24, key2];
|
|
13046
13543
|
const displayPath = toDisplayPath(nextPath);
|
|
13047
13544
|
const field = fieldByPath.get(displayPath);
|
|
13048
13545
|
if (field !== void 0) {
|
|
@@ -13054,7 +13551,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13054
13551
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13055
13552
|
);
|
|
13056
13553
|
}
|
|
13057
|
-
if (!
|
|
13554
|
+
if (!isPlainObject4(value)) {
|
|
13058
13555
|
throw new UserError(
|
|
13059
13556
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13060
13557
|
);
|
|
@@ -13097,8 +13594,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13097
13594
|
}
|
|
13098
13595
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13099
13596
|
}
|
|
13100
|
-
if (
|
|
13101
|
-
if (!
|
|
13597
|
+
if (isPlainObject4(expected)) {
|
|
13598
|
+
if (!isPlainObject4(actual)) {
|
|
13102
13599
|
return false;
|
|
13103
13600
|
}
|
|
13104
13601
|
return Object.entries(expected).every(
|
|
@@ -13161,9 +13658,9 @@ function createFixtureFetch(entries) {
|
|
|
13161
13658
|
};
|
|
13162
13659
|
}
|
|
13163
13660
|
function createFixtureFs(definition) {
|
|
13164
|
-
const fsDefinition =
|
|
13165
|
-
const readFileEntries =
|
|
13166
|
-
const existsEntries =
|
|
13661
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13662
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13663
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13167
13664
|
return {
|
|
13168
13665
|
readFile: async (filePath) => {
|
|
13169
13666
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13186,10 +13683,10 @@ function createFixtureFs(definition) {
|
|
|
13186
13683
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13187
13684
|
if (Array.isArray(definition)) {
|
|
13188
13685
|
for (const entry of definition) {
|
|
13189
|
-
if (!
|
|
13686
|
+
if (!isPlainObject4(entry)) {
|
|
13190
13687
|
continue;
|
|
13191
13688
|
}
|
|
13192
|
-
const explicitMatcher =
|
|
13689
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13193
13690
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13194
13691
|
Object.entries(entry).filter(
|
|
13195
13692
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13201,7 +13698,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13201
13698
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13202
13699
|
} else if (Object.keys(matcher).length === 0) {
|
|
13203
13700
|
matched = true;
|
|
13204
|
-
} else if (
|
|
13701
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13205
13702
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13206
13703
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13207
13704
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13222,7 +13719,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13222
13719
|
return Promise.resolve(null);
|
|
13223
13720
|
}
|
|
13224
13721
|
}
|
|
13225
|
-
if (
|
|
13722
|
+
if (isPlainObject4(definition)) {
|
|
13226
13723
|
const firstArg = args[0];
|
|
13227
13724
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13228
13725
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13234,7 +13731,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13234
13731
|
return Promise.resolve(null);
|
|
13235
13732
|
}
|
|
13236
13733
|
function createFixtureService(definition) {
|
|
13237
|
-
const methods =
|
|
13734
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13238
13735
|
return new Proxy(
|
|
13239
13736
|
{},
|
|
13240
13737
|
{
|
|
@@ -13249,8 +13746,8 @@ function createFixtureService(definition) {
|
|
|
13249
13746
|
);
|
|
13250
13747
|
}
|
|
13251
13748
|
function resolveFixturePath(commandPath) {
|
|
13252
|
-
const parsed =
|
|
13253
|
-
return
|
|
13749
|
+
const parsed = path14.parse(commandPath);
|
|
13750
|
+
return path14.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
13254
13751
|
}
|
|
13255
13752
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
13256
13753
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -13332,7 +13829,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13332
13829
|
};
|
|
13333
13830
|
}
|
|
13334
13831
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13335
|
-
const scenarioServices =
|
|
13832
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13336
13833
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13337
13834
|
...Object.keys(services),
|
|
13338
13835
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13384,8 +13881,8 @@ function validateServices(services) {
|
|
|
13384
13881
|
}
|
|
13385
13882
|
}
|
|
13386
13883
|
}
|
|
13387
|
-
function getNestedValue(target,
|
|
13388
|
-
return
|
|
13884
|
+
function getNestedValue(target, path24) {
|
|
13885
|
+
return path24.reduce(
|
|
13389
13886
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
13390
13887
|
target
|
|
13391
13888
|
);
|
|
@@ -13614,7 +14111,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13614
14111
|
if (itemSchema.kind !== "object") {
|
|
13615
14112
|
return value;
|
|
13616
14113
|
}
|
|
13617
|
-
if (!
|
|
14114
|
+
if (!isPlainObject4(value)) {
|
|
13618
14115
|
errors2.push({
|
|
13619
14116
|
path: displayPath,
|
|
13620
14117
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13649,7 +14146,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13649
14146
|
);
|
|
13650
14147
|
}
|
|
13651
14148
|
case "object": {
|
|
13652
|
-
if (!
|
|
14149
|
+
if (!isPlainObject4(value)) {
|
|
13653
14150
|
errors2.push({
|
|
13654
14151
|
path: displayPath,
|
|
13655
14152
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13680,7 +14177,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13680
14177
|
return result;
|
|
13681
14178
|
}
|
|
13682
14179
|
case "record": {
|
|
13683
|
-
if (!
|
|
14180
|
+
if (!isPlainObject4(value)) {
|
|
13684
14181
|
errors2.push({
|
|
13685
14182
|
path: displayPath,
|
|
13686
14183
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14106,10 +14603,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14106
14603
|
}
|
|
14107
14604
|
}
|
|
14108
14605
|
function isStringRecord(value) {
|
|
14109
|
-
return
|
|
14606
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14110
14607
|
}
|
|
14111
14608
|
function isHttpErrorLike(error3) {
|
|
14112
|
-
if (!
|
|
14609
|
+
if (!isPlainObject4(error3)) {
|
|
14113
14610
|
return false;
|
|
14114
14611
|
}
|
|
14115
14612
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14117,7 +14614,7 @@ function isHttpErrorLike(error3) {
|
|
|
14117
14614
|
}
|
|
14118
14615
|
const request = error3.request;
|
|
14119
14616
|
const response = error3.response;
|
|
14120
|
-
return
|
|
14617
|
+
return isPlainObject4(request) && typeof request.method === "string" && typeof request.url === "string" && isStringRecord(request.headers) && isPlainObject4(response) && typeof response.status === "number" && typeof response.statusText === "string" && isStringRecord(response.headers) && "body" in response;
|
|
14121
14618
|
}
|
|
14122
14619
|
function hasTypedOptionalField(value, field, type2) {
|
|
14123
14620
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14126,7 +14623,7 @@ function isNonEmptyString(value) {
|
|
|
14126
14623
|
return typeof value === "string" && value.trim().length > 0;
|
|
14127
14624
|
}
|
|
14128
14625
|
function isProblemDetailsLike(body) {
|
|
14129
|
-
if (!
|
|
14626
|
+
if (!isPlainObject4(body)) {
|
|
14130
14627
|
return false;
|
|
14131
14628
|
}
|
|
14132
14629
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14147,11 +14644,11 @@ function isProblemDetailsLike(body) {
|
|
|
14147
14644
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14148
14645
|
}
|
|
14149
14646
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14150
|
-
if (!
|
|
14647
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14151
14648
|
return false;
|
|
14152
14649
|
}
|
|
14153
14650
|
return body.errors.every((error3) => {
|
|
14154
|
-
if (!
|
|
14651
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14155
14652
|
return false;
|
|
14156
14653
|
}
|
|
14157
14654
|
if ("path" in error3) {
|
|
@@ -14161,7 +14658,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14161
14658
|
}
|
|
14162
14659
|
}
|
|
14163
14660
|
if ("extensions" in error3) {
|
|
14164
|
-
if (!
|
|
14661
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14165
14662
|
return false;
|
|
14166
14663
|
}
|
|
14167
14664
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14209,23 +14706,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14209
14706
|
}).join("\n\n");
|
|
14210
14707
|
}
|
|
14211
14708
|
function formatHttpErrorBody(body) {
|
|
14212
|
-
|
|
14213
|
-
|
|
14709
|
+
const redactedBody = redactHttpBody(body);
|
|
14710
|
+
if (typeof redactedBody === "string") {
|
|
14711
|
+
return redactedBody;
|
|
14214
14712
|
}
|
|
14215
|
-
if (isProblemDetailsLike(
|
|
14216
|
-
return formatProblemDetailsBody(
|
|
14713
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
14714
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14217
14715
|
}
|
|
14218
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14219
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
14716
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
14717
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14220
14718
|
}
|
|
14221
|
-
const serialized = JSON.stringify(
|
|
14222
|
-
return serialized === void 0 ? String(
|
|
14719
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
14720
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14223
14721
|
}
|
|
14224
14722
|
function indentHttpErrorBlock(value) {
|
|
14225
14723
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14226
14724
|
}
|
|
14227
14725
|
function formatHttpHeaderValue(name, value) {
|
|
14228
|
-
return name
|
|
14726
|
+
return redactHttpHeaderValue(name, value);
|
|
14229
14727
|
}
|
|
14230
14728
|
function formatHttpErrorHeaders(headers) {
|
|
14231
14729
|
return Object.entries(headers).map(
|
|
@@ -14243,7 +14741,11 @@ function renderHttpError(error3, options) {
|
|
|
14243
14741
|
if (detailed) {
|
|
14244
14742
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14245
14743
|
if (error3.request.body !== void 0) {
|
|
14246
|
-
lines.push(
|
|
14744
|
+
lines.push(
|
|
14745
|
+
"Request body:",
|
|
14746
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
14747
|
+
""
|
|
14748
|
+
);
|
|
14247
14749
|
}
|
|
14248
14750
|
}
|
|
14249
14751
|
lines.push(
|
|
@@ -14536,7 +15038,8 @@ function configureCommanderSuggestionOutput(command) {
|
|
|
14536
15038
|
}
|
|
14537
15039
|
async function runCLI(roots, options = {}) {
|
|
14538
15040
|
enableSourceMaps();
|
|
14539
|
-
const
|
|
15041
|
+
const normalizedRoot = normalizeRoots(roots, process.argv);
|
|
15042
|
+
const root = options.approvals === false ? normalizedRoot : mergeApprovalsGroup(normalizedRoot);
|
|
14540
15043
|
await resolveMcpProxies(root, { projectRoot: options.projectRoot });
|
|
14541
15044
|
const casing = options.casing ?? "kebab";
|
|
14542
15045
|
const services = options.services ?? {};
|
|
@@ -14648,7 +15151,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14648
15151
|
}
|
|
14649
15152
|
|
|
14650
15153
|
// src/terminal-pilot.ts
|
|
14651
|
-
import { randomUUID as
|
|
15154
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
14652
15155
|
|
|
14653
15156
|
// src/terminal-session.ts
|
|
14654
15157
|
import { EventEmitter } from "node:events";
|
|
@@ -14667,7 +15170,7 @@ var DCS = 144;
|
|
|
14667
15170
|
var SOS = 152;
|
|
14668
15171
|
var PM = 158;
|
|
14669
15172
|
var APC = 159;
|
|
14670
|
-
function
|
|
15173
|
+
function stripAnsi4(input) {
|
|
14671
15174
|
let output = "";
|
|
14672
15175
|
for (let index = 0; index < input.length; index += 1) {
|
|
14673
15176
|
const code = input.charCodeAt(index);
|
|
@@ -15547,7 +16050,7 @@ var TerminalScreen = class {
|
|
|
15547
16050
|
cursor,
|
|
15548
16051
|
size
|
|
15549
16052
|
}) {
|
|
15550
|
-
this.lines = Object.freeze(lines.map((line) =>
|
|
16053
|
+
this.lines = Object.freeze(lines.map((line) => stripAnsi4(line)));
|
|
15551
16054
|
this.rawLines = Object.freeze([...rawLines]);
|
|
15552
16055
|
this.cursor = Object.freeze({ ...cursor });
|
|
15553
16056
|
this.size = Object.freeze({ ...size });
|
|
@@ -15702,7 +16205,7 @@ var TerminalSession = class {
|
|
|
15702
16205
|
});
|
|
15703
16206
|
}
|
|
15704
16207
|
async history(opts) {
|
|
15705
|
-
const normalized = normalizeHistoryBuffer(
|
|
16208
|
+
const normalized = normalizeHistoryBuffer(stripAnsi4(this.rawBuffer));
|
|
15706
16209
|
const lines = splitHistoryLines(normalized);
|
|
15707
16210
|
if (opts?.last === void 0) {
|
|
15708
16211
|
return lines;
|
|
@@ -15835,7 +16338,7 @@ function isMissingFileError(error3) {
|
|
|
15835
16338
|
return "code" in error3 && error3.code === "ENOENT";
|
|
15836
16339
|
}
|
|
15837
16340
|
function matchPattern(buffer, pattern) {
|
|
15838
|
-
const clean = normalizeHistoryBuffer(
|
|
16341
|
+
const clean = normalizeHistoryBuffer(stripAnsi4(buffer));
|
|
15839
16342
|
for (const line of clean.split("\n")) {
|
|
15840
16343
|
if (typeof pattern === "string") {
|
|
15841
16344
|
if (line.includes(pattern)) return line;
|
|
@@ -15923,7 +16426,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
15923
16426
|
}
|
|
15924
16427
|
async newSession(opts) {
|
|
15925
16428
|
const session = new TerminalSession({
|
|
15926
|
-
id:
|
|
16429
|
+
id: randomUUID4(),
|
|
15927
16430
|
command: opts.command,
|
|
15928
16431
|
args: opts.args,
|
|
15929
16432
|
cwd: opts.cwd,
|
|
@@ -16191,7 +16694,7 @@ var getSession = defineCommand({
|
|
|
16191
16694
|
|
|
16192
16695
|
// ../agent-skill-config/src/configs.ts
|
|
16193
16696
|
import os2 from "node:os";
|
|
16194
|
-
import
|
|
16697
|
+
import path15 from "node:path";
|
|
16195
16698
|
|
|
16196
16699
|
// ../agent-defs/src/agents/claude-code.ts
|
|
16197
16700
|
var claudeCodeAgent = {
|
|
@@ -16397,11 +16900,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16397
16900
|
if (!resolvedId) {
|
|
16398
16901
|
return { status: "unknown", input };
|
|
16399
16902
|
}
|
|
16400
|
-
const
|
|
16401
|
-
if (!
|
|
16903
|
+
const config2 = registry[resolvedId];
|
|
16904
|
+
if (!config2) {
|
|
16402
16905
|
return { status: "unsupported", input, id: resolvedId };
|
|
16403
16906
|
}
|
|
16404
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
16907
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16405
16908
|
}
|
|
16406
16909
|
function getAgentConfig(agentId) {
|
|
16407
16910
|
const support = resolveAgentSupport(agentId);
|
|
@@ -16500,7 +17003,7 @@ var templateMutation = {
|
|
|
16500
17003
|
};
|
|
16501
17004
|
|
|
16502
17005
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
16503
|
-
import
|
|
17006
|
+
import path17 from "node:path";
|
|
16504
17007
|
|
|
16505
17008
|
// ../config-mutations/src/formats/json.ts
|
|
16506
17009
|
import * as jsonc from "jsonc-parser";
|
|
@@ -16538,6 +17041,13 @@ function cloneConfigValue(value) {
|
|
|
16538
17041
|
function isConfigObject(value) {
|
|
16539
17042
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16540
17043
|
}
|
|
17044
|
+
function detectIndent(content) {
|
|
17045
|
+
const match = content.match(/^[\t ]+/m);
|
|
17046
|
+
if (match) {
|
|
17047
|
+
return match[0];
|
|
17048
|
+
}
|
|
17049
|
+
return " ";
|
|
17050
|
+
}
|
|
16541
17051
|
function parse3(content) {
|
|
16542
17052
|
if (!content || content.trim() === "") {
|
|
16543
17053
|
return {};
|
|
@@ -16577,6 +17087,9 @@ function merge(base, patch) {
|
|
|
16577
17087
|
}
|
|
16578
17088
|
return result;
|
|
16579
17089
|
}
|
|
17090
|
+
function configValuesEqual(left, right) {
|
|
17091
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
17092
|
+
}
|
|
16580
17093
|
function prune(obj, shape) {
|
|
16581
17094
|
let changed = false;
|
|
16582
17095
|
const result = cloneConfigObject(obj);
|
|
@@ -16613,9 +17126,56 @@ function prune(obj, shape) {
|
|
|
16613
17126
|
}
|
|
16614
17127
|
return { changed, result };
|
|
16615
17128
|
}
|
|
17129
|
+
function modifyAtPath(content, path24, value) {
|
|
17130
|
+
const indent = detectIndent(content);
|
|
17131
|
+
const formattingOptions = {
|
|
17132
|
+
tabSize: indent === " " ? 1 : indent.length,
|
|
17133
|
+
insertSpaces: indent !== " ",
|
|
17134
|
+
eol: "\n"
|
|
17135
|
+
};
|
|
17136
|
+
const edits = jsonc.modify(content, path24, value, { formattingOptions });
|
|
17137
|
+
let result = jsonc.applyEdits(content, edits);
|
|
17138
|
+
if (!result.endsWith("\n")) {
|
|
17139
|
+
result += "\n";
|
|
17140
|
+
}
|
|
17141
|
+
return result;
|
|
17142
|
+
}
|
|
17143
|
+
function removeAtPath(content, path24) {
|
|
17144
|
+
return modifyAtPath(content, path24, void 0);
|
|
17145
|
+
}
|
|
17146
|
+
function serializeUpdate(content, current, next) {
|
|
17147
|
+
let result = content || "{}";
|
|
17148
|
+
result = applyObjectUpdate(result, [], current, next);
|
|
17149
|
+
if (!result.endsWith("\n")) {
|
|
17150
|
+
result += "\n";
|
|
17151
|
+
}
|
|
17152
|
+
return result;
|
|
17153
|
+
}
|
|
17154
|
+
function applyObjectUpdate(content, path24, current, next) {
|
|
17155
|
+
let result = content;
|
|
17156
|
+
for (const key2 of Object.keys(current)) {
|
|
17157
|
+
if (!hasConfigEntry(next, key2)) {
|
|
17158
|
+
result = removeAtPath(result, [...path24, key2]);
|
|
17159
|
+
}
|
|
17160
|
+
}
|
|
17161
|
+
for (const [key2, nextValue] of Object.entries(next)) {
|
|
17162
|
+
const nextPath = [...path24, key2];
|
|
17163
|
+
const hasCurrent = hasConfigEntry(current, key2);
|
|
17164
|
+
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
17165
|
+
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
17166
|
+
result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
|
|
17167
|
+
continue;
|
|
17168
|
+
}
|
|
17169
|
+
if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
|
|
17170
|
+
result = modifyAtPath(result, nextPath, nextValue);
|
|
17171
|
+
}
|
|
17172
|
+
}
|
|
17173
|
+
return result;
|
|
17174
|
+
}
|
|
16616
17175
|
var jsonFormat = {
|
|
16617
17176
|
parse: parse3,
|
|
16618
17177
|
serialize,
|
|
17178
|
+
serializeUpdate,
|
|
16619
17179
|
merge,
|
|
16620
17180
|
prune
|
|
16621
17181
|
};
|
|
@@ -16799,20 +17359,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
16799
17359
|
}
|
|
16800
17360
|
return formatRegistry[formatName];
|
|
16801
17361
|
}
|
|
16802
|
-
function detectFormat(
|
|
16803
|
-
const ext = getExtension(
|
|
17362
|
+
function detectFormat(path24) {
|
|
17363
|
+
const ext = getExtension(path24);
|
|
16804
17364
|
return extensionMap[ext];
|
|
16805
17365
|
}
|
|
16806
|
-
function getExtension(
|
|
16807
|
-
const lastDot =
|
|
17366
|
+
function getExtension(path24) {
|
|
17367
|
+
const lastDot = path24.lastIndexOf(".");
|
|
16808
17368
|
if (lastDot === -1) {
|
|
16809
17369
|
return "";
|
|
16810
17370
|
}
|
|
16811
|
-
return
|
|
17371
|
+
return path24.slice(lastDot).toLowerCase();
|
|
16812
17372
|
}
|
|
16813
17373
|
|
|
16814
17374
|
// ../config-mutations/src/execution/path-utils.ts
|
|
16815
|
-
import
|
|
17375
|
+
import path16 from "node:path";
|
|
16816
17376
|
function expandHome(targetPath, homeDir) {
|
|
16817
17377
|
if (!targetPath?.startsWith("~")) {
|
|
16818
17378
|
return targetPath;
|
|
@@ -16829,7 +17389,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
16829
17389
|
remainder = remainder.slice(1);
|
|
16830
17390
|
}
|
|
16831
17391
|
}
|
|
16832
|
-
return remainder.length === 0 ? homeDir :
|
|
17392
|
+
return remainder.length === 0 ? homeDir : path16.join(homeDir, remainder);
|
|
16833
17393
|
}
|
|
16834
17394
|
function validateHomePath(targetPath) {
|
|
16835
17395
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -16844,21 +17404,21 @@ function validateHomePath(targetPath) {
|
|
|
16844
17404
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
16845
17405
|
validateHomePath(rawPath);
|
|
16846
17406
|
const expanded = expandHome(rawPath, homeDir);
|
|
16847
|
-
const canonicalHome =
|
|
16848
|
-
const canonicalExpanded =
|
|
16849
|
-
const relative =
|
|
16850
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
17407
|
+
const canonicalHome = path16.resolve(homeDir);
|
|
17408
|
+
const canonicalExpanded = path16.resolve(expanded);
|
|
17409
|
+
const relative = path16.relative(canonicalHome, canonicalExpanded);
|
|
17410
|
+
if (relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
|
|
16851
17411
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
16852
17412
|
}
|
|
16853
17413
|
if (!pathMapper) {
|
|
16854
17414
|
return canonicalExpanded;
|
|
16855
17415
|
}
|
|
16856
|
-
const rawDirectory =
|
|
17416
|
+
const rawDirectory = path16.dirname(expanded);
|
|
16857
17417
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
16858
17418
|
targetDirectory: rawDirectory
|
|
16859
17419
|
});
|
|
16860
|
-
const filename =
|
|
16861
|
-
return filename.length === 0 ? mappedDirectory :
|
|
17420
|
+
const filename = path16.basename(expanded);
|
|
17421
|
+
return filename.length === 0 ? mappedDirectory : path16.join(mappedDirectory, filename);
|
|
16862
17422
|
}
|
|
16863
17423
|
|
|
16864
17424
|
// ../config-mutations/src/fs-utils.ts
|
|
@@ -16922,8 +17482,8 @@ function isAlreadyExists(error3) {
|
|
|
16922
17482
|
return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
|
|
16923
17483
|
}
|
|
16924
17484
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
16925
|
-
const boundary =
|
|
16926
|
-
let currentPath =
|
|
17485
|
+
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
17486
|
+
let currentPath = path17.resolve(targetPath);
|
|
16927
17487
|
while (currentPath !== boundary) {
|
|
16928
17488
|
try {
|
|
16929
17489
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -16934,7 +17494,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
16934
17494
|
throw error3;
|
|
16935
17495
|
}
|
|
16936
17496
|
}
|
|
16937
|
-
const parentPath =
|
|
17497
|
+
const parentPath = path17.dirname(currentPath);
|
|
16938
17498
|
if (parentPath === currentPath) {
|
|
16939
17499
|
return;
|
|
16940
17500
|
}
|
|
@@ -16997,7 +17557,7 @@ function pruneKeysByPrefix(table, prefix) {
|
|
|
16997
17557
|
const result = {};
|
|
16998
17558
|
for (const [key2, value] of Object.entries(table)) {
|
|
16999
17559
|
if (!key2.startsWith(prefix)) {
|
|
17000
|
-
result
|
|
17560
|
+
setConfigEntry(result, key2, value);
|
|
17001
17561
|
}
|
|
17002
17562
|
}
|
|
17003
17563
|
return result;
|
|
@@ -17006,28 +17566,43 @@ function isConfigObject4(value) {
|
|
|
17006
17566
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17007
17567
|
}
|
|
17008
17568
|
function mergeWithPruneByPrefix(base, patch, pruneByPrefix) {
|
|
17009
|
-
const result =
|
|
17569
|
+
const result = cloneConfigObject(base);
|
|
17010
17570
|
const prefixMap = pruneByPrefix ?? {};
|
|
17011
17571
|
for (const [key2, value] of Object.entries(patch)) {
|
|
17572
|
+
if (value === void 0) {
|
|
17573
|
+
continue;
|
|
17574
|
+
}
|
|
17012
17575
|
const current = result[key2];
|
|
17013
17576
|
const prefix = prefixMap[key2];
|
|
17014
17577
|
if (isConfigObject4(current) && isConfigObject4(value)) {
|
|
17015
17578
|
if (prefix) {
|
|
17016
17579
|
const pruned = pruneKeysByPrefix(current, prefix);
|
|
17017
|
-
result
|
|
17580
|
+
setConfigEntry(result, key2, mergePrunedConfigObject(pruned, value));
|
|
17018
17581
|
} else {
|
|
17019
|
-
result
|
|
17020
|
-
current,
|
|
17021
|
-
value,
|
|
17022
|
-
prefixMap
|
|
17023
|
-
);
|
|
17582
|
+
setConfigEntry(result, key2, mergeWithPruneByPrefix(current, value, prefixMap));
|
|
17024
17583
|
}
|
|
17025
17584
|
continue;
|
|
17026
17585
|
}
|
|
17027
|
-
result
|
|
17586
|
+
setConfigEntry(result, key2, value);
|
|
17028
17587
|
}
|
|
17029
17588
|
return result;
|
|
17030
17589
|
}
|
|
17590
|
+
function mergePrunedConfigObject(base, patch) {
|
|
17591
|
+
const result = cloneConfigObject(base);
|
|
17592
|
+
for (const [key2, value] of Object.entries(patch)) {
|
|
17593
|
+
if (value === void 0) {
|
|
17594
|
+
continue;
|
|
17595
|
+
}
|
|
17596
|
+
setConfigEntry(result, key2, value);
|
|
17597
|
+
}
|
|
17598
|
+
return result;
|
|
17599
|
+
}
|
|
17600
|
+
function serializeConfigUpdate(format, rawContent, current, next) {
|
|
17601
|
+
if (rawContent !== null && format.serializeUpdate) {
|
|
17602
|
+
return format.serializeUpdate(rawContent, current, next);
|
|
17603
|
+
}
|
|
17604
|
+
return format.serialize(next);
|
|
17605
|
+
}
|
|
17031
17606
|
async function applyMutation(mutation, context, options) {
|
|
17032
17607
|
switch (mutation.kind) {
|
|
17033
17608
|
case "ensureDirectory":
|
|
@@ -17340,6 +17915,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17340
17915
|
}
|
|
17341
17916
|
const format = getConfigFormat(formatName);
|
|
17342
17917
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
17918
|
+
let preserveContent = rawContent;
|
|
17343
17919
|
let current;
|
|
17344
17920
|
try {
|
|
17345
17921
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17348,6 +17924,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17348
17924
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17349
17925
|
}
|
|
17350
17926
|
current = {};
|
|
17927
|
+
preserveContent = null;
|
|
17351
17928
|
}
|
|
17352
17929
|
const value = resolveValue(mutation.value, options);
|
|
17353
17930
|
let merged;
|
|
@@ -17356,7 +17933,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17356
17933
|
} else {
|
|
17357
17934
|
merged = format.merge(current, value);
|
|
17358
17935
|
}
|
|
17359
|
-
const serialized = format
|
|
17936
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, merged);
|
|
17360
17937
|
const changed = serialized !== rawContent;
|
|
17361
17938
|
if (changed && !context.dryRun) {
|
|
17362
17939
|
await writeAtomically2(context, targetPath, serialized);
|
|
@@ -17424,7 +18001,7 @@ async function applyConfigPrune(mutation, context, options) {
|
|
|
17424
18001
|
details
|
|
17425
18002
|
};
|
|
17426
18003
|
}
|
|
17427
|
-
const serialized = format
|
|
18004
|
+
const serialized = serializeConfigUpdate(format, rawContent, current, result);
|
|
17428
18005
|
if (!context.dryRun) {
|
|
17429
18006
|
await writeAtomically2(context, targetPath, serialized);
|
|
17430
18007
|
}
|
|
@@ -17449,6 +18026,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17449
18026
|
}
|
|
17450
18027
|
const format = getConfigFormat(formatName);
|
|
17451
18028
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
18029
|
+
let preserveContent = rawContent;
|
|
17452
18030
|
let current;
|
|
17453
18031
|
try {
|
|
17454
18032
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17457,6 +18035,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17457
18035
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17458
18036
|
}
|
|
17459
18037
|
current = {};
|
|
18038
|
+
preserveContent = null;
|
|
17460
18039
|
}
|
|
17461
18040
|
const { content: transformed, changed } = mutation.transform(current, options);
|
|
17462
18041
|
if (!changed) {
|
|
@@ -17480,7 +18059,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17480
18059
|
details
|
|
17481
18060
|
};
|
|
17482
18061
|
}
|
|
17483
|
-
const serialized = format
|
|
18062
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
17484
18063
|
if (!context.dryRun) {
|
|
17485
18064
|
await writeAtomically2(context, targetPath, serialized);
|
|
17486
18065
|
}
|
|
@@ -17622,7 +18201,7 @@ async function executeMutation(mutation, context, options) {
|
|
|
17622
18201
|
|
|
17623
18202
|
// ../agent-skill-config/src/templates.ts
|
|
17624
18203
|
import { readFile as readFile5, stat } from "node:fs/promises";
|
|
17625
|
-
import
|
|
18204
|
+
import path18 from "node:path";
|
|
17626
18205
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17627
18206
|
|
|
17628
18207
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -17657,14 +18236,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17657
18236
|
throw new UnsupportedAgentError(agentId);
|
|
17658
18237
|
}
|
|
17659
18238
|
const scope = options.scope ?? "local";
|
|
17660
|
-
const
|
|
18239
|
+
const config2 = support.config;
|
|
17661
18240
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17662
18241
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17663
18242
|
}
|
|
17664
|
-
const skillDir = scope === "global" ?
|
|
18243
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17665
18244
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17666
18245
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17667
|
-
const displayPath = `${scope === "global" ?
|
|
18246
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17668
18247
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17669
18248
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17670
18249
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -17699,21 +18278,21 @@ async function installSkill(agentId, skill, options) {
|
|
|
17699
18278
|
|
|
17700
18279
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
17701
18280
|
import { statSync as statSync2 } from "node:fs";
|
|
17702
|
-
import
|
|
18281
|
+
import path19 from "node:path";
|
|
17703
18282
|
|
|
17704
18283
|
// ../agent-skill-config/src/git-exclude.ts
|
|
17705
18284
|
import { execFileSync } from "node:child_process";
|
|
17706
18285
|
import * as fs2 from "node:fs";
|
|
17707
|
-
import
|
|
18286
|
+
import path20 from "node:path";
|
|
17708
18287
|
|
|
17709
18288
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
17710
18289
|
import * as fs3 from "node:fs";
|
|
17711
|
-
import { createHash as createHash4, randomUUID as
|
|
17712
|
-
import
|
|
18290
|
+
import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
|
|
18291
|
+
import path21 from "node:path";
|
|
17713
18292
|
|
|
17714
18293
|
// src/commands/installer.ts
|
|
17715
18294
|
import os3 from "node:os";
|
|
17716
|
-
import
|
|
18295
|
+
import path22 from "node:path";
|
|
17717
18296
|
import * as nodeFs2 from "node:fs/promises";
|
|
17718
18297
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
17719
18298
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
@@ -17780,28 +18359,28 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
17780
18359
|
return homeDir;
|
|
17781
18360
|
}
|
|
17782
18361
|
if (targetPath.startsWith("~/")) {
|
|
17783
|
-
return
|
|
18362
|
+
return path22.join(homeDir, targetPath.slice(2));
|
|
17784
18363
|
}
|
|
17785
18364
|
return targetPath;
|
|
17786
18365
|
}
|
|
17787
18366
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
17788
|
-
const
|
|
17789
|
-
if (!
|
|
18367
|
+
const config2 = getAgentConfig(agent);
|
|
18368
|
+
if (!config2) {
|
|
17790
18369
|
throwUnsupportedAgent(agent);
|
|
17791
18370
|
}
|
|
17792
18371
|
return {
|
|
17793
|
-
displayPath:
|
|
17794
|
-
scope === "global" ?
|
|
18372
|
+
displayPath: path22.join(
|
|
18373
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
17795
18374
|
TERMINAL_PILOT_SKILL_NAME
|
|
17796
18375
|
),
|
|
17797
|
-
fullPath:
|
|
17798
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18376
|
+
fullPath: path22.join(
|
|
18377
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
17799
18378
|
TERMINAL_PILOT_SKILL_NAME
|
|
17800
18379
|
)
|
|
17801
18380
|
};
|
|
17802
18381
|
}
|
|
17803
18382
|
async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
17804
|
-
const rootPath =
|
|
18383
|
+
const rootPath = path22.parse(targetPath).root;
|
|
17805
18384
|
let currentPath = targetPath;
|
|
17806
18385
|
while (currentPath !== rootPath) {
|
|
17807
18386
|
try {
|
|
@@ -17813,7 +18392,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
17813
18392
|
throw error3;
|
|
17814
18393
|
}
|
|
17815
18394
|
}
|
|
17816
|
-
currentPath =
|
|
18395
|
+
currentPath = path22.dirname(currentPath);
|
|
17817
18396
|
}
|
|
17818
18397
|
}
|
|
17819
18398
|
|
|
@@ -17952,7 +18531,7 @@ var resize = defineCommand({
|
|
|
17952
18531
|
});
|
|
17953
18532
|
|
|
17954
18533
|
// ../terminal-png/src/index.ts
|
|
17955
|
-
import { randomUUID as
|
|
18534
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17956
18535
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
17957
18536
|
|
|
17958
18537
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -18892,7 +19471,7 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
18892
19471
|
});
|
|
18893
19472
|
const png = renderPng(svg);
|
|
18894
19473
|
if (options.output) {
|
|
18895
|
-
const temporaryPath = `${options.output}.${
|
|
19474
|
+
const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
|
|
18896
19475
|
try {
|
|
18897
19476
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
18898
19477
|
await rename4(temporaryPath, options.output);
|
|
@@ -18969,7 +19548,7 @@ var type = defineCommand({
|
|
|
18969
19548
|
});
|
|
18970
19549
|
|
|
18971
19550
|
// src/commands/uninstall.ts
|
|
18972
|
-
import { randomUUID as
|
|
19551
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18973
19552
|
var params14 = S.Object({
|
|
18974
19553
|
agent: S.Enum(installableAgents, {
|
|
18975
19554
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19005,7 +19584,7 @@ var uninstall = defineCommand({
|
|
|
19005
19584
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19006
19585
|
continue;
|
|
19007
19586
|
}
|
|
19008
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19587
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
|
|
19009
19588
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19010
19589
|
staged.push({ ...skill, stagingPath });
|
|
19011
19590
|
}
|
|
@@ -19112,6 +19691,7 @@ function createTerminalPilotGroup() {
|
|
|
19112
19691
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19113
19692
|
|
|
19114
19693
|
// src/cli.ts
|
|
19694
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19115
19695
|
function normalizeArgv(argv) {
|
|
19116
19696
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19117
19697
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19135,8 +19715,8 @@ async function isDirectExecution(argv) {
|
|
|
19135
19715
|
try {
|
|
19136
19716
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19137
19717
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19138
|
-
|
|
19139
|
-
|
|
19718
|
+
realpath3(path23.resolve(entryPoint)),
|
|
19719
|
+
realpath3(modulePath)
|
|
19140
19720
|
]);
|
|
19141
19721
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19142
19722
|
} catch {
|