terminal-pilot 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1011 -452
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js +6 -4
- package/dist/commands/close-session.js.map +3 -3
- package/dist/commands/create-session.js +6 -4
- package/dist/commands/create-session.js.map +3 -3
- package/dist/commands/fill.js +6 -4
- package/dist/commands/fill.js.map +3 -3
- package/dist/commands/get-session.js +6 -4
- package/dist/commands/get-session.js.map +3 -3
- package/dist/commands/index.js +299 -159
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +251 -113
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +190 -62
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js +6 -4
- package/dist/commands/list-sessions.js.map +3 -3
- package/dist/commands/press-key.js +6 -4
- package/dist/commands/press-key.js.map +3 -3
- package/dist/commands/read-history.js +6 -4
- package/dist/commands/read-history.js.map +3 -3
- package/dist/commands/read-screen.js +6 -4
- package/dist/commands/read-screen.js.map +3 -3
- package/dist/commands/resize.js +6 -4
- package/dist/commands/resize.js.map +3 -3
- package/dist/commands/runtime.js +6 -4
- package/dist/commands/runtime.js.map +3 -3
- package/dist/commands/screenshot.js +17 -8
- package/dist/commands/screenshot.js.map +3 -3
- package/dist/commands/send-signal.js +6 -4
- package/dist/commands/send-signal.js.map +3 -3
- package/dist/commands/type.js +6 -4
- package/dist/commands/type.js.map +3 -3
- package/dist/commands/uninstall.js +226 -98
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js +6 -4
- package/dist/commands/wait-for-exit.js.map +3 -3
- package/dist/commands/wait-for.js +6 -4
- package/dist/commands/wait-for.js.map +3 -3
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +8 -0
- package/dist/errors.js.map +7 -0
- package/dist/index.js +8 -4
- package/dist/index.js.map +3 -3
- package/dist/terminal-pilot.js +6 -4
- package/dist/terminal-pilot.js.map +3 -3
- package/dist/terminal-session.js +6 -4
- package/dist/terminal-session.js.map +3 -3
- package/dist/testing/cli-repl.js +1011 -452
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +1011 -452
- package/dist/testing/qa-cli.js.map +4 -4
- package/node_modules/@poe-code/agent-skill-config/dist/apply.js +4 -1
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +1 -1
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +17 -9
- package/node_modules/@poe-code/agent-skill-config/dist/templates.js +4 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -6,12 +6,12 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
|
-
import { realpath as
|
|
9
|
+
import { realpath as realpath3 } from "node:fs/promises";
|
|
10
10
|
import path23 from "node:path";
|
|
11
11
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
12
12
|
|
|
13
13
|
// ../toolcraft/src/cli.ts
|
|
14
|
-
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as
|
|
14
|
+
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
15
15
|
import path14 from "node:path";
|
|
16
16
|
import {
|
|
17
17
|
Command as CommanderCommand,
|
|
@@ -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,7 @@ ${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
|
|
1281
1388
|
var MAX_PARTIAL_DEPTH = 100;
|
|
1282
1389
|
var HTML_ESCAPE = {
|
|
1283
1390
|
"&": "&",
|
|
@@ -1689,22 +1796,22 @@ function hasProperty(value, key2) {
|
|
|
1689
1796
|
return Object.prototype.hasOwnProperty.call(value, key2);
|
|
1690
1797
|
}
|
|
1691
1798
|
|
|
1692
|
-
// ../design
|
|
1799
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
1693
1800
|
import { spawn } from "node:child_process";
|
|
1694
1801
|
import process2 from "node:process";
|
|
1695
1802
|
|
|
1696
|
-
// ../design
|
|
1803
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
1697
1804
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1698
1805
|
var storage = new AsyncLocalStorage2();
|
|
1699
1806
|
|
|
1700
|
-
// ../design
|
|
1807
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
1701
1808
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1702
1809
|
|
|
1703
|
-
// ../design
|
|
1810
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
1704
1811
|
import readline from "node:readline";
|
|
1705
1812
|
import { PassThrough } from "node:stream";
|
|
1706
1813
|
|
|
1707
|
-
// ../design
|
|
1814
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
1708
1815
|
var REGION_HEADER = 1 << 0;
|
|
1709
1816
|
var REGION_LIST = 1 << 1;
|
|
1710
1817
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -1713,10 +1820,10 @@ var REGION_MODAL = 1 << 4;
|
|
|
1713
1820
|
var REGION_TOAST = 1 << 5;
|
|
1714
1821
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
1715
1822
|
|
|
1716
|
-
// ../design
|
|
1823
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1717
1824
|
import * as clack from "@clack/prompts";
|
|
1718
1825
|
|
|
1719
|
-
// ../design
|
|
1826
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
1720
1827
|
import { isCancel } from "@clack/prompts";
|
|
1721
1828
|
function cancel(msg = "") {
|
|
1722
1829
|
if (resolveOutputFormat() !== "terminal") {
|
|
@@ -1727,7 +1834,7 @@ function cancel(msg = "") {
|
|
|
1727
1834
|
`);
|
|
1728
1835
|
}
|
|
1729
1836
|
|
|
1730
|
-
// ../design
|
|
1837
|
+
// ../toolcraft-design/src/prompts/primitives/note.ts
|
|
1731
1838
|
function getVisibleWidth(value) {
|
|
1732
1839
|
return stripAnsi(value).length;
|
|
1733
1840
|
}
|
|
@@ -1776,10 +1883,10 @@ function note(message2, title) {
|
|
|
1776
1883
|
`);
|
|
1777
1884
|
}
|
|
1778
1885
|
|
|
1779
|
-
// ../design
|
|
1886
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
1780
1887
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
1781
1888
|
|
|
1782
|
-
// ../design
|
|
1889
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
1783
1890
|
async function select2(opts) {
|
|
1784
1891
|
return clack.select(opts);
|
|
1785
1892
|
}
|
|
@@ -1822,19 +1929,19 @@ var ApprovalDeclinedError = class extends UserError {
|
|
|
1822
1929
|
};
|
|
1823
1930
|
|
|
1824
1931
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
1825
|
-
function validateHumanInLoopOnDefine(
|
|
1826
|
-
const label = Array.isArray(
|
|
1827
|
-
if (
|
|
1828
|
-
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`);
|
|
1829
1936
|
}
|
|
1830
|
-
if (
|
|
1937
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
1831
1938
|
return;
|
|
1832
1939
|
}
|
|
1833
|
-
if (
|
|
1834
|
-
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"`);
|
|
1835
1942
|
}
|
|
1836
|
-
if (typeof
|
|
1837
|
-
throw new Error(`${label} '${
|
|
1943
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
1944
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
1838
1945
|
}
|
|
1839
1946
|
}
|
|
1840
1947
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -1910,12 +2017,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
1910
2017
|
}
|
|
1911
2018
|
}
|
|
1912
2019
|
}
|
|
1913
|
-
function OneOf(
|
|
1914
|
-
assertValidBranches(
|
|
2020
|
+
function OneOf(config2) {
|
|
2021
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
1915
2022
|
return {
|
|
1916
2023
|
kind: "oneOf",
|
|
1917
|
-
discriminator:
|
|
1918
|
-
branches:
|
|
2024
|
+
discriminator: config2.discriminator,
|
|
2025
|
+
branches: config2.branches
|
|
1919
2026
|
};
|
|
1920
2027
|
}
|
|
1921
2028
|
|
|
@@ -2165,22 +2272,22 @@ function cloneStringArray(values) {
|
|
|
2165
2272
|
function cloneStringRecord(values) {
|
|
2166
2273
|
return values === void 0 ? void 0 : { ...values };
|
|
2167
2274
|
}
|
|
2168
|
-
function cloneMcpServerConfig(
|
|
2169
|
-
if (
|
|
2275
|
+
function cloneMcpServerConfig(config2) {
|
|
2276
|
+
if (config2 === void 0) {
|
|
2170
2277
|
return void 0;
|
|
2171
2278
|
}
|
|
2172
|
-
if (
|
|
2279
|
+
if (config2.transport === "stdio") {
|
|
2173
2280
|
return {
|
|
2174
2281
|
transport: "stdio",
|
|
2175
|
-
command:
|
|
2176
|
-
args: cloneStringArray(
|
|
2177
|
-
env: cloneStringRecord(
|
|
2282
|
+
command: config2.command,
|
|
2283
|
+
args: cloneStringArray(config2.args),
|
|
2284
|
+
env: cloneStringRecord(config2.env)
|
|
2178
2285
|
};
|
|
2179
2286
|
}
|
|
2180
2287
|
return {
|
|
2181
2288
|
transport: "http",
|
|
2182
|
-
url:
|
|
2183
|
-
headers: cloneStringRecord(
|
|
2289
|
+
url: config2.url,
|
|
2290
|
+
headers: cloneStringRecord(config2.headers)
|
|
2184
2291
|
};
|
|
2185
2292
|
}
|
|
2186
2293
|
function cloneRenameMap(rename5) {
|
|
@@ -2421,57 +2528,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
2421
2528
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
2422
2529
|
return cloneScope(ownScope ?? inheritedScope);
|
|
2423
2530
|
}
|
|
2424
|
-
function createBaseCommand(
|
|
2531
|
+
function createBaseCommand(config2) {
|
|
2425
2532
|
const command = {
|
|
2426
2533
|
kind: "command",
|
|
2427
|
-
name:
|
|
2428
|
-
description:
|
|
2429
|
-
aliases: [...
|
|
2430
|
-
positional: [...
|
|
2431
|
-
params:
|
|
2432
|
-
secrets: cloneSecrets(
|
|
2433
|
-
scope: resolveCommandScope(
|
|
2434
|
-
confirm:
|
|
2435
|
-
humanInLoop:
|
|
2436
|
-
requires: cloneRequires(
|
|
2437
|
-
handler:
|
|
2438
|
-
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
|
|
2439
2546
|
};
|
|
2440
2547
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
2441
2548
|
value: {
|
|
2442
|
-
scope: cloneScope(
|
|
2443
|
-
humanInLoop:
|
|
2444
|
-
secrets: cloneSecrets(
|
|
2445
|
-
requires: cloneRequires(
|
|
2549
|
+
scope: cloneScope(config2.scope),
|
|
2550
|
+
humanInLoop: config2.humanInLoop,
|
|
2551
|
+
secrets: cloneSecrets(config2.secrets),
|
|
2552
|
+
requires: cloneRequires(config2.requires),
|
|
2446
2553
|
sourcePath: inferCommandSourcePath()
|
|
2447
2554
|
}
|
|
2448
2555
|
});
|
|
2449
2556
|
return command;
|
|
2450
2557
|
}
|
|
2451
|
-
function createBaseGroup(
|
|
2558
|
+
function createBaseGroup(config2) {
|
|
2452
2559
|
const group = {
|
|
2453
2560
|
kind: "group",
|
|
2454
|
-
name:
|
|
2455
|
-
description:
|
|
2456
|
-
aliases: [...
|
|
2457
|
-
scope: resolveGroupScope(
|
|
2458
|
-
humanInLoop:
|
|
2459
|
-
secrets: cloneSecrets(
|
|
2460
|
-
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),
|
|
2461
2568
|
children: [],
|
|
2462
2569
|
default: void 0
|
|
2463
2570
|
};
|
|
2464
2571
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
2465
2572
|
value: {
|
|
2466
|
-
mcp: cloneMcpServerConfig(
|
|
2467
|
-
scope: cloneScope(
|
|
2468
|
-
humanInLoop:
|
|
2469
|
-
secrets: cloneSecrets(
|
|
2470
|
-
tools: cloneStringArray(
|
|
2471
|
-
rename: cloneRenameMap(
|
|
2472
|
-
requires: cloneRequires(
|
|
2473
|
-
children: [...
|
|
2474
|
-
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
|
|
2475
2582
|
}
|
|
2476
2583
|
});
|
|
2477
2584
|
return group;
|
|
@@ -2574,10 +2681,10 @@ function materializeNode(node, inherited) {
|
|
|
2574
2681
|
}
|
|
2575
2682
|
return materializeGroup(node, inherited);
|
|
2576
2683
|
}
|
|
2577
|
-
function defineCommand(
|
|
2578
|
-
validateHumanInLoopOnDefine(
|
|
2684
|
+
function defineCommand(config2) {
|
|
2685
|
+
validateHumanInLoopOnDefine(config2);
|
|
2579
2686
|
return materializeCommand(
|
|
2580
|
-
createBaseCommand(
|
|
2687
|
+
createBaseCommand(config2),
|
|
2581
2688
|
{
|
|
2582
2689
|
scope: void 0,
|
|
2583
2690
|
humanInLoop: void 0,
|
|
@@ -2586,10 +2693,10 @@ function defineCommand(config) {
|
|
|
2586
2693
|
}
|
|
2587
2694
|
);
|
|
2588
2695
|
}
|
|
2589
|
-
function defineGroup(
|
|
2590
|
-
validateRenameMap(
|
|
2591
|
-
validateHumanInLoopOnDefine(
|
|
2592
|
-
return materializeGroup(createBaseGroup(
|
|
2696
|
+
function defineGroup(config2) {
|
|
2697
|
+
validateRenameMap(config2.rename);
|
|
2698
|
+
validateHumanInLoopOnDefine(config2);
|
|
2699
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
2593
2700
|
scope: void 0,
|
|
2594
2701
|
humanInLoop: void 0,
|
|
2595
2702
|
secrets: {},
|
|
@@ -2620,27 +2727,27 @@ function validateMachine(machine) {
|
|
|
2620
2727
|
if (!isRecord(machine)) {
|
|
2621
2728
|
throw new TypeError("State machine must be an object.");
|
|
2622
2729
|
}
|
|
2623
|
-
if (!isStateList(machine.states)) {
|
|
2730
|
+
if (!hasOwnRecordField(machine, "states") || !isStateList(machine.states)) {
|
|
2624
2731
|
throw new TypeError("State machine states must be a string array.");
|
|
2625
2732
|
}
|
|
2626
2733
|
const states = new Set(machine.states);
|
|
2627
|
-
if (typeof machine.initial !== "string") {
|
|
2734
|
+
if (!hasOwnRecordField(machine, "initial") || typeof machine.initial !== "string") {
|
|
2628
2735
|
throw new TypeError("State machine initial must be a string.");
|
|
2629
2736
|
}
|
|
2630
2737
|
if (!states.has(machine.initial)) {
|
|
2631
2738
|
throw new Error(`Initial state "${machine.initial}" is not declared.`);
|
|
2632
2739
|
}
|
|
2633
|
-
if (!isRecord(machine.events)) {
|
|
2740
|
+
if (!hasOwnRecordField(machine, "events") || !isRecord(machine.events)) {
|
|
2634
2741
|
throw new TypeError("State machine events must be an object.");
|
|
2635
2742
|
}
|
|
2636
2743
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
2637
2744
|
if (!isRecord(event)) {
|
|
2638
2745
|
throw new TypeError(`Event "${eventName}" must be an object.`);
|
|
2639
2746
|
}
|
|
2640
|
-
if (event.from !== "*" && !isStateList(event.from)) {
|
|
2747
|
+
if (!hasOwnRecordField(event, "from") || event.from !== "*" && !isStateList(event.from)) {
|
|
2641
2748
|
throw new TypeError(`Event "${eventName}" has an invalid "from" definition.`);
|
|
2642
2749
|
}
|
|
2643
|
-
if (typeof event.to !== "string") {
|
|
2750
|
+
if (!hasOwnRecordField(event, "to") || typeof event.to !== "string") {
|
|
2644
2751
|
throw new TypeError(`Event "${eventName}" target state must be a string.`);
|
|
2645
2752
|
}
|
|
2646
2753
|
if (!states.has(event.to)) {
|
|
@@ -2655,6 +2762,9 @@ function validateMachine(machine) {
|
|
|
2655
2762
|
}
|
|
2656
2763
|
}
|
|
2657
2764
|
}
|
|
2765
|
+
function hasOwnRecordField(record, key2) {
|
|
2766
|
+
return Object.prototype.hasOwnProperty.call(record, key2);
|
|
2767
|
+
}
|
|
2658
2768
|
function eventsFromState(machine, fromState) {
|
|
2659
2769
|
const events = [];
|
|
2660
2770
|
for (const [eventName, event] of Object.entries(machine.events)) {
|
|
@@ -2758,7 +2868,7 @@ import path3 from "node:path";
|
|
|
2758
2868
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2759
2869
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2760
2870
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2761
|
-
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2871
|
+
import { readdir, readFile, realpath, writeFile } from "node:fs/promises";
|
|
2762
2872
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
2763
2873
|
import path5 from "node:path";
|
|
2764
2874
|
|
|
@@ -2926,6 +3036,7 @@ function resolveEndpoint(options = {}) {
|
|
|
2926
3036
|
}
|
|
2927
3037
|
|
|
2928
3038
|
// ../task-list/src/backends/utils.ts
|
|
3039
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
2929
3040
|
import path6 from "node:path";
|
|
2930
3041
|
function compareCreated(left, right) {
|
|
2931
3042
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
@@ -2946,9 +3057,8 @@ function applyOrder(entries, order) {
|
|
|
2946
3057
|
}
|
|
2947
3058
|
return entries.map((entry) => entry.task);
|
|
2948
3059
|
}
|
|
2949
|
-
var tmpFileCounter = 0;
|
|
2950
3060
|
function hasErrorCode(error3, code) {
|
|
2951
|
-
return !!error3 && typeof error3 === "object" && "code"
|
|
3061
|
+
return !!error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
|
|
2952
3062
|
}
|
|
2953
3063
|
function isRecord2(value) {
|
|
2954
3064
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -2995,18 +3105,22 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
2995
3105
|
}
|
|
2996
3106
|
}
|
|
2997
3107
|
async function writeAtomically(fs4, filePath, content) {
|
|
2998
|
-
const tempPath = `${filePath}
|
|
2999
|
-
|
|
3108
|
+
const tempPath = `${filePath}.${process.pid}.${randomUUID2()}.tmp`;
|
|
3109
|
+
let tempCreated = false;
|
|
3000
3110
|
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
3001
3111
|
try {
|
|
3002
3112
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
3113
|
+
tempCreated = true;
|
|
3003
3114
|
await fs4.rename(tempPath, filePath);
|
|
3115
|
+
tempCreated = false;
|
|
3004
3116
|
} catch (error3) {
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3117
|
+
if (tempCreated || !hasErrorCode(error3, "EEXIST")) {
|
|
3118
|
+
try {
|
|
3119
|
+
await fs4.unlink(tempPath);
|
|
3120
|
+
} catch (unlinkError) {
|
|
3121
|
+
if (!hasErrorCode(unlinkError, "ENOENT")) {
|
|
3122
|
+
throw unlinkError;
|
|
3123
|
+
}
|
|
3010
3124
|
}
|
|
3011
3125
|
}
|
|
3012
3126
|
throw error3;
|
|
@@ -3020,6 +3134,7 @@ async function withFileLock(fs4, lockPath, operation) {
|
|
|
3020
3134
|
break;
|
|
3021
3135
|
} catch (error3) {
|
|
3022
3136
|
if (!hasErrorCode(error3, "EEXIST")) {
|
|
3137
|
+
await fs4.unlink(lockPath).catch(() => void 0);
|
|
3023
3138
|
throw error3;
|
|
3024
3139
|
}
|
|
3025
3140
|
if (await removeAbandonedLock(fs4, lockPath)) {
|
|
@@ -4303,27 +4418,30 @@ function readFrontmatter(frontmatterContent, filePath) {
|
|
|
4303
4418
|
return parsed;
|
|
4304
4419
|
}
|
|
4305
4420
|
function assertValidTaskRecord(frontmatter, filePath, validStates) {
|
|
4306
|
-
if ("$schema"
|
|
4421
|
+
if (hasOwnTaskField(frontmatter, "$schema") && frontmatter.$schema !== TASK_SCHEMA_ID) {
|
|
4307
4422
|
throw malformedTask(filePath, "$schema");
|
|
4308
4423
|
}
|
|
4309
|
-
if ("kind"
|
|
4424
|
+
if (hasOwnTaskField(frontmatter, "kind") && frontmatter.kind !== TASK_KIND) {
|
|
4310
4425
|
throw malformedTask(filePath, "kind");
|
|
4311
4426
|
}
|
|
4312
|
-
if ("version"
|
|
4427
|
+
if (hasOwnTaskField(frontmatter, "version")) {
|
|
4313
4428
|
if (typeof frontmatter.version !== "number" || !Number.isInteger(frontmatter.version) || frontmatter.version !== TASK_VERSION) {
|
|
4314
4429
|
throw malformedTask(filePath, "version");
|
|
4315
4430
|
}
|
|
4316
4431
|
}
|
|
4317
|
-
if (typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
4432
|
+
if (!hasOwnTaskField(frontmatter, "name") || typeof frontmatter.name !== "string" || frontmatter.name.length === 0) {
|
|
4318
4433
|
throw malformedTask(filePath, "name");
|
|
4319
4434
|
}
|
|
4320
|
-
if (typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
|
|
4435
|
+
if (!hasOwnTaskField(frontmatter, "state") || typeof frontmatter.state !== "string" || !validStates.has(frontmatter.state)) {
|
|
4321
4436
|
throw malformedTask(filePath, "state");
|
|
4322
4437
|
}
|
|
4323
|
-
if ("description"
|
|
4438
|
+
if (hasOwnTaskField(frontmatter, "description") && typeof frontmatter.description !== "string") {
|
|
4324
4439
|
throw malformedTask(filePath, "description");
|
|
4325
4440
|
}
|
|
4326
4441
|
}
|
|
4442
|
+
function hasOwnTaskField(frontmatter, key2) {
|
|
4443
|
+
return Object.prototype.hasOwnProperty.call(frontmatter, key2);
|
|
4444
|
+
}
|
|
4327
4445
|
function reservedFrontmatterKeys(mode) {
|
|
4328
4446
|
return mode === "passthrough" ? PASSTHROUGH_RESERVED_FRONTMATTER_KEYS : RESERVED_FRONTMATTER_KEYS;
|
|
4329
4447
|
}
|
|
@@ -4446,7 +4564,7 @@ async function readTaskAtLocation(fs4, rootPath, layout, list, id, validStates,
|
|
|
4446
4564
|
}
|
|
4447
4565
|
return readTaskFile(fs4, list, id, location.path, validStates, initialState, mode);
|
|
4448
4566
|
}
|
|
4449
|
-
function createdFrontmatter(
|
|
4567
|
+
function createdFrontmatter(defaults2, input, initialState, mode) {
|
|
4450
4568
|
const frontmatter = mode !== "passthrough" ? {
|
|
4451
4569
|
$schema: TASK_SCHEMA_ID,
|
|
4452
4570
|
kind: TASK_KIND,
|
|
@@ -4458,7 +4576,7 @@ function createdFrontmatter(defaults, input, initialState, mode) {
|
|
|
4458
4576
|
state: initialState
|
|
4459
4577
|
};
|
|
4460
4578
|
const reservedKeys = reservedFrontmatterKeys(mode);
|
|
4461
|
-
for (const [key2, value] of Object.entries(
|
|
4579
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
4462
4580
|
if (!reservedKeys.has(key2)) {
|
|
4463
4581
|
setOwnValue(frontmatter, key2, value);
|
|
4464
4582
|
}
|
|
@@ -5172,7 +5290,8 @@ function parseQualifiedId3(qualifiedId) {
|
|
|
5172
5290
|
};
|
|
5173
5291
|
}
|
|
5174
5292
|
function descriptionFromTaskRecord(taskRecord) {
|
|
5175
|
-
|
|
5293
|
+
const description = getOwnEntry(taskRecord, "description");
|
|
5294
|
+
return typeof description === "string" ? description : "";
|
|
5176
5295
|
}
|
|
5177
5296
|
function metadataFromTaskRecord(taskRecord) {
|
|
5178
5297
|
const metadata = /* @__PURE__ */ Object.create(null);
|
|
@@ -5188,8 +5307,8 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5188
5307
|
list,
|
|
5189
5308
|
id,
|
|
5190
5309
|
qualifiedId: `${list}/${id}`,
|
|
5191
|
-
name: taskRecord
|
|
5192
|
-
state: taskRecord
|
|
5310
|
+
name: getOwnEntry(taskRecord, "name"),
|
|
5311
|
+
state: getOwnEntry(taskRecord, "state"),
|
|
5193
5312
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5194
5313
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5195
5314
|
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
@@ -5204,13 +5323,13 @@ function matchesFilter(task, filter) {
|
|
|
5204
5323
|
}
|
|
5205
5324
|
return true;
|
|
5206
5325
|
}
|
|
5207
|
-
function createTaskRecord(
|
|
5326
|
+
function createTaskRecord(defaults2, input, initialState) {
|
|
5208
5327
|
const taskRecord = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
5209
5328
|
name: input.name,
|
|
5210
5329
|
state: initialState,
|
|
5211
5330
|
description: input.description ?? ""
|
|
5212
5331
|
});
|
|
5213
|
-
for (const [key2, value] of Object.entries(
|
|
5332
|
+
for (const [key2, value] of Object.entries(defaults2.metadata)) {
|
|
5214
5333
|
if (!RESERVED_TASK_KEYS.has(key2)) {
|
|
5215
5334
|
taskRecord[key2] = value;
|
|
5216
5335
|
}
|
|
@@ -5286,16 +5405,17 @@ function assertValidStoreRecord(store, filePath) {
|
|
|
5286
5405
|
if (!isRecord2(store)) {
|
|
5287
5406
|
throw malformedStore(filePath, "store");
|
|
5288
5407
|
}
|
|
5289
|
-
if (store
|
|
5408
|
+
if (getOwnEntry(store, "$schema") !== STORE_SCHEMA_ID) {
|
|
5290
5409
|
throw malformedStore(filePath, "$schema");
|
|
5291
5410
|
}
|
|
5292
|
-
if (store
|
|
5411
|
+
if (getOwnEntry(store, "kind") !== STORE_KIND) {
|
|
5293
5412
|
throw malformedStore(filePath, "kind");
|
|
5294
5413
|
}
|
|
5295
|
-
|
|
5414
|
+
const version = getOwnEntry(store, "version");
|
|
5415
|
+
if (typeof version !== "number" || !Number.isInteger(version) || version !== STORE_VERSION) {
|
|
5296
5416
|
throw malformedStore(filePath, "version");
|
|
5297
5417
|
}
|
|
5298
|
-
if (!isRecord2(store
|
|
5418
|
+
if (!isRecord2(getOwnEntry(store, "lists"))) {
|
|
5299
5419
|
throw malformedStore(filePath, "lists");
|
|
5300
5420
|
}
|
|
5301
5421
|
}
|
|
@@ -5303,29 +5423,38 @@ function assertValidTaskRecord2(taskRecord, list, id, validStates) {
|
|
|
5303
5423
|
if (!isRecord2(taskRecord)) {
|
|
5304
5424
|
throw malformedTask2(list, id, "task");
|
|
5305
5425
|
}
|
|
5306
|
-
if ("$schema"
|
|
5426
|
+
if (hasOwnTaskField2(taskRecord, "$schema") && getOwnEntry(taskRecord, "$schema") !== TASK_SCHEMA_ID2) {
|
|
5307
5427
|
throw malformedTask2(list, id, "$schema");
|
|
5308
5428
|
}
|
|
5309
|
-
if ("kind"
|
|
5429
|
+
if (hasOwnTaskField2(taskRecord, "kind") && getOwnEntry(taskRecord, "kind") !== TASK_KIND2) {
|
|
5310
5430
|
throw malformedTask2(list, id, "kind");
|
|
5311
5431
|
}
|
|
5312
|
-
if ("version"
|
|
5313
|
-
|
|
5432
|
+
if (hasOwnTaskField2(taskRecord, "version")) {
|
|
5433
|
+
const version = getOwnEntry(taskRecord, "version");
|
|
5434
|
+
if (typeof version !== "number" || !Number.isInteger(version) || version !== TASK_VERSION2) {
|
|
5314
5435
|
throw malformedTask2(list, id, "version");
|
|
5315
5436
|
}
|
|
5316
5437
|
}
|
|
5317
|
-
|
|
5438
|
+
const name = getOwnEntry(taskRecord, "name");
|
|
5439
|
+
if (!hasOwnTaskField2(taskRecord, "name") || typeof name !== "string" || name.length === 0) {
|
|
5318
5440
|
throw malformedTask2(list, id, "name");
|
|
5319
5441
|
}
|
|
5320
|
-
|
|
5442
|
+
const state = getOwnEntry(taskRecord, "state");
|
|
5443
|
+
if (!hasOwnTaskField2(taskRecord, "state") || typeof state !== "string" || !validStates.has(state)) {
|
|
5321
5444
|
throw malformedTask2(list, id, "state");
|
|
5322
5445
|
}
|
|
5323
|
-
if ("description"
|
|
5446
|
+
if (hasOwnTaskField2(taskRecord, "description") && typeof getOwnEntry(taskRecord, "description") !== "string") {
|
|
5324
5447
|
throw malformedTask2(list, id, "description");
|
|
5325
5448
|
}
|
|
5326
5449
|
}
|
|
5450
|
+
function hasOwnTaskField2(taskRecord, key2) {
|
|
5451
|
+
return Object.prototype.hasOwnProperty.call(taskRecord, key2);
|
|
5452
|
+
}
|
|
5453
|
+
function getOwnEntry(record, key2) {
|
|
5454
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
5455
|
+
}
|
|
5327
5456
|
function validateStoreEntries(store, filePath, validStates) {
|
|
5328
|
-
const lists = store
|
|
5457
|
+
const lists = getOwnEntry(store, "lists");
|
|
5329
5458
|
if (!isRecord2(lists)) {
|
|
5330
5459
|
throw malformedStore(filePath, "lists");
|
|
5331
5460
|
}
|
|
@@ -5365,10 +5494,11 @@ async function readStore(fs4, filePath, validStates) {
|
|
|
5365
5494
|
};
|
|
5366
5495
|
}
|
|
5367
5496
|
function getListsRecord(store) {
|
|
5368
|
-
|
|
5497
|
+
const lists = getOwnEntry(store, "lists");
|
|
5498
|
+
return isRecord2(lists) ? lists : {};
|
|
5369
5499
|
}
|
|
5370
5500
|
function getListRecord(store, list) {
|
|
5371
|
-
const listRecord = getListsRecord(store)
|
|
5501
|
+
const listRecord = getOwnEntry(getListsRecord(store), list);
|
|
5372
5502
|
return isRecord2(listRecord) ? listRecord : void 0;
|
|
5373
5503
|
}
|
|
5374
5504
|
function getTaskRecord(store, list, id) {
|
|
@@ -5661,7 +5791,7 @@ async function yamlFileBackend(deps) {
|
|
|
5661
5791
|
const result = [];
|
|
5662
5792
|
const listNames = sortStrings(Object.keys(getListsRecord(store)));
|
|
5663
5793
|
for (const listName of listNames) {
|
|
5664
|
-
const listRecord = getListsRecord(store)
|
|
5794
|
+
const listRecord = getOwnEntry(getListsRecord(store), listName);
|
|
5665
5795
|
if (!isRecord2(listRecord)) continue;
|
|
5666
5796
|
const entries = Object.entries(listRecord).map(([id, taskRecord]) => ({
|
|
5667
5797
|
task: createTask2(listName, id, taskRecord, deps.path),
|
|
@@ -6295,8 +6425,8 @@ function createHandlerContext(command, params17) {
|
|
|
6295
6425
|
function createFs() {
|
|
6296
6426
|
return {
|
|
6297
6427
|
readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
|
|
6298
|
-
writeFile: async (path24, contents) => {
|
|
6299
|
-
await writeFile2(path24, contents);
|
|
6428
|
+
writeFile: async (path24, contents, options) => {
|
|
6429
|
+
await writeFile2(path24, contents, options);
|
|
6300
6430
|
},
|
|
6301
6431
|
exists: async (path24) => {
|
|
6302
6432
|
try {
|
|
@@ -6584,17 +6714,17 @@ function isMissingStateError(error3) {
|
|
|
6584
6714
|
}
|
|
6585
6715
|
|
|
6586
6716
|
// ../toolcraft/src/error-report.ts
|
|
6587
|
-
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6588
|
-
import { randomUUID as
|
|
6717
|
+
import { mkdir as mkdir2, realpath as realpath2, writeFile as writeFile4 } from "node:fs/promises";
|
|
6718
|
+
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
6589
6719
|
import os from "node:os";
|
|
6590
6720
|
import path13 from "node:path";
|
|
6591
6721
|
import { CommanderError } from "commander";
|
|
6592
6722
|
|
|
6593
6723
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6594
6724
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6595
|
-
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6725
|
+
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6596
6726
|
import path12 from "node:path";
|
|
6597
|
-
import { createHash as createHash3, randomUUID as
|
|
6727
|
+
import { createHash as createHash3, randomUUID as randomUUID4 } from "node:crypto";
|
|
6598
6728
|
|
|
6599
6729
|
// ../tiny-mcp-client/src/internal.ts
|
|
6600
6730
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6605,7 +6735,7 @@ import crypto from "node:crypto";
|
|
|
6605
6735
|
import path11 from "node:path";
|
|
6606
6736
|
|
|
6607
6737
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6608
|
-
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6738
|
+
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, randomUUID as randomUUID3, scrypt } from "node:crypto";
|
|
6609
6739
|
import { promises as fs } from "node:fs";
|
|
6610
6740
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6611
6741
|
import path10 from "node:path";
|
|
@@ -6616,7 +6746,6 @@ var ENCRYPTION_KEY_BYTES = 32;
|
|
|
6616
6746
|
var ENCRYPTION_IV_BYTES = 12;
|
|
6617
6747
|
var ENCRYPTION_AUTH_TAG_BYTES = 16;
|
|
6618
6748
|
var ENCRYPTION_FILE_MODE = 384;
|
|
6619
|
-
var temporaryFileSequence = 0;
|
|
6620
6749
|
var EncryptedFileStore = class {
|
|
6621
6750
|
fs;
|
|
6622
6751
|
filePath;
|
|
@@ -6648,7 +6777,7 @@ var EncryptedFileStore = class {
|
|
|
6648
6777
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6649
6778
|
}
|
|
6650
6779
|
async get() {
|
|
6651
|
-
await this.
|
|
6780
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6652
6781
|
let rawDocument;
|
|
6653
6782
|
try {
|
|
6654
6783
|
rawDocument = await this.fs.readFile(this.filePath, "utf8");
|
|
@@ -6679,7 +6808,7 @@ var EncryptedFileStore = class {
|
|
|
6679
6808
|
}
|
|
6680
6809
|
}
|
|
6681
6810
|
async set(value) {
|
|
6682
|
-
await this.
|
|
6811
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6683
6812
|
const key2 = await this.getEncryptionKey();
|
|
6684
6813
|
const iv = this.getRandomBytes(ENCRYPTION_IV_BYTES);
|
|
6685
6814
|
const cipher = createCipheriv(ENCRYPTION_ALGORITHM, key2, iv);
|
|
@@ -6695,25 +6824,28 @@ var EncryptedFileStore = class {
|
|
|
6695
6824
|
ciphertext: ciphertext.toString("base64")
|
|
6696
6825
|
};
|
|
6697
6826
|
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6698
|
-
await this.
|
|
6699
|
-
const temporaryPath = `${this.filePath}.${process.pid}.${
|
|
6827
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6828
|
+
const temporaryPath = `${this.filePath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
6829
|
+
let temporaryCreated = false;
|
|
6700
6830
|
try {
|
|
6831
|
+
await this.assertCredentialPathHasNoSymbolicLinks(temporaryPath);
|
|
6701
6832
|
await this.fs.writeFile(temporaryPath, JSON.stringify(document), {
|
|
6702
6833
|
encoding: "utf8",
|
|
6703
6834
|
flag: "wx",
|
|
6704
6835
|
mode: ENCRYPTION_FILE_MODE
|
|
6705
6836
|
});
|
|
6837
|
+
temporaryCreated = true;
|
|
6706
6838
|
await this.fs.chmod(temporaryPath, ENCRYPTION_FILE_MODE);
|
|
6707
6839
|
await this.fs.rename(temporaryPath, this.filePath);
|
|
6708
6840
|
} catch (error3) {
|
|
6709
|
-
if (!isAlreadyExistsError(error3)) {
|
|
6841
|
+
if (temporaryCreated || !isAlreadyExistsError(error3)) {
|
|
6710
6842
|
await removeIfPresent(this.fs, temporaryPath).catch(() => void 0);
|
|
6711
6843
|
}
|
|
6712
6844
|
throw error3;
|
|
6713
6845
|
}
|
|
6714
6846
|
}
|
|
6715
6847
|
async delete() {
|
|
6716
|
-
await this.
|
|
6848
|
+
await this.assertCredentialPathHasNoSymbolicLinks(this.filePath);
|
|
6717
6849
|
try {
|
|
6718
6850
|
await this.fs.unlink(this.filePath);
|
|
6719
6851
|
} catch (error3) {
|
|
@@ -6722,8 +6854,8 @@ var EncryptedFileStore = class {
|
|
|
6722
6854
|
}
|
|
6723
6855
|
}
|
|
6724
6856
|
}
|
|
6725
|
-
async
|
|
6726
|
-
const resolvedPath = path10.resolve(
|
|
6857
|
+
async assertCredentialPathHasNoSymbolicLinks(targetPath) {
|
|
6858
|
+
const resolvedPath = path10.resolve(targetPath);
|
|
6727
6859
|
const protectedPaths = getProtectedCredentialPaths(
|
|
6728
6860
|
resolvedPath,
|
|
6729
6861
|
this.symbolicLinkCheckStartPath
|
|
@@ -6788,9 +6920,6 @@ async function removeIfPresent(fileSystem, filePath) {
|
|
|
6788
6920
|
}
|
|
6789
6921
|
}
|
|
6790
6922
|
}
|
|
6791
|
-
function isAlreadyExistsError(error3) {
|
|
6792
|
-
return typeof error3 === "object" && error3 !== null && "code" in error3 && error3.code === "EEXIST";
|
|
6793
|
-
}
|
|
6794
6923
|
function defaultMachineIdentity() {
|
|
6795
6924
|
return {
|
|
6796
6925
|
hostname: hostname(),
|
|
@@ -6828,17 +6957,21 @@ function parseEncryptedDocument(raw) {
|
|
|
6828
6957
|
if (!isRecord4(parsed)) {
|
|
6829
6958
|
return null;
|
|
6830
6959
|
}
|
|
6831
|
-
|
|
6960
|
+
const version = getOwnEntry2(parsed, "version");
|
|
6961
|
+
const iv = getOwnEntry2(parsed, "iv");
|
|
6962
|
+
const authTag = getOwnEntry2(parsed, "authTag");
|
|
6963
|
+
const ciphertext = getOwnEntry2(parsed, "ciphertext");
|
|
6964
|
+
if (version !== ENCRYPTION_VERSION) {
|
|
6832
6965
|
return null;
|
|
6833
6966
|
}
|
|
6834
|
-
if (typeof
|
|
6967
|
+
if (typeof iv !== "string" || typeof authTag !== "string" || typeof ciphertext !== "string") {
|
|
6835
6968
|
return null;
|
|
6836
6969
|
}
|
|
6837
6970
|
return {
|
|
6838
|
-
version
|
|
6839
|
-
iv
|
|
6840
|
-
authTag
|
|
6841
|
-
ciphertext
|
|
6971
|
+
version,
|
|
6972
|
+
iv,
|
|
6973
|
+
authTag,
|
|
6974
|
+
ciphertext
|
|
6842
6975
|
};
|
|
6843
6976
|
} catch {
|
|
6844
6977
|
return null;
|
|
@@ -6847,9 +6980,17 @@ function parseEncryptedDocument(raw) {
|
|
|
6847
6980
|
function isRecord4(value) {
|
|
6848
6981
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
6849
6982
|
}
|
|
6983
|
+
function getOwnEntry2(record, key2) {
|
|
6984
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
6985
|
+
}
|
|
6850
6986
|
function isNotFoundError(error3) {
|
|
6851
6987
|
return Boolean(
|
|
6852
|
-
error3 && typeof error3 === "object" && "code"
|
|
6988
|
+
error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT"
|
|
6989
|
+
);
|
|
6990
|
+
}
|
|
6991
|
+
function isAlreadyExistsError(error3) {
|
|
6992
|
+
return Boolean(
|
|
6993
|
+
error3 && typeof error3 === "object" && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST"
|
|
6853
6994
|
);
|
|
6854
6995
|
}
|
|
6855
6996
|
|
|
@@ -6871,8 +7012,8 @@ var KeychainStore = class {
|
|
|
6871
7012
|
["find-generic-password", "-s", this.service, "-a", this.account, "-w"],
|
|
6872
7013
|
"read secret from macOS Keychain"
|
|
6873
7014
|
);
|
|
6874
|
-
if (result
|
|
6875
|
-
return stripTrailingLineBreak(result
|
|
7015
|
+
if (getCommandExitCode(result) === 0) {
|
|
7016
|
+
return stripTrailingLineBreak(getCommandOutput(result, "stdout"));
|
|
6876
7017
|
}
|
|
6877
7018
|
if (isKeychainEntryNotFound(result)) {
|
|
6878
7019
|
return null;
|
|
@@ -6896,7 +7037,7 @@ var KeychainStore = class {
|
|
|
6896
7037
|
"store secret in macOS Keychain",
|
|
6897
7038
|
{ stdin: value }
|
|
6898
7039
|
);
|
|
6899
|
-
if (result
|
|
7040
|
+
if (getCommandExitCode(result) !== 0) {
|
|
6900
7041
|
throw createSecurityCliFailure("store secret in macOS Keychain", result);
|
|
6901
7042
|
}
|
|
6902
7043
|
}
|
|
@@ -6905,7 +7046,7 @@ var KeychainStore = class {
|
|
|
6905
7046
|
["delete-generic-password", "-s", this.service, "-a", this.account],
|
|
6906
7047
|
"delete secret from macOS Keychain"
|
|
6907
7048
|
);
|
|
6908
|
-
if (result
|
|
7049
|
+
if (getCommandExitCode(result) === 0 || isKeychainEntryNotFound(result)) {
|
|
6909
7050
|
return;
|
|
6910
7051
|
}
|
|
6911
7052
|
throw createSecurityCliFailure("delete secret from macOS Keychain", result);
|
|
@@ -6984,16 +7125,28 @@ function stripTrailingLineBreak(value) {
|
|
|
6984
7125
|
return value;
|
|
6985
7126
|
}
|
|
6986
7127
|
function isKeychainEntryNotFound(result) {
|
|
6987
|
-
return result
|
|
7128
|
+
return getCommandExitCode(result) === KEYCHAIN_ITEM_NOT_FOUND_EXIT_CODE;
|
|
6988
7129
|
}
|
|
6989
7130
|
function createSecurityCliFailure(operation, result) {
|
|
6990
|
-
const
|
|
7131
|
+
const exitCode = getCommandExitCode(result);
|
|
7132
|
+
const details = getCommandOutput(result, "stderr").trim() || getCommandOutput(result, "stdout").trim();
|
|
6991
7133
|
if (details) {
|
|
6992
7134
|
return new Error(
|
|
6993
|
-
`Failed to ${operation}: security exited with code ${
|
|
7135
|
+
`Failed to ${operation}: security exited with code ${exitCode}: ${details}`
|
|
6994
7136
|
);
|
|
6995
7137
|
}
|
|
6996
|
-
return new Error(`Failed to ${operation}: security exited with code ${
|
|
7138
|
+
return new Error(`Failed to ${operation}: security exited with code ${exitCode}`);
|
|
7139
|
+
}
|
|
7140
|
+
function getCommandExitCode(result) {
|
|
7141
|
+
const value = getOwnEntry3(result, "exitCode");
|
|
7142
|
+
return typeof value === "number" && Number.isInteger(value) ? value : 1;
|
|
7143
|
+
}
|
|
7144
|
+
function getCommandOutput(result, key2) {
|
|
7145
|
+
const value = getOwnEntry3(result, key2);
|
|
7146
|
+
return typeof value === "string" ? value : "";
|
|
7147
|
+
}
|
|
7148
|
+
function getOwnEntry3(record, key2) {
|
|
7149
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
6997
7150
|
}
|
|
6998
7151
|
|
|
6999
7152
|
// ../auth-store/src/create-secret-store.ts
|
|
@@ -7026,7 +7179,7 @@ function createSecretStore(input) {
|
|
|
7026
7179
|
}
|
|
7027
7180
|
function resolveBackend(input) {
|
|
7028
7181
|
const envVar = input.backendEnvVar ?? DEFAULT_BACKEND_ENV_VAR;
|
|
7029
|
-
const configuredBackend = input.backend ?? input.env
|
|
7182
|
+
const configuredBackend = input.backend ?? getOwnEnvValue(input.env, envVar) ?? getOwnEnvValue(process.env, envVar);
|
|
7030
7183
|
if (configuredBackend === "keychain") {
|
|
7031
7184
|
return "keychain";
|
|
7032
7185
|
}
|
|
@@ -7035,6 +7188,9 @@ function resolveBackend(input) {
|
|
|
7035
7188
|
}
|
|
7036
7189
|
throw new Error(`Unsupported auth store backend: ${configuredBackend}`);
|
|
7037
7190
|
}
|
|
7191
|
+
function getOwnEnvValue(env, key2) {
|
|
7192
|
+
return env !== void 0 && Object.prototype.hasOwnProperty.call(env, key2) ? env[key2] : void 0;
|
|
7193
|
+
}
|
|
7038
7194
|
|
|
7039
7195
|
// ../mcp-oauth/src/resource-indicator.ts
|
|
7040
7196
|
function canonicalizeResourceIndicator(value) {
|
|
@@ -7088,8 +7244,13 @@ function createAuthStoreClientStore(options) {
|
|
|
7088
7244
|
return null;
|
|
7089
7245
|
}
|
|
7090
7246
|
const parsed = JSON.parse(value);
|
|
7091
|
-
|
|
7092
|
-
|
|
7247
|
+
const clientId = isObjectRecord(parsed) ? getOwnString(parsed, "clientId") : void 0;
|
|
7248
|
+
if (clientId !== void 0) {
|
|
7249
|
+
const client = { clientId };
|
|
7250
|
+
if (isObjectRecord(parsed) && Object.prototype.hasOwnProperty.call(parsed, "clientSecret")) {
|
|
7251
|
+
client.clientSecret = getOwnEntry4(parsed, "clientSecret");
|
|
7252
|
+
}
|
|
7253
|
+
return client;
|
|
7093
7254
|
}
|
|
7094
7255
|
throw new Error("Stored OAuth client must be a JSON object with clientId");
|
|
7095
7256
|
},
|
|
@@ -7103,19 +7264,24 @@ function createAuthStoreClientStore(options) {
|
|
|
7103
7264
|
}
|
|
7104
7265
|
};
|
|
7105
7266
|
}
|
|
7106
|
-
function createNamedSecretStore(key2, options,
|
|
7267
|
+
function createNamedSecretStore(key2, options, defaults2) {
|
|
7107
7268
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
7108
|
-
const
|
|
7269
|
+
const configuredFilePath = options.fileStore?.filePath;
|
|
7270
|
+
const parsedFilePath = configuredFilePath === void 0 ? null : path11.parse(configuredFilePath);
|
|
7109
7271
|
const fileStore = {
|
|
7110
7272
|
...options.fileStore,
|
|
7111
|
-
|
|
7112
|
-
|
|
7273
|
+
filePath: parsedFilePath === null ? void 0 : path11.join(
|
|
7274
|
+
parsedFilePath.dir,
|
|
7275
|
+
`${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7276
|
+
),
|
|
7277
|
+
salt: options.fileStore?.salt ?? defaults2.salt,
|
|
7278
|
+
defaultDirectory: options.fileStore?.defaultDirectory || defaults2.directory,
|
|
7113
7279
|
defaultFileName: parsedFilePath === null ? `${hash}.enc` : `${parsedFilePath.name}-${hash}${parsedFilePath.ext || ".enc"}`
|
|
7114
7280
|
};
|
|
7115
7281
|
const keychainStore = {
|
|
7116
7282
|
...options.keychainStore,
|
|
7117
|
-
service: options.keychainStore?.service ??
|
|
7118
|
-
account: `${options.keychainStore?.account ??
|
|
7283
|
+
service: options.keychainStore?.service ?? defaults2.service,
|
|
7284
|
+
account: `${options.keychainStore?.account ?? defaults2.accountPrefix}:${hash}`
|
|
7119
7285
|
};
|
|
7120
7286
|
return createSecretStore({ ...options, fileStore, keychainStore }).store;
|
|
7121
7287
|
}
|
|
@@ -7143,6 +7309,16 @@ function createIssuerSecretStore(issuer, options) {
|
|
|
7143
7309
|
}
|
|
7144
7310
|
);
|
|
7145
7311
|
}
|
|
7312
|
+
function isObjectRecord(value) {
|
|
7313
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7314
|
+
}
|
|
7315
|
+
function getOwnEntry4(record, key2) {
|
|
7316
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7317
|
+
}
|
|
7318
|
+
function getOwnString(record, key2) {
|
|
7319
|
+
const value = getOwnEntry4(record, key2);
|
|
7320
|
+
return typeof value === "string" ? value : void 0;
|
|
7321
|
+
}
|
|
7146
7322
|
|
|
7147
7323
|
// ../mcp-oauth/src/client/default-oauth-client-provider.ts
|
|
7148
7324
|
import { URL as URL2 } from "node:url";
|
|
@@ -7168,17 +7344,30 @@ function parseAuthorizationState(value) {
|
|
|
7168
7344
|
try {
|
|
7169
7345
|
const decoded = Buffer.from(value, "base64url").toString("utf8");
|
|
7170
7346
|
const parsed = JSON.parse(decoded);
|
|
7171
|
-
if (parsed
|
|
7347
|
+
if (!isObjectRecord2(parsed)) {
|
|
7348
|
+
return null;
|
|
7349
|
+
}
|
|
7350
|
+
const version = getOwnEntry5(parsed, "v");
|
|
7351
|
+
const nonce = getOwnEntry5(parsed, "n");
|
|
7352
|
+
const issuer = getOwnEntry5(parsed, "i");
|
|
7353
|
+
const requireIssuer = getOwnEntry5(parsed, "r");
|
|
7354
|
+
if (version !== 1 || typeof nonce !== "string" || nonce.length === 0 || typeof issuer !== "string" || issuer.length === 0 || typeof requireIssuer !== "boolean") {
|
|
7172
7355
|
return null;
|
|
7173
7356
|
}
|
|
7174
7357
|
return {
|
|
7175
|
-
issuer
|
|
7176
|
-
requireIssuer
|
|
7358
|
+
issuer,
|
|
7359
|
+
requireIssuer
|
|
7177
7360
|
};
|
|
7178
7361
|
} catch {
|
|
7179
7362
|
return null;
|
|
7180
7363
|
}
|
|
7181
7364
|
}
|
|
7365
|
+
function isObjectRecord2(value) {
|
|
7366
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7367
|
+
}
|
|
7368
|
+
function getOwnEntry5(record, key2) {
|
|
7369
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7370
|
+
}
|
|
7182
7371
|
|
|
7183
7372
|
// ../mcp-oauth/src/client/loopback-authorization.ts
|
|
7184
7373
|
async function createLoopbackAuthorizationSession(options = {}) {
|
|
@@ -7455,22 +7644,26 @@ async function requestTokens(input) {
|
|
|
7455
7644
|
body: body.toString()
|
|
7456
7645
|
});
|
|
7457
7646
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
7458
|
-
|
|
7647
|
+
const accessToken = getOwnEntry6(payload, "access_token");
|
|
7648
|
+
if (typeof accessToken !== "string" || accessToken.trim().length === 0) {
|
|
7459
7649
|
throw new Error("OAuth token response missing access_token");
|
|
7460
7650
|
}
|
|
7461
|
-
const tokenType = normalizeBearerTokenType(payload
|
|
7651
|
+
const tokenType = normalizeBearerTokenType(getOwnEntry6(payload, "token_type"));
|
|
7462
7652
|
if (tokenType === null) {
|
|
7463
7653
|
throw new Error("OAuth token response missing token_type=Bearer");
|
|
7464
7654
|
}
|
|
7465
|
-
|
|
7655
|
+
const expiresIn = getOwnEntry6(payload, "expires_in");
|
|
7656
|
+
if (typeof expiresIn === "number" && Number.isFinite(expiresIn) && expiresIn < 0) {
|
|
7466
7657
|
throw new Error("OAuth token response has invalid expires_in");
|
|
7467
7658
|
}
|
|
7659
|
+
const refreshToken = getOwnEntry6(payload, "refresh_token");
|
|
7660
|
+
const scope = getOwnEntry6(payload, "scope");
|
|
7468
7661
|
return {
|
|
7469
|
-
accessToken
|
|
7470
|
-
refreshToken: typeof
|
|
7662
|
+
accessToken,
|
|
7663
|
+
refreshToken: typeof refreshToken === "string" && refreshToken.length > 0 ? refreshToken : void 0,
|
|
7471
7664
|
tokenType,
|
|
7472
|
-
expiresAt: typeof
|
|
7473
|
-
scope: typeof
|
|
7665
|
+
expiresAt: typeof expiresIn === "number" && Number.isFinite(expiresIn) ? input.now() + expiresIn * 1e3 : null,
|
|
7666
|
+
scope: typeof scope === "string" && scope.length > 0 ? scope : void 0
|
|
7474
7667
|
};
|
|
7475
7668
|
}
|
|
7476
7669
|
async function readOAuthJsonObjectResponse(response) {
|
|
@@ -7497,12 +7690,18 @@ async function readOAuthJsonObjectResponse(response) {
|
|
|
7497
7690
|
return record;
|
|
7498
7691
|
}
|
|
7499
7692
|
function readOAuthError(payload, fallbackError = "server_error") {
|
|
7693
|
+
const error3 = getOwnEntry6(payload, "error");
|
|
7694
|
+
const errorDescription = getOwnEntry6(payload, "error_description");
|
|
7695
|
+
const errorUri = getOwnEntry6(payload, "error_uri");
|
|
7500
7696
|
return {
|
|
7501
|
-
error: typeof
|
|
7502
|
-
error_description: typeof
|
|
7503
|
-
error_uri: typeof
|
|
7697
|
+
error: typeof error3 === "string" ? error3 : fallbackError,
|
|
7698
|
+
error_description: typeof errorDescription === "string" ? errorDescription : void 0,
|
|
7699
|
+
error_uri: typeof errorUri === "string" ? errorUri : void 0
|
|
7504
7700
|
};
|
|
7505
7701
|
}
|
|
7702
|
+
function getOwnEntry6(record, key2) {
|
|
7703
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
7704
|
+
}
|
|
7506
7705
|
function createFallbackOAuthError(status) {
|
|
7507
7706
|
const error3 = status === 503 ? "temporarily_unavailable" : "server_error";
|
|
7508
7707
|
return new OAuthError({ error: error3 }, status);
|
|
@@ -7607,7 +7806,11 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7607
7806
|
while (true) {
|
|
7608
7807
|
try {
|
|
7609
7808
|
refreshedTokens = await refreshAccessToken({
|
|
7610
|
-
tokenEndpoint:
|
|
7809
|
+
tokenEndpoint: requireOwnString(
|
|
7810
|
+
discovery.authorizationServerMetadata,
|
|
7811
|
+
"token_endpoint",
|
|
7812
|
+
"Authorization server metadata"
|
|
7813
|
+
),
|
|
7611
7814
|
clientId: session.client.clientId,
|
|
7612
7815
|
clientSecret: session.client.clientSecret,
|
|
7613
7816
|
refreshToken: session.tokens.refreshToken,
|
|
@@ -7695,7 +7898,11 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7695
7898
|
});
|
|
7696
7899
|
const code = await loopback.waitForCode(authorizationUrl);
|
|
7697
7900
|
const tokens = await exchangeAuthorizationCode({
|
|
7698
|
-
tokenEndpoint:
|
|
7901
|
+
tokenEndpoint: requireOwnString(
|
|
7902
|
+
discovery.authorizationServerMetadata,
|
|
7903
|
+
"token_endpoint",
|
|
7904
|
+
"Authorization server metadata"
|
|
7905
|
+
),
|
|
7699
7906
|
clientId: resolvedClient.client.clientId,
|
|
7700
7907
|
clientSecret: resolvedClient.client.clientSecret,
|
|
7701
7908
|
code,
|
|
@@ -7748,7 +7955,10 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7748
7955
|
}
|
|
7749
7956
|
};
|
|
7750
7957
|
}
|
|
7751
|
-
const registrationEndpoint =
|
|
7958
|
+
const registrationEndpoint = getOwnString2(
|
|
7959
|
+
discovery.authorizationServerMetadata,
|
|
7960
|
+
"registration_endpoint"
|
|
7961
|
+
);
|
|
7752
7962
|
if (registrationEndpoint === void 0 && options.client.clientId !== void 0) {
|
|
7753
7963
|
return {
|
|
7754
7964
|
kind: "static",
|
|
@@ -7800,12 +8010,14 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7800
8010
|
body: JSON.stringify(registrationBody)
|
|
7801
8011
|
});
|
|
7802
8012
|
const payload = await readOAuthJsonObjectResponse(response);
|
|
7803
|
-
|
|
8013
|
+
const clientId = getOwnString2(payload, "client_id");
|
|
8014
|
+
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
7804
8015
|
throw new Error("OAuth client registration response missing client_id");
|
|
7805
8016
|
}
|
|
8017
|
+
const clientSecret = getOwnString2(payload, "client_secret");
|
|
7806
8018
|
const registeredClient = {
|
|
7807
|
-
clientId
|
|
7808
|
-
clientSecret:
|
|
8019
|
+
clientId,
|
|
8020
|
+
clientSecret: clientSecret !== void 0 && clientSecret.length > 0 ? clientSecret : void 0
|
|
7809
8021
|
};
|
|
7810
8022
|
await saveRegisteredClient(discovery.authorizationServer, registeredClient);
|
|
7811
8023
|
return {
|
|
@@ -7831,12 +8043,13 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7831
8043
|
return null;
|
|
7832
8044
|
}
|
|
7833
8045
|
const client = await clientStore.load(issuer);
|
|
7834
|
-
|
|
8046
|
+
const normalizedClient = client === null ? null : normalizeStoredClient(client);
|
|
8047
|
+
if (client !== null && normalizedClient === null) {
|
|
7835
8048
|
await clientStore.clear(issuer);
|
|
7836
8049
|
return null;
|
|
7837
8050
|
}
|
|
7838
|
-
registeredClients.set(issuer,
|
|
7839
|
-
return
|
|
8051
|
+
registeredClients.set(issuer, normalizedClient);
|
|
8052
|
+
return normalizedClient;
|
|
7840
8053
|
}
|
|
7841
8054
|
async function saveRegisteredClient(issuer, client) {
|
|
7842
8055
|
registeredClients.set(issuer, client);
|
|
@@ -7852,7 +8065,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
7852
8065
|
}
|
|
7853
8066
|
}
|
|
7854
8067
|
function isProviderOptions(options) {
|
|
7855
|
-
return "provider"
|
|
8068
|
+
return Object.prototype.hasOwnProperty.call(options, "provider");
|
|
7856
8069
|
}
|
|
7857
8070
|
function isExpired(tokens, now) {
|
|
7858
8071
|
return tokens.expiresAt !== null && tokens.expiresAt <= now();
|
|
@@ -7868,7 +8081,14 @@ function resolveDiscovery(discovery, session) {
|
|
|
7868
8081
|
return void 0;
|
|
7869
8082
|
}
|
|
7870
8083
|
const metadata = session.discovery.authorizationServerMetadata;
|
|
7871
|
-
|
|
8084
|
+
const issuer = getOwnString2(metadata, "issuer");
|
|
8085
|
+
const authorizationEndpoint = getOwnString2(metadata, "authorization_endpoint");
|
|
8086
|
+
const tokenEndpoint = getOwnString2(metadata, "token_endpoint");
|
|
8087
|
+
const codeChallengeMethodsSupported = getOwnStringArray(
|
|
8088
|
+
metadata,
|
|
8089
|
+
"code_challenge_methods_supported"
|
|
8090
|
+
);
|
|
8091
|
+
if (issuer === void 0 || authorizationEndpoint === void 0 || tokenEndpoint === void 0 || codeChallengeMethodsSupported === void 0 || !codeChallengeMethodsSupported.includes("S256")) {
|
|
7872
8092
|
return void 0;
|
|
7873
8093
|
}
|
|
7874
8094
|
return {
|
|
@@ -7892,29 +8112,94 @@ function normalizeLoadedSession(session) {
|
|
|
7892
8112
|
if (session === null) {
|
|
7893
8113
|
return null;
|
|
7894
8114
|
}
|
|
7895
|
-
|
|
8115
|
+
const client = normalizeStoredClient(getOwnEntry7(session, "client"));
|
|
8116
|
+
if (client === null) {
|
|
7896
8117
|
return { ...session, client: { clientId: "" }, tokens: void 0 };
|
|
7897
8118
|
}
|
|
7898
|
-
return
|
|
8119
|
+
return {
|
|
8120
|
+
...session,
|
|
8121
|
+
client,
|
|
8122
|
+
tokens: normalizeStoredTokens(getOwnEntry7(session, "tokens"))
|
|
8123
|
+
};
|
|
7899
8124
|
}
|
|
7900
|
-
function
|
|
7901
|
-
|
|
8125
|
+
function normalizeStoredClient(value) {
|
|
8126
|
+
if (!isObjectRecord3(value)) {
|
|
8127
|
+
return null;
|
|
8128
|
+
}
|
|
8129
|
+
const clientId = getOwnString2(value, "clientId");
|
|
8130
|
+
if (clientId === void 0 || clientId.trim().length === 0) {
|
|
8131
|
+
return null;
|
|
8132
|
+
}
|
|
8133
|
+
const clientSecret = getOwnEntry7(value, "clientSecret");
|
|
8134
|
+
if (clientSecret === void 0) {
|
|
8135
|
+
return { clientId };
|
|
8136
|
+
}
|
|
8137
|
+
if (typeof clientSecret !== "string" || clientSecret.trim().length === 0) {
|
|
8138
|
+
return null;
|
|
8139
|
+
}
|
|
8140
|
+
return { clientId, clientSecret };
|
|
7902
8141
|
}
|
|
7903
|
-
function
|
|
7904
|
-
if (
|
|
7905
|
-
return
|
|
8142
|
+
function normalizeStoredTokens(value) {
|
|
8143
|
+
if (value === void 0 || !isObjectRecord3(value)) {
|
|
8144
|
+
return void 0;
|
|
8145
|
+
}
|
|
8146
|
+
const accessToken = getOwnString2(value, "accessToken");
|
|
8147
|
+
const tokenType = getOwnString2(value, "tokenType");
|
|
8148
|
+
const expiresAt = getOwnEntry7(value, "expiresAt");
|
|
8149
|
+
const refreshToken = getOwnEntry7(value, "refreshToken");
|
|
8150
|
+
const scope = getOwnString2(value, "scope");
|
|
8151
|
+
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken : void 0;
|
|
8152
|
+
if (accessToken === void 0 || accessToken.trim().length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isFinite(expiresAt)) || refreshToken !== void 0 && (typeof refreshToken !== "string" || refreshToken.trim().length === 0)) {
|
|
8153
|
+
return void 0;
|
|
7906
8154
|
}
|
|
7907
|
-
return
|
|
8155
|
+
return {
|
|
8156
|
+
accessToken,
|
|
8157
|
+
tokenType,
|
|
8158
|
+
expiresAt,
|
|
8159
|
+
...normalizedRefreshToken === void 0 ? {} : { refreshToken: normalizedRefreshToken },
|
|
8160
|
+
...scope === void 0 || scope.length === 0 ? {} : { scope }
|
|
8161
|
+
};
|
|
7908
8162
|
}
|
|
7909
8163
|
function getClientMetadata(client) {
|
|
7910
8164
|
return client.metadata;
|
|
7911
8165
|
}
|
|
8166
|
+
function getOwnEntry7(record, key2) {
|
|
8167
|
+
return Object.prototype.hasOwnProperty.call(record, key2) ? record[key2] : void 0;
|
|
8168
|
+
}
|
|
8169
|
+
function isObjectRecord3(value) {
|
|
8170
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8171
|
+
}
|
|
8172
|
+
function getOwnString2(record, key2) {
|
|
8173
|
+
const value = getOwnEntry7(record, key2);
|
|
8174
|
+
return typeof value === "string" ? value : void 0;
|
|
8175
|
+
}
|
|
8176
|
+
function requireOwnString(record, key2, label) {
|
|
8177
|
+
const value = getOwnString2(record, key2);
|
|
8178
|
+
if (value === void 0) {
|
|
8179
|
+
throw new Error(`${label} is missing ${key2}`);
|
|
8180
|
+
}
|
|
8181
|
+
return value;
|
|
8182
|
+
}
|
|
8183
|
+
function getOwnStringArray(record, key2) {
|
|
8184
|
+
const value = getOwnEntry7(record, key2);
|
|
8185
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
|
|
8186
|
+
}
|
|
7912
8187
|
function buildAuthorizationUrl(input) {
|
|
7913
|
-
const
|
|
8188
|
+
const authorizationEndpoint = requireOwnString(
|
|
8189
|
+
input.metadata,
|
|
8190
|
+
"authorization_endpoint",
|
|
8191
|
+
"Authorization server metadata"
|
|
8192
|
+
);
|
|
8193
|
+
const issuer = requireOwnString(
|
|
8194
|
+
input.metadata,
|
|
8195
|
+
"issuer",
|
|
8196
|
+
"Authorization server metadata"
|
|
8197
|
+
);
|
|
8198
|
+
const url = new URL2(authorizationEndpoint);
|
|
7914
8199
|
const resource = canonicalizeResourceIndicator(input.resource);
|
|
7915
8200
|
const state = createAuthorizationState({
|
|
7916
|
-
issuer
|
|
7917
|
-
requireIssuer: input.metadata
|
|
8201
|
+
issuer,
|
|
8202
|
+
requireIssuer: getOwnEntry7(input.metadata, "authorization_response_iss_parameter_supported") === true
|
|
7918
8203
|
});
|
|
7919
8204
|
url.searchParams.set("response_type", "code");
|
|
7920
8205
|
url.searchParams.set("client_id", input.clientId);
|
|
@@ -7929,7 +8214,7 @@ function buildAuthorizationUrl(input) {
|
|
|
7929
8214
|
return url.toString();
|
|
7930
8215
|
}
|
|
7931
8216
|
function assertS256PkceSupport(metadata) {
|
|
7932
|
-
if (!metadata
|
|
8217
|
+
if (!getOwnStringArray(metadata, "code_challenge_methods_supported")?.includes("S256")) {
|
|
7933
8218
|
throw new Error(
|
|
7934
8219
|
"Authorization server metadata must advertise code_challenge_methods_supported including S256"
|
|
7935
8220
|
);
|
|
@@ -7953,13 +8238,24 @@ function assertSecureUrl(value, label) {
|
|
|
7953
8238
|
throw new Error(`${label} must use https unless it targets a loopback host`);
|
|
7954
8239
|
}
|
|
7955
8240
|
function assertSecureOAuthFlowEndpoints(metadata) {
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
8241
|
+
const authorizationEndpoint = requireOwnString(
|
|
8242
|
+
metadata,
|
|
8243
|
+
"authorization_endpoint",
|
|
8244
|
+
"Authorization server metadata"
|
|
8245
|
+
);
|
|
8246
|
+
const tokenEndpoint = requireOwnString(
|
|
8247
|
+
metadata,
|
|
8248
|
+
"token_endpoint",
|
|
8249
|
+
"Authorization server metadata"
|
|
8250
|
+
);
|
|
8251
|
+
const registrationEndpoint = getOwnString2(metadata, "registration_endpoint");
|
|
8252
|
+
assertNoAccessTokenInUrl(authorizationEndpoint, "Authorization endpoint");
|
|
8253
|
+
assertNoAccessTokenInUrl(tokenEndpoint, "Token endpoint");
|
|
8254
|
+
assertSecureUrl(authorizationEndpoint, "Authorization endpoint");
|
|
8255
|
+
assertSecureUrl(tokenEndpoint, "Token endpoint");
|
|
8256
|
+
if (registrationEndpoint !== void 0) {
|
|
8257
|
+
assertNoAccessTokenInUrl(registrationEndpoint, "Registration endpoint");
|
|
8258
|
+
assertSecureUrl(registrationEndpoint, "Registration endpoint");
|
|
7963
8259
|
}
|
|
7964
8260
|
}
|
|
7965
8261
|
function assertNoAccessTokenInUrl(value, label) {
|
|
@@ -7982,17 +8278,21 @@ function buildClientRegistrationBody(metadata, redirectUri) {
|
|
|
7982
8278
|
response_types: ["code"],
|
|
7983
8279
|
token_endpoint_auth_method: "none"
|
|
7984
8280
|
};
|
|
7985
|
-
|
|
7986
|
-
|
|
8281
|
+
const clientName = metadata === void 0 ? void 0 : getOwnString2(metadata, "clientName");
|
|
8282
|
+
const scope = metadata === void 0 ? void 0 : getOwnString2(metadata, "scope");
|
|
8283
|
+
const softwareId = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareId");
|
|
8284
|
+
const softwareVersion = metadata === void 0 ? void 0 : getOwnString2(metadata, "softwareVersion");
|
|
8285
|
+
if (clientName !== void 0 && clientName.length > 0) {
|
|
8286
|
+
body.client_name = clientName;
|
|
7987
8287
|
}
|
|
7988
|
-
if (
|
|
7989
|
-
body.scope =
|
|
8288
|
+
if (scope !== void 0 && scope.length > 0) {
|
|
8289
|
+
body.scope = scope;
|
|
7990
8290
|
}
|
|
7991
|
-
if (
|
|
7992
|
-
body.software_id =
|
|
8291
|
+
if (softwareId !== void 0 && softwareId.length > 0) {
|
|
8292
|
+
body.software_id = softwareId;
|
|
7993
8293
|
}
|
|
7994
|
-
if (
|
|
7995
|
-
body.software_version =
|
|
8294
|
+
if (softwareVersion !== void 0 && softwareVersion.length > 0) {
|
|
8295
|
+
body.software_version = softwareVersion;
|
|
7996
8296
|
}
|
|
7997
8297
|
return body;
|
|
7998
8298
|
}
|
|
@@ -8028,7 +8328,7 @@ import {
|
|
|
8028
8328
|
function defaultOAuthMetadataFetch(input, init) {
|
|
8029
8329
|
return fetch(input, init);
|
|
8030
8330
|
}
|
|
8031
|
-
function
|
|
8331
|
+
function isObjectRecord4(value) {
|
|
8032
8332
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8033
8333
|
}
|
|
8034
8334
|
function isStringArray(value) {
|
|
@@ -8051,7 +8351,7 @@ function assertSecureUrl2(url, label) {
|
|
|
8051
8351
|
throw new Error(`${label} must use https unless it targets a loopback host`);
|
|
8052
8352
|
}
|
|
8053
8353
|
function validateProtectedResourceMetadata(value, resourceUrl) {
|
|
8054
|
-
if (!
|
|
8354
|
+
if (!isObjectRecord4(value)) {
|
|
8055
8355
|
throw new Error("Protected resource metadata must be a JSON object");
|
|
8056
8356
|
}
|
|
8057
8357
|
if (typeof value.resource !== "string" || value.resource.length === 0) {
|
|
@@ -8074,7 +8374,7 @@ function validateProtectedResourceMetadata(value, resourceUrl) {
|
|
|
8074
8374
|
};
|
|
8075
8375
|
}
|
|
8076
8376
|
function validateAuthorizationServerMetadata(value, issuer) {
|
|
8077
|
-
if (!
|
|
8377
|
+
if (!isObjectRecord4(value)) {
|
|
8078
8378
|
throw new Error("Authorization server metadata must be a JSON object");
|
|
8079
8379
|
}
|
|
8080
8380
|
if (typeof value.issuer !== "string" || value.issuer.length === 0) {
|
|
@@ -8527,7 +8827,7 @@ var McpClient = class {
|
|
|
8527
8827
|
await onPromptsChanged();
|
|
8528
8828
|
});
|
|
8529
8829
|
messageLayer.onNotification("notifications/message", async (params17) => {
|
|
8530
|
-
if (onLog === void 0 || !
|
|
8830
|
+
if (onLog === void 0 || !isObjectRecord5(params17) || !isLogLevel(params17.level)) {
|
|
8531
8831
|
return;
|
|
8532
8832
|
}
|
|
8533
8833
|
if (!hasOwn(params17, "data")) {
|
|
@@ -8546,7 +8846,7 @@ var McpClient = class {
|
|
|
8546
8846
|
await onLog(message2);
|
|
8547
8847
|
});
|
|
8548
8848
|
messageLayer.onNotification("notifications/progress", async (params17) => {
|
|
8549
|
-
if (onProgress === void 0 || !
|
|
8849
|
+
if (onProgress === void 0 || !isObjectRecord5(params17)) {
|
|
8550
8850
|
return;
|
|
8551
8851
|
}
|
|
8552
8852
|
const { progressToken, progress } = params17;
|
|
@@ -8715,6 +9015,9 @@ var McpClient = class {
|
|
|
8715
9015
|
const abortPromise = new Promise((_, reject) => {
|
|
8716
9016
|
const rejectWithAbortReason = () => {
|
|
8717
9017
|
sendCancellationNotification();
|
|
9018
|
+
if (requestId !== void 0) {
|
|
9019
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
9020
|
+
}
|
|
8718
9021
|
reject(signal.reason);
|
|
8719
9022
|
};
|
|
8720
9023
|
abortListener = rejectWithAbortReason;
|
|
@@ -8889,11 +9192,13 @@ var StdioTransport = class _StdioTransport {
|
|
|
8889
9192
|
const child = this.child;
|
|
8890
9193
|
this.readable = child.stdout;
|
|
8891
9194
|
this.writable = child.stdin;
|
|
9195
|
+
const stderrDecoder = new TextDecoder();
|
|
8892
9196
|
child.stderr.on("data", (chunk) => {
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
9197
|
+
const decoded = chunk instanceof Uint8Array ? stderrDecoder.decode(chunk, { stream: true }) : `${stderrDecoder.decode()}${String(chunk)}`;
|
|
9198
|
+
this.appendStderrOutput(decoded);
|
|
9199
|
+
});
|
|
9200
|
+
child.stderr.once("end", () => {
|
|
9201
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
8897
9202
|
});
|
|
8898
9203
|
this.closed = new Promise((resolve) => {
|
|
8899
9204
|
let settled = false;
|
|
@@ -8933,6 +9238,15 @@ var StdioTransport = class _StdioTransport {
|
|
|
8933
9238
|
getStderrOutput() {
|
|
8934
9239
|
return this.stderrOutput;
|
|
8935
9240
|
}
|
|
9241
|
+
appendStderrOutput(chunk) {
|
|
9242
|
+
if (chunk.length === 0) {
|
|
9243
|
+
return;
|
|
9244
|
+
}
|
|
9245
|
+
this.stderrOutput += chunk;
|
|
9246
|
+
if (this.stderrOutput.length > _StdioTransport.STDERR_MAX_LENGTH) {
|
|
9247
|
+
this.stderrOutput = this.stderrOutput.slice(-_StdioTransport.STDERR_MAX_LENGTH);
|
|
9248
|
+
}
|
|
9249
|
+
}
|
|
8936
9250
|
dispose(reason = new Error("Stdio transport disposed")) {
|
|
8937
9251
|
void reason;
|
|
8938
9252
|
if (this.disposed) {
|
|
@@ -9340,15 +9654,6 @@ function serializeJsonRpcMessage(message2) {
|
|
|
9340
9654
|
return `${JSON.stringify(message2)}
|
|
9341
9655
|
`;
|
|
9342
9656
|
}
|
|
9343
|
-
function chunkToString(chunk) {
|
|
9344
|
-
if (typeof chunk === "string") {
|
|
9345
|
-
return chunk;
|
|
9346
|
-
}
|
|
9347
|
-
if (chunk instanceof Uint8Array) {
|
|
9348
|
-
return Buffer.from(chunk).toString("utf8");
|
|
9349
|
-
}
|
|
9350
|
-
return String(chunk);
|
|
9351
|
-
}
|
|
9352
9657
|
function normalizeLine(line) {
|
|
9353
9658
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
9354
9659
|
}
|
|
@@ -9538,6 +9843,16 @@ var JsonRpcMessageLayer = class {
|
|
|
9538
9843
|
}
|
|
9539
9844
|
});
|
|
9540
9845
|
}
|
|
9846
|
+
cancelRequest(requestId, reason) {
|
|
9847
|
+
const pending = this.pendingRequests.get(requestId);
|
|
9848
|
+
if (pending === void 0) {
|
|
9849
|
+
return false;
|
|
9850
|
+
}
|
|
9851
|
+
this.pendingRequests.delete(requestId);
|
|
9852
|
+
clearTimeout(pending.timeout);
|
|
9853
|
+
pending.reject(reason);
|
|
9854
|
+
return true;
|
|
9855
|
+
}
|
|
9541
9856
|
dispose(reason = new Error("JSON-RPC message layer disposed")) {
|
|
9542
9857
|
if (this.disposedError !== void 0) {
|
|
9543
9858
|
return;
|
|
@@ -9732,7 +10047,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9732
10047
|
})();
|
|
9733
10048
|
}
|
|
9734
10049
|
handleCancellationNotification(params17) {
|
|
9735
|
-
if (!
|
|
10050
|
+
if (!isObjectRecord5(params17)) {
|
|
9736
10051
|
return;
|
|
9737
10052
|
}
|
|
9738
10053
|
const requestId = params17.requestId;
|
|
@@ -9747,34 +10062,34 @@ var JsonRpcMessageLayer = class {
|
|
|
9747
10062
|
this.activeIncomingRequests.delete(requestId);
|
|
9748
10063
|
}
|
|
9749
10064
|
};
|
|
9750
|
-
function
|
|
10065
|
+
function isObjectRecord5(value) {
|
|
9751
10066
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9752
10067
|
}
|
|
9753
10068
|
function isInitializeResult(value) {
|
|
9754
|
-
if (!
|
|
10069
|
+
if (!isObjectRecord5(value) || typeof value.protocolVersion !== "string") {
|
|
9755
10070
|
return false;
|
|
9756
10071
|
}
|
|
9757
10072
|
if (!isServerCapabilities(value.capabilities)) {
|
|
9758
10073
|
return false;
|
|
9759
10074
|
}
|
|
9760
|
-
if (!
|
|
10075
|
+
if (!isObjectRecord5(value.serverInfo) || typeof value.serverInfo.name !== "string" || value.serverInfo.name.length === 0 || typeof value.serverInfo.version !== "string" || value.serverInfo.version.length === 0) {
|
|
9761
10076
|
return false;
|
|
9762
10077
|
}
|
|
9763
10078
|
return value.instructions === void 0 || typeof value.instructions === "string";
|
|
9764
10079
|
}
|
|
9765
10080
|
function isServerCapabilities(value) {
|
|
9766
|
-
if (!
|
|
10081
|
+
if (!isObjectRecord5(value)) {
|
|
9767
10082
|
return false;
|
|
9768
10083
|
}
|
|
9769
10084
|
for (const capability of ["prompts", "resources", "tools", "logging", "completions", "experimental"]) {
|
|
9770
|
-
if (value[capability] !== void 0 && !
|
|
10085
|
+
if (value[capability] !== void 0 && !isObjectRecord5(value[capability])) {
|
|
9771
10086
|
return false;
|
|
9772
10087
|
}
|
|
9773
10088
|
}
|
|
9774
10089
|
return true;
|
|
9775
10090
|
}
|
|
9776
10091
|
function isCallToolResult(value) {
|
|
9777
|
-
if (!
|
|
10092
|
+
if (!isObjectRecord5(value) || !Array.isArray(value.content)) {
|
|
9778
10093
|
return false;
|
|
9779
10094
|
}
|
|
9780
10095
|
if (value.isError !== void 0 && typeof value.isError !== "boolean") {
|
|
@@ -9783,10 +10098,10 @@ function isCallToolResult(value) {
|
|
|
9783
10098
|
return value.content.every(isContentItem);
|
|
9784
10099
|
}
|
|
9785
10100
|
function isToolsListResult(value) {
|
|
9786
|
-
return
|
|
10101
|
+
return isObjectRecord5(value) && Array.isArray(value.tools) && (value.nextCursor === void 0 || typeof value.nextCursor === "string");
|
|
9787
10102
|
}
|
|
9788
10103
|
function isContentItem(value) {
|
|
9789
|
-
if (!
|
|
10104
|
+
if (!isObjectRecord5(value)) {
|
|
9790
10105
|
return false;
|
|
9791
10106
|
}
|
|
9792
10107
|
if (value.type === "text") {
|
|
@@ -9795,7 +10110,7 @@ function isContentItem(value) {
|
|
|
9795
10110
|
if (value.type === "image" || value.type === "audio") {
|
|
9796
10111
|
return typeof value.data === "string" && typeof value.mimeType === "string";
|
|
9797
10112
|
}
|
|
9798
|
-
if (value.type !== "resource" || !
|
|
10113
|
+
if (value.type !== "resource" || !isObjectRecord5(value.resource)) {
|
|
9799
10114
|
return false;
|
|
9800
10115
|
}
|
|
9801
10116
|
return typeof value.resource.uri === "string" && (value.resource.mimeType === void 0 || typeof value.resource.mimeType === "string") && (typeof value.resource.text === "string" || typeof value.resource.blob === "string");
|
|
@@ -9819,7 +10134,7 @@ function invalidRequest() {
|
|
|
9819
10134
|
return new McpError(ERROR_INVALID_REQUEST, "Invalid Request");
|
|
9820
10135
|
}
|
|
9821
10136
|
function isJsonRpcErrorObject(value) {
|
|
9822
|
-
if (!
|
|
10137
|
+
if (!isObjectRecord5(value)) {
|
|
9823
10138
|
return false;
|
|
9824
10139
|
}
|
|
9825
10140
|
if (typeof value.code !== "number" || typeof value.message !== "string") {
|
|
@@ -9828,7 +10143,7 @@ function isJsonRpcErrorObject(value) {
|
|
|
9828
10143
|
return value.data === void 0 || hasOwn(value, "data");
|
|
9829
10144
|
}
|
|
9830
10145
|
function parseJsonRpcPayload(parsed) {
|
|
9831
|
-
if (!
|
|
10146
|
+
if (!isObjectRecord5(parsed)) {
|
|
9832
10147
|
return {
|
|
9833
10148
|
type: "invalid",
|
|
9834
10149
|
id: null,
|
|
@@ -10155,7 +10470,11 @@ function convertObjectSchema(schema, root, options) {
|
|
|
10155
10470
|
"properties",
|
|
10156
10471
|
key2
|
|
10157
10472
|
]);
|
|
10158
|
-
|
|
10473
|
+
setOwnShapeProperty(
|
|
10474
|
+
shape,
|
|
10475
|
+
key2,
|
|
10476
|
+
requiredKeys.has(key2) ? convertedProperty : S.Optional(convertedProperty)
|
|
10477
|
+
);
|
|
10159
10478
|
}
|
|
10160
10479
|
return applyMetadata(
|
|
10161
10480
|
S.Object(shape, {
|
|
@@ -10167,6 +10486,14 @@ function convertObjectSchema(schema, root, options) {
|
|
|
10167
10486
|
}
|
|
10168
10487
|
);
|
|
10169
10488
|
}
|
|
10489
|
+
function setOwnShapeProperty(shape, key2, value) {
|
|
10490
|
+
Object.defineProperty(shape, key2, {
|
|
10491
|
+
configurable: true,
|
|
10492
|
+
enumerable: true,
|
|
10493
|
+
writable: true,
|
|
10494
|
+
value
|
|
10495
|
+
});
|
|
10496
|
+
}
|
|
10170
10497
|
function createCommonOptions(schema, nullable, defaultValue) {
|
|
10171
10498
|
return {
|
|
10172
10499
|
...schema.description === void 0 ? {} : { description: schema.description },
|
|
@@ -10417,6 +10744,9 @@ function resolveLocalRef(root, ref) {
|
|
|
10417
10744
|
if (!isPlainObject(current)) {
|
|
10418
10745
|
return void 0;
|
|
10419
10746
|
}
|
|
10747
|
+
if (!Object.prototype.hasOwnProperty.call(current, segment)) {
|
|
10748
|
+
return void 0;
|
|
10749
|
+
}
|
|
10420
10750
|
current = current[segment];
|
|
10421
10751
|
}
|
|
10422
10752
|
return isPlainObject(current) ? current : void 0;
|
|
@@ -10606,10 +10936,10 @@ function validateRenameMap2(name, tools, rename5) {
|
|
|
10606
10936
|
}
|
|
10607
10937
|
}
|
|
10608
10938
|
}
|
|
10609
|
-
function createConnection(name,
|
|
10939
|
+
function createConnection(name, config2) {
|
|
10610
10940
|
const connection = {
|
|
10611
10941
|
name,
|
|
10612
|
-
config,
|
|
10942
|
+
config: config2,
|
|
10613
10943
|
async dispose() {
|
|
10614
10944
|
shutdownDisposers.delete(connection.dispose);
|
|
10615
10945
|
connection.connecting = void 0;
|
|
@@ -10665,24 +10995,42 @@ async function readCache(cachePath) {
|
|
|
10665
10995
|
}
|
|
10666
10996
|
async function writeCache(cachePath, cache) {
|
|
10667
10997
|
const directory = path12.dirname(cachePath);
|
|
10668
|
-
const tempPath = `${cachePath}.tmp-${
|
|
10998
|
+
const tempPath = `${cachePath}.tmp-${randomUUID4()}`;
|
|
10999
|
+
let tempCreated = false;
|
|
10669
11000
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10670
11001
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10671
11002
|
await mkdir(directory, { recursive: true });
|
|
10672
11003
|
await assertCachePathHasNoSymlinks(directory);
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
11004
|
+
try {
|
|
11005
|
+
await writeFile3(tempPath, `${JSON.stringify(cache, null, 2)}
|
|
11006
|
+
`, {
|
|
11007
|
+
encoding: "utf8",
|
|
11008
|
+
flag: "wx"
|
|
11009
|
+
});
|
|
11010
|
+
tempCreated = true;
|
|
11011
|
+
await assertCachePathHasNoSymlinks(tempPath);
|
|
11012
|
+
await assertCachePathHasNoSymlinks(cachePath);
|
|
11013
|
+
await rename2(tempPath, cachePath);
|
|
11014
|
+
tempCreated = false;
|
|
11015
|
+
} catch (error3) {
|
|
11016
|
+
if (tempCreated || !isAlreadyExistsError2(error3)) {
|
|
11017
|
+
await unlink2(tempPath).catch(() => void 0);
|
|
11018
|
+
}
|
|
11019
|
+
throw error3;
|
|
11020
|
+
}
|
|
10678
11021
|
}
|
|
10679
|
-
|
|
11022
|
+
function isAlreadyExistsError2(error3) {
|
|
11023
|
+
return Boolean(
|
|
11024
|
+
error3 && typeof error3 === "object" && error3.code === "EEXIST"
|
|
11025
|
+
);
|
|
11026
|
+
}
|
|
11027
|
+
async function fetchCache(name, config2) {
|
|
10680
11028
|
const logger2 = createLogger((message2) => {
|
|
10681
11029
|
process.stderr.write(`${message2}
|
|
10682
11030
|
`);
|
|
10683
11031
|
});
|
|
10684
11032
|
logger2.info(`MCP ${name}: connecting`);
|
|
10685
|
-
const client = await dialUpstream(name,
|
|
11033
|
+
const client = await dialUpstream(name, config2);
|
|
10686
11034
|
try {
|
|
10687
11035
|
logger2.info(`MCP ${name}: listing tools`);
|
|
10688
11036
|
const tools = [];
|
|
@@ -10701,7 +11049,7 @@ async function fetchCache(name, config) {
|
|
|
10701
11049
|
$schema: MCP_PROXY_SCHEMA_URL,
|
|
10702
11050
|
version: 1,
|
|
10703
11051
|
upstream,
|
|
10704
|
-
configFingerprint: fingerprintMcpServerConfig(
|
|
11052
|
+
configFingerprint: fingerprintMcpServerConfig(config2),
|
|
10705
11053
|
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10706
11054
|
tools
|
|
10707
11055
|
};
|
|
@@ -10771,8 +11119,8 @@ function isRefreshRequested(name, refresh) {
|
|
|
10771
11119
|
}
|
|
10772
11120
|
async function resolveSingleProxy(group, options) {
|
|
10773
11121
|
const internal = getInternalGroupConfig2(group);
|
|
10774
|
-
const
|
|
10775
|
-
if (
|
|
11122
|
+
const config2 = internal.mcp;
|
|
11123
|
+
if (config2 === void 0) {
|
|
10776
11124
|
return;
|
|
10777
11125
|
}
|
|
10778
11126
|
const name = group.name;
|
|
@@ -10782,21 +11130,21 @@ async function resolveSingleProxy(group, options) {
|
|
|
10782
11130
|
let cache;
|
|
10783
11131
|
let shouldWriteCache = false;
|
|
10784
11132
|
if (isRefreshRequested(name, refresh)) {
|
|
10785
|
-
cache = await fetchCache(name,
|
|
11133
|
+
cache = await fetchCache(name, config2);
|
|
10786
11134
|
shouldWriteCache = true;
|
|
10787
11135
|
} else {
|
|
10788
11136
|
const storedCache = await readCache(cachePath);
|
|
10789
|
-
if (storedCache && cacheMatchesConfig(storedCache,
|
|
11137
|
+
if (storedCache && cacheMatchesConfig(storedCache, config2)) {
|
|
10790
11138
|
cache = storedCache;
|
|
10791
11139
|
} else {
|
|
10792
|
-
cache = await fetchCache(name,
|
|
11140
|
+
cache = await fetchCache(name, config2);
|
|
10793
11141
|
shouldWriteCache = true;
|
|
10794
11142
|
}
|
|
10795
11143
|
}
|
|
10796
11144
|
const tools = filterAllowlistedTools(cache.tools, internal.tools);
|
|
10797
11145
|
validateRenameMap2(name, tools, internal.rename);
|
|
10798
11146
|
const previousConnection = getProxyConnection(group);
|
|
10799
|
-
const nextConnection = createConnection(name,
|
|
11147
|
+
const nextConnection = createConnection(name, config2);
|
|
10800
11148
|
try {
|
|
10801
11149
|
replaceProxyChildrenSafely(group, tools, internal.rename, nextConnection);
|
|
10802
11150
|
if (shouldWriteCache) {
|
|
@@ -10821,11 +11169,11 @@ async function resolveSingleProxy(group, options) {
|
|
|
10821
11169
|
);
|
|
10822
11170
|
}
|
|
10823
11171
|
}
|
|
10824
|
-
function cacheMatchesConfig(cache,
|
|
10825
|
-
return cache.configFingerprint === fingerprintMcpServerConfig(
|
|
11172
|
+
function cacheMatchesConfig(cache, config2) {
|
|
11173
|
+
return cache.configFingerprint === fingerprintMcpServerConfig(config2);
|
|
10826
11174
|
}
|
|
10827
|
-
function fingerprintMcpServerConfig(
|
|
10828
|
-
return createHash3("sha256").update(JSON.stringify(
|
|
11175
|
+
function fingerprintMcpServerConfig(config2) {
|
|
11176
|
+
return createHash3("sha256").update(JSON.stringify(config2)).digest("hex");
|
|
10829
11177
|
}
|
|
10830
11178
|
function collectProxyGroups(root) {
|
|
10831
11179
|
const groups = [];
|
|
@@ -10903,20 +11251,20 @@ function parseRefreshEnv(value) {
|
|
|
10903
11251
|
const names = trimmed.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
10904
11252
|
return names.length === 0 ? void 0 : new Set(names);
|
|
10905
11253
|
}
|
|
10906
|
-
async function dialUpstream(name,
|
|
11254
|
+
async function dialUpstream(name, config2) {
|
|
10907
11255
|
const client = new McpClient({
|
|
10908
11256
|
clientInfo: {
|
|
10909
11257
|
name: `${DEFAULT_CLIENT_INFO.name}-${name}`,
|
|
10910
11258
|
version: DEFAULT_CLIENT_INFO.version
|
|
10911
11259
|
}
|
|
10912
11260
|
});
|
|
10913
|
-
const transport =
|
|
10914
|
-
command:
|
|
10915
|
-
...
|
|
10916
|
-
...
|
|
11261
|
+
const transport = config2.transport === "stdio" ? new StdioTransport({
|
|
11262
|
+
command: config2.command,
|
|
11263
|
+
...config2.args === void 0 ? {} : { args: config2.args },
|
|
11264
|
+
...config2.env === void 0 ? {} : { env: config2.env }
|
|
10917
11265
|
}) : new HttpTransport({
|
|
10918
|
-
url:
|
|
10919
|
-
...
|
|
11266
|
+
url: config2.url,
|
|
11267
|
+
...config2.headers === void 0 ? {} : { headers: config2.headers }
|
|
10920
11268
|
});
|
|
10921
11269
|
await client.connect(transport);
|
|
10922
11270
|
return client;
|
|
@@ -10926,10 +11274,82 @@ async function resolveMcpProxies(root, options = {}) {
|
|
|
10926
11274
|
await Promise.all(groups.map((group) => resolveSingleProxy(group, options)));
|
|
10927
11275
|
}
|
|
10928
11276
|
|
|
11277
|
+
// ../toolcraft/src/redaction.ts
|
|
11278
|
+
var REDACTED_VALUE = "<redacted>";
|
|
11279
|
+
var SENSITIVE_NAME_PARTS = ["password", "token", "apikey", "secret"];
|
|
11280
|
+
var AUTHORIZATION_HEADER_NAMES = /* @__PURE__ */ new Set(["authorization", "proxyauthorization"]);
|
|
11281
|
+
var SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["cookie", "setcookie"]);
|
|
11282
|
+
function isPlainObject2(value) {
|
|
11283
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11284
|
+
}
|
|
11285
|
+
function normalizeName(name) {
|
|
11286
|
+
return name.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
11287
|
+
}
|
|
11288
|
+
function isSensitiveName(name) {
|
|
11289
|
+
const normalized = normalizeName(name);
|
|
11290
|
+
return SENSITIVE_NAME_PARTS.some((candidate) => normalized.includes(candidate));
|
|
11291
|
+
}
|
|
11292
|
+
function redactSecretLikeFieldsValue(value, name, seen) {
|
|
11293
|
+
if (name.length > 0 && isSensitiveName(name)) {
|
|
11294
|
+
return REDACTED_VALUE;
|
|
11295
|
+
}
|
|
11296
|
+
if (Array.isArray(value)) {
|
|
11297
|
+
if (seen.has(value)) {
|
|
11298
|
+
return "[Circular]";
|
|
11299
|
+
}
|
|
11300
|
+
seen.add(value);
|
|
11301
|
+
return value.map((entry) => redactSecretLikeFieldsValue(entry, name, seen));
|
|
11302
|
+
}
|
|
11303
|
+
if (isPlainObject2(value)) {
|
|
11304
|
+
if (seen.has(value)) {
|
|
11305
|
+
return "[Circular]";
|
|
11306
|
+
}
|
|
11307
|
+
seen.add(value);
|
|
11308
|
+
return Object.fromEntries(
|
|
11309
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11310
|
+
key2,
|
|
11311
|
+
redactSecretLikeFieldsValue(entry, key2, seen)
|
|
11312
|
+
])
|
|
11313
|
+
);
|
|
11314
|
+
}
|
|
11315
|
+
return value;
|
|
11316
|
+
}
|
|
11317
|
+
function redactSecretLikeFields(value, name = "") {
|
|
11318
|
+
return redactSecretLikeFieldsValue(value, name, /* @__PURE__ */ new WeakSet());
|
|
11319
|
+
}
|
|
11320
|
+
function parseJsonObjectOrArray(value) {
|
|
11321
|
+
const trimmed = value.trim();
|
|
11322
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
|
|
11323
|
+
return void 0;
|
|
11324
|
+
}
|
|
11325
|
+
try {
|
|
11326
|
+
const parsed = JSON.parse(trimmed);
|
|
11327
|
+
return isPlainObject2(parsed) || Array.isArray(parsed) ? parsed : void 0;
|
|
11328
|
+
} catch {
|
|
11329
|
+
return void 0;
|
|
11330
|
+
}
|
|
11331
|
+
}
|
|
11332
|
+
function redactHttpBody(body) {
|
|
11333
|
+
if (typeof body === "string") {
|
|
11334
|
+
const parsed = parseJsonObjectOrArray(body);
|
|
11335
|
+
return parsed === void 0 ? body : redactSecretLikeFields(parsed);
|
|
11336
|
+
}
|
|
11337
|
+
return redactSecretLikeFields(body);
|
|
11338
|
+
}
|
|
11339
|
+
function redactHttpHeaderValue(name, value) {
|
|
11340
|
+
const normalized = normalizeName(name);
|
|
11341
|
+
if (AUTHORIZATION_HEADER_NAMES.has(normalized)) {
|
|
11342
|
+
return "Bearer ****";
|
|
11343
|
+
}
|
|
11344
|
+
if (SECRET_HEADER_NAMES.has(normalized) || isSensitiveName(name)) {
|
|
11345
|
+
return REDACTED_VALUE;
|
|
11346
|
+
}
|
|
11347
|
+
return value;
|
|
11348
|
+
}
|
|
11349
|
+
|
|
10929
11350
|
// ../toolcraft/src/error-report.ts
|
|
10930
11351
|
var ERROR_REPORTS_ENV = "TOOLCRAFT_ERROR_REPORTS";
|
|
10931
|
-
|
|
10932
|
-
function isPlainObject2(value) {
|
|
11352
|
+
function isPlainObject3(value) {
|
|
10933
11353
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10934
11354
|
}
|
|
10935
11355
|
function unwrapOptional(schema) {
|
|
@@ -10939,7 +11359,7 @@ function unwrapOptional(schema) {
|
|
|
10939
11359
|
return schema;
|
|
10940
11360
|
}
|
|
10941
11361
|
function hasHttpContext(error3) {
|
|
10942
|
-
return error3 instanceof Error && error3.name === "HttpError" &&
|
|
11362
|
+
return error3 instanceof Error && error3.name === "HttpError" && isPlainObject3(error3.request) && isPlainObject3(error3.response);
|
|
10943
11363
|
}
|
|
10944
11364
|
function isSkippedError(error3) {
|
|
10945
11365
|
if (error3 instanceof ApprovalDeclinedError) {
|
|
@@ -10976,8 +11396,8 @@ async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
|
10976
11396
|
throw new Error("Error report directory resolves outside project root.");
|
|
10977
11397
|
}
|
|
10978
11398
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
10979
|
-
|
|
10980
|
-
|
|
11399
|
+
realpath2(projectRoot),
|
|
11400
|
+
realpath2(reportDir)
|
|
10981
11401
|
]);
|
|
10982
11402
|
if (!isWithinDirectory(canonicalProjectRoot, canonicalReportDir)) {
|
|
10983
11403
|
throw new Error("Error report directory resolves outside project root.");
|
|
@@ -11032,9 +11452,24 @@ function redactValue(value) {
|
|
|
11032
11452
|
}
|
|
11033
11453
|
return `<set, ${value.length} chars>`;
|
|
11034
11454
|
}
|
|
11035
|
-
function
|
|
11036
|
-
|
|
11037
|
-
|
|
11455
|
+
function collectStringLeaves(value, output) {
|
|
11456
|
+
if (typeof value === "string") {
|
|
11457
|
+
if (value.length > 0) {
|
|
11458
|
+
output.add(value);
|
|
11459
|
+
}
|
|
11460
|
+
return;
|
|
11461
|
+
}
|
|
11462
|
+
if (Array.isArray(value)) {
|
|
11463
|
+
for (const entry of value) {
|
|
11464
|
+
collectStringLeaves(entry, output);
|
|
11465
|
+
}
|
|
11466
|
+
return;
|
|
11467
|
+
}
|
|
11468
|
+
if (isPlainObject3(value)) {
|
|
11469
|
+
for (const entry of Object.values(value)) {
|
|
11470
|
+
collectStringLeaves(entry, output);
|
|
11471
|
+
}
|
|
11472
|
+
}
|
|
11038
11473
|
}
|
|
11039
11474
|
function schemaSecretValue(schema) {
|
|
11040
11475
|
const unwrapped = unwrapOptional(schema);
|
|
@@ -11055,7 +11490,7 @@ function redactParamsValue(value, schema, name) {
|
|
|
11055
11490
|
return "<redacted>";
|
|
11056
11491
|
}
|
|
11057
11492
|
const unwrapped = unwrapOptional(schema);
|
|
11058
|
-
if (unwrapped.kind === "object" &&
|
|
11493
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11059
11494
|
return Object.fromEntries(
|
|
11060
11495
|
Object.entries(value).map(([key2, childValue]) => {
|
|
11061
11496
|
const childSchema = unwrapped.shape[key2];
|
|
@@ -11077,6 +11512,52 @@ function redactParams(params17, command) {
|
|
|
11077
11512
|
}
|
|
11078
11513
|
return redactParamsValue(params17, command.params, "");
|
|
11079
11514
|
}
|
|
11515
|
+
function collectSensitiveParamValues(value, schema, name, output) {
|
|
11516
|
+
if (shouldRedactParam(name, schema)) {
|
|
11517
|
+
collectStringLeaves(value, output);
|
|
11518
|
+
return;
|
|
11519
|
+
}
|
|
11520
|
+
const unwrapped = unwrapOptional(schema);
|
|
11521
|
+
if (unwrapped.kind === "object" && isPlainObject3(value)) {
|
|
11522
|
+
for (const [key2, childValue] of Object.entries(value)) {
|
|
11523
|
+
const childSchema = unwrapped.shape[key2];
|
|
11524
|
+
if (childSchema !== void 0) {
|
|
11525
|
+
collectSensitiveParamValues(childValue, childSchema, key2, output);
|
|
11526
|
+
}
|
|
11527
|
+
}
|
|
11528
|
+
return;
|
|
11529
|
+
}
|
|
11530
|
+
if (unwrapped.kind === "array" && Array.isArray(value)) {
|
|
11531
|
+
for (const entry of value) {
|
|
11532
|
+
collectSensitiveParamValues(entry, unwrapped.item, name, output);
|
|
11533
|
+
}
|
|
11534
|
+
}
|
|
11535
|
+
}
|
|
11536
|
+
function createReportStringRedactor(context, env) {
|
|
11537
|
+
const values = /* @__PURE__ */ new Set();
|
|
11538
|
+
for (const value of Object.values(context.secrets ?? {})) {
|
|
11539
|
+
if (value !== void 0 && value.length > 0) {
|
|
11540
|
+
values.add(value);
|
|
11541
|
+
}
|
|
11542
|
+
}
|
|
11543
|
+
for (const [name, secret] of Object.entries(context.command?.secrets ?? {})) {
|
|
11544
|
+
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11545
|
+
if (value !== void 0 && value.length > 0) {
|
|
11546
|
+
values.add(value);
|
|
11547
|
+
}
|
|
11548
|
+
}
|
|
11549
|
+
if (context.command !== void 0) {
|
|
11550
|
+
collectSensitiveParamValues(context.params, context.command.params, "", values);
|
|
11551
|
+
}
|
|
11552
|
+
const orderedValues = [...values].sort((left, right) => right.length - left.length);
|
|
11553
|
+
return (value) => {
|
|
11554
|
+
let redacted = value;
|
|
11555
|
+
for (const secretValue of orderedValues) {
|
|
11556
|
+
redacted = redacted.split(secretValue).join("<redacted>");
|
|
11557
|
+
}
|
|
11558
|
+
return redacted;
|
|
11559
|
+
};
|
|
11560
|
+
}
|
|
11080
11561
|
function commandSecretEnvNames(secrets) {
|
|
11081
11562
|
if (secrets === void 0) {
|
|
11082
11563
|
return [];
|
|
@@ -11130,28 +11611,42 @@ function redactArgv(argv, options) {
|
|
|
11130
11611
|
function stableJson(value) {
|
|
11131
11612
|
return JSON.stringify(value, null, 2) ?? "undefined";
|
|
11132
11613
|
}
|
|
11133
|
-
function redactStructuredErrorField(name, value) {
|
|
11134
|
-
if (typeof value === "string"
|
|
11135
|
-
|
|
11614
|
+
function redactStructuredErrorField(name, value, redactString) {
|
|
11615
|
+
if (typeof value === "string") {
|
|
11616
|
+
const redactedHeaderValue = redactHttpHeaderValue(name, value);
|
|
11617
|
+
if (redactedHeaderValue !== value) {
|
|
11618
|
+
return redactedHeaderValue;
|
|
11619
|
+
}
|
|
11620
|
+
if (isSensitiveName(name)) {
|
|
11621
|
+
return "<redacted>";
|
|
11622
|
+
}
|
|
11623
|
+
return redactString(value);
|
|
11136
11624
|
}
|
|
11137
11625
|
if (Array.isArray(value)) {
|
|
11138
|
-
return value.map((entry) => redactStructuredErrorField(name, entry));
|
|
11626
|
+
return value.map((entry) => redactStructuredErrorField(name, entry, redactString));
|
|
11139
11627
|
}
|
|
11140
|
-
if (
|
|
11628
|
+
if (isPlainObject3(value)) {
|
|
11141
11629
|
return Object.fromEntries(
|
|
11142
|
-
Object.entries(value).map(([key2, entry]) => [
|
|
11630
|
+
Object.entries(value).map(([key2, entry]) => [
|
|
11631
|
+
key2,
|
|
11632
|
+
redactStructuredErrorField(key2, entry, redactString)
|
|
11633
|
+
])
|
|
11143
11634
|
);
|
|
11144
11635
|
}
|
|
11145
11636
|
return value;
|
|
11146
11637
|
}
|
|
11147
|
-
function ownStructuredFields(error3) {
|
|
11638
|
+
function ownStructuredFields(error3, redactString) {
|
|
11148
11639
|
const fields = {};
|
|
11149
11640
|
for (const key2 of Object.keys(error3)) {
|
|
11150
11641
|
if (key2 === "name" || key2 === "message" || key2 === "stack" || key2 === "cause") {
|
|
11151
11642
|
continue;
|
|
11152
11643
|
}
|
|
11153
11644
|
Object.defineProperty(fields, key2, {
|
|
11154
|
-
value: redactStructuredErrorField(
|
|
11645
|
+
value: redactStructuredErrorField(
|
|
11646
|
+
key2,
|
|
11647
|
+
error3[key2],
|
|
11648
|
+
redactString
|
|
11649
|
+
),
|
|
11155
11650
|
enumerable: true,
|
|
11156
11651
|
configurable: true,
|
|
11157
11652
|
writable: true
|
|
@@ -11159,43 +11654,44 @@ function ownStructuredFields(error3) {
|
|
|
11159
11654
|
}
|
|
11160
11655
|
return fields;
|
|
11161
11656
|
}
|
|
11162
|
-
function formatStackChain(error3) {
|
|
11657
|
+
function formatStackChain(error3, redactString) {
|
|
11163
11658
|
const lines = [];
|
|
11164
11659
|
let current = error3;
|
|
11165
11660
|
let index = 0;
|
|
11166
11661
|
while (current !== void 0) {
|
|
11167
11662
|
if (current instanceof Error) {
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
);
|
|
11663
|
+
const stack = current.stack ?? String(current);
|
|
11664
|
+
lines.push(redactString(index === 0 ? stack : `Caused by: ${stack}`));
|
|
11171
11665
|
current = current.cause;
|
|
11172
11666
|
} else {
|
|
11173
|
-
|
|
11667
|
+
const message2 = String(current);
|
|
11668
|
+
lines.push(redactString(index === 0 ? message2 : `Caused by: ${message2}`));
|
|
11174
11669
|
current = void 0;
|
|
11175
11670
|
}
|
|
11176
11671
|
index += 1;
|
|
11177
11672
|
}
|
|
11178
11673
|
return lines.join("\n");
|
|
11179
11674
|
}
|
|
11180
|
-
function formatHeaderValue(name, value) {
|
|
11181
|
-
return name
|
|
11675
|
+
function formatHeaderValue(name, value, redactString) {
|
|
11676
|
+
return redactString(redactHttpHeaderValue(name, value));
|
|
11182
11677
|
}
|
|
11183
|
-
function formatHeaders(headers) {
|
|
11184
|
-
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value)}`).join("\n");
|
|
11678
|
+
function formatHeaders(headers, redactString) {
|
|
11679
|
+
return Object.entries(headers).map(([name, value]) => `${name}: ${formatHeaderValue(name, value, redactString)}`).join("\n");
|
|
11185
11680
|
}
|
|
11186
|
-
function formatBody(body) {
|
|
11187
|
-
|
|
11188
|
-
|
|
11681
|
+
function formatBody(body, redactString) {
|
|
11682
|
+
const redactedBody = redactHttpBody(body);
|
|
11683
|
+
if (typeof redactedBody === "string") {
|
|
11684
|
+
return redactString(redactedBody);
|
|
11189
11685
|
}
|
|
11190
|
-
return stableJson(
|
|
11686
|
+
return redactString(stableJson(redactedBody));
|
|
11191
11687
|
}
|
|
11192
|
-
function formatHttpTranscript(error3) {
|
|
11688
|
+
function formatHttpTranscript(error3, redactString) {
|
|
11193
11689
|
const requestLines = [
|
|
11194
11690
|
`${error3.request.method} ${error3.request.url}`,
|
|
11195
|
-
formatHeaders(error3.request.headers)
|
|
11691
|
+
formatHeaders(error3.request.headers, redactString)
|
|
11196
11692
|
].filter((line) => line.length > 0);
|
|
11197
11693
|
if (error3.request.body !== void 0) {
|
|
11198
|
-
requestLines.push("", formatBody(error3.request.body));
|
|
11694
|
+
requestLines.push("", formatBody(error3.request.body, redactString));
|
|
11199
11695
|
}
|
|
11200
11696
|
return [
|
|
11201
11697
|
"Request:",
|
|
@@ -11203,9 +11699,9 @@ function formatHttpTranscript(error3) {
|
|
|
11203
11699
|
"",
|
|
11204
11700
|
"Response:",
|
|
11205
11701
|
`${error3.response.status} ${error3.response.statusText}`,
|
|
11206
|
-
formatHeaders(error3.response.headers),
|
|
11702
|
+
formatHeaders(error3.response.headers, redactString),
|
|
11207
11703
|
"",
|
|
11208
|
-
formatBody(error3.response.body)
|
|
11704
|
+
formatBody(error3.response.body, redactString)
|
|
11209
11705
|
].join("\n");
|
|
11210
11706
|
}
|
|
11211
11707
|
function resolveToolcraftVersion(version) {
|
|
@@ -11214,9 +11710,10 @@ function resolveToolcraftVersion(version) {
|
|
|
11214
11710
|
function buildReport(context) {
|
|
11215
11711
|
const env = context.env ?? process.env;
|
|
11216
11712
|
const error3 = context.error;
|
|
11713
|
+
const redactString = createReportStringRedactor(context, env);
|
|
11217
11714
|
const errorName = error3 instanceof Error ? error3.name : typeof error3;
|
|
11218
|
-
const errorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
11219
|
-
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3) : {};
|
|
11715
|
+
const errorMessage = redactString(error3 instanceof Error ? error3.message : String(error3));
|
|
11716
|
+
const structuredFields = error3 instanceof Error ? ownStructuredFields(error3, redactString) : {};
|
|
11220
11717
|
const secretLines = Object.entries(context.command?.secrets ?? {}).map(([name, secret]) => {
|
|
11221
11718
|
const value = context.secrets?.[name] ?? env[secret.env];
|
|
11222
11719
|
return `${secret.env}=${redactValue(value)}`;
|
|
@@ -11230,7 +11727,9 @@ function buildReport(context) {
|
|
|
11230
11727
|
`platform: ${process.platform} ${process.arch}`,
|
|
11231
11728
|
"",
|
|
11232
11729
|
"Argv",
|
|
11233
|
-
|
|
11730
|
+
redactString(
|
|
11731
|
+
stableJson(redactArgv(context.argv, { command: context.command, secrets: context.secrets }))
|
|
11732
|
+
),
|
|
11234
11733
|
"",
|
|
11235
11734
|
"Resolved Secrets",
|
|
11236
11735
|
...secretLines.length === 0 ? ["<none>"] : secretLines,
|
|
@@ -11239,19 +11738,19 @@ function buildReport(context) {
|
|
|
11239
11738
|
context.commandPath === void 0 || context.commandPath.length === 0 ? "root" : context.commandPath,
|
|
11240
11739
|
"",
|
|
11241
11740
|
"Parsed Params",
|
|
11242
|
-
stableJson(redactParams(context.params, context.command)),
|
|
11741
|
+
redactString(stableJson(redactParams(context.params, context.command))),
|
|
11243
11742
|
"",
|
|
11244
11743
|
"Error",
|
|
11245
11744
|
`name: ${errorName}`,
|
|
11246
11745
|
`message: ${errorMessage}`,
|
|
11247
11746
|
"structured fields:",
|
|
11248
|
-
stableJson(structuredFields),
|
|
11747
|
+
redactString(stableJson(structuredFields)),
|
|
11249
11748
|
"",
|
|
11250
11749
|
"Stack",
|
|
11251
|
-
formatStackChain(error3)
|
|
11750
|
+
formatStackChain(error3, redactString)
|
|
11252
11751
|
];
|
|
11253
11752
|
if (hasHttpContext(error3)) {
|
|
11254
|
-
lines.push("", "HTTP Transcript", formatHttpTranscript(error3));
|
|
11753
|
+
lines.push("", "HTTP Transcript", formatHttpTranscript(error3, redactString));
|
|
11255
11754
|
}
|
|
11256
11755
|
return `${lines.join("\n")}
|
|
11257
11756
|
`;
|
|
@@ -11263,7 +11762,7 @@ async function writeErrorReport(context) {
|
|
|
11263
11762
|
}
|
|
11264
11763
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11265
11764
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11266
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11765
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID5()}.log`;
|
|
11267
11766
|
const absolutePath = path13.join(reportDir, fileName);
|
|
11268
11767
|
await mkdir2(reportDir, { recursive: true });
|
|
11269
11768
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
@@ -11711,6 +12210,7 @@ ${rendered.join("\n")}`);
|
|
|
11711
12210
|
}
|
|
11712
12211
|
|
|
11713
12212
|
// ../toolcraft/src/cli.ts
|
|
12213
|
+
configureTheme({ brand: "blue", label: "Toolcraft" });
|
|
11714
12214
|
var RESERVED_SERVICE_NAMES = /* @__PURE__ */ new Set([
|
|
11715
12215
|
"params",
|
|
11716
12216
|
"secrets",
|
|
@@ -12741,10 +13241,10 @@ function renderHelpSections(sections) {
|
|
|
12741
13241
|
return sections.filter((section) => section.length > 0).join("\n\n");
|
|
12742
13242
|
}
|
|
12743
13243
|
function formatHelpCommandList(rows) {
|
|
12744
|
-
return process.stdout.isTTY
|
|
13244
|
+
return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatCommandList(rows) : formatCommandList(rows);
|
|
12745
13245
|
}
|
|
12746
13246
|
function formatHelpOptionList(rows) {
|
|
12747
|
-
return process.stdout.isTTY
|
|
13247
|
+
return process.stdout.isTTY !== true ? help_formatter_plain_exports.formatOptionList(rows) : formatOptionList(rows);
|
|
12748
13248
|
}
|
|
12749
13249
|
function buildUsageLine(breadcrumb, rootUsageName, suffix) {
|
|
12750
13250
|
const visibleBreadcrumb = breadcrumb.filter((segment) => segment.length > 0);
|
|
@@ -13032,11 +13532,18 @@ function formatResolvedValue(value) {
|
|
|
13032
13532
|
function fieldPromptLabel(field) {
|
|
13033
13533
|
return field.positionalIndex === void 0 ? field.optionFlag : `<${field.displayPath}>`;
|
|
13034
13534
|
}
|
|
13535
|
+
function enumOptionLabel(schema, value) {
|
|
13536
|
+
const key2 = String(value);
|
|
13537
|
+
if (schema.labels === void 0 || !Object.prototype.hasOwnProperty.call(schema.labels, key2)) {
|
|
13538
|
+
return key2;
|
|
13539
|
+
}
|
|
13540
|
+
return schema.labels[key2] ?? key2;
|
|
13541
|
+
}
|
|
13035
13542
|
async function promptForField(field) {
|
|
13036
13543
|
const schema = field.schema;
|
|
13037
13544
|
if (schema.kind === "enum") {
|
|
13038
13545
|
const options = schema.loadOptions ? await schema.loadOptions() : schema.values.map((value) => ({
|
|
13039
|
-
label: schema
|
|
13546
|
+
label: enumOptionLabel(schema, value),
|
|
13040
13547
|
value
|
|
13041
13548
|
}));
|
|
13042
13549
|
const selected = await select2({
|
|
@@ -13121,8 +13628,8 @@ async function withOutputFormat2(output, fn) {
|
|
|
13121
13628
|
function createFs2() {
|
|
13122
13629
|
return {
|
|
13123
13630
|
readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
|
|
13124
|
-
writeFile: async (path24, contents) => {
|
|
13125
|
-
await writeFile5(path24, contents);
|
|
13631
|
+
writeFile: async (path24, contents, options) => {
|
|
13632
|
+
await writeFile5(path24, contents, options);
|
|
13126
13633
|
},
|
|
13127
13634
|
exists: async (path24) => {
|
|
13128
13635
|
try {
|
|
@@ -13134,7 +13641,7 @@ function createFs2() {
|
|
|
13134
13641
|
},
|
|
13135
13642
|
lstat: async (path24) => lstat3(path24),
|
|
13136
13643
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
13137
|
-
unlink: async (path24) =>
|
|
13644
|
+
unlink: async (path24) => unlink3(path24)
|
|
13138
13645
|
};
|
|
13139
13646
|
}
|
|
13140
13647
|
function createEnv2(values = process.env) {
|
|
@@ -13144,7 +13651,7 @@ function createEnv2(values = process.env) {
|
|
|
13144
13651
|
}
|
|
13145
13652
|
};
|
|
13146
13653
|
}
|
|
13147
|
-
function
|
|
13654
|
+
function isPlainObject4(value) {
|
|
13148
13655
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
13149
13656
|
}
|
|
13150
13657
|
function hasFieldValue(value) {
|
|
@@ -13253,7 +13760,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13253
13760
|
{ cause: error3 }
|
|
13254
13761
|
);
|
|
13255
13762
|
}
|
|
13256
|
-
if (!
|
|
13763
|
+
if (!isPlainObject4(parsedPreset)) {
|
|
13257
13764
|
throw new UserError(`Preset file "${presetPath}" must contain a JSON object.`);
|
|
13258
13765
|
}
|
|
13259
13766
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
@@ -13272,7 +13779,7 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13272
13779
|
`Preset file "${presetPath}" contains unknown parameter "${displayPath}".`
|
|
13273
13780
|
);
|
|
13274
13781
|
}
|
|
13275
|
-
if (!
|
|
13782
|
+
if (!isPlainObject4(value)) {
|
|
13276
13783
|
throw new UserError(
|
|
13277
13784
|
`Preset file "${presetPath}" has an invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
13278
13785
|
);
|
|
@@ -13315,8 +13822,8 @@ function matchesFixtureValue(expected, actual) {
|
|
|
13315
13822
|
}
|
|
13316
13823
|
return expected.every((item, index) => matchesFixtureValue(item, actual[index]));
|
|
13317
13824
|
}
|
|
13318
|
-
if (
|
|
13319
|
-
if (!
|
|
13825
|
+
if (isPlainObject4(expected)) {
|
|
13826
|
+
if (!isPlainObject4(actual)) {
|
|
13320
13827
|
return false;
|
|
13321
13828
|
}
|
|
13322
13829
|
return Object.entries(expected).every(
|
|
@@ -13379,9 +13886,9 @@ function createFixtureFetch(entries) {
|
|
|
13379
13886
|
};
|
|
13380
13887
|
}
|
|
13381
13888
|
function createFixtureFs(definition) {
|
|
13382
|
-
const fsDefinition =
|
|
13383
|
-
const readFileEntries =
|
|
13384
|
-
const existsEntries =
|
|
13889
|
+
const fsDefinition = isPlainObject4(definition) ? definition : {};
|
|
13890
|
+
const readFileEntries = isPlainObject4(fsDefinition.readFile) ? fsDefinition.readFile : {};
|
|
13891
|
+
const existsEntries = isPlainObject4(fsDefinition.exists) ? fsDefinition.exists : {};
|
|
13385
13892
|
return {
|
|
13386
13893
|
readFile: async (filePath) => {
|
|
13387
13894
|
if (Object.prototype.hasOwnProperty.call(readFileEntries, filePath)) {
|
|
@@ -13404,10 +13911,10 @@ function createFixtureFs(definition) {
|
|
|
13404
13911
|
function resolveFixtureMethodResult(methodName, definition, args) {
|
|
13405
13912
|
if (Array.isArray(definition)) {
|
|
13406
13913
|
for (const entry of definition) {
|
|
13407
|
-
if (!
|
|
13914
|
+
if (!isPlainObject4(entry)) {
|
|
13408
13915
|
continue;
|
|
13409
13916
|
}
|
|
13410
|
-
const explicitMatcher =
|
|
13917
|
+
const explicitMatcher = isPlainObject4(entry.request) ? entry.request : void 0;
|
|
13411
13918
|
const matcher = explicitMatcher ?? Object.fromEntries(
|
|
13412
13919
|
Object.entries(entry).filter(
|
|
13413
13920
|
([key2]) => key2 !== "result" && key2 !== "response" && key2 !== "error"
|
|
@@ -13419,7 +13926,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13419
13926
|
matched = matchesFixtureValue(matcher.args, args);
|
|
13420
13927
|
} else if (Object.keys(matcher).length === 0) {
|
|
13421
13928
|
matched = true;
|
|
13422
|
-
} else if (
|
|
13929
|
+
} else if (isPlainObject4(firstArg)) {
|
|
13423
13930
|
matched = matchesFixtureValue(matcher, firstArg);
|
|
13424
13931
|
} else if (args.length === 1 && Object.keys(matcher).length === 1) {
|
|
13425
13932
|
const [[, expectedValue]] = Object.entries(matcher);
|
|
@@ -13440,7 +13947,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13440
13947
|
return Promise.resolve(null);
|
|
13441
13948
|
}
|
|
13442
13949
|
}
|
|
13443
|
-
if (
|
|
13950
|
+
if (isPlainObject4(definition)) {
|
|
13444
13951
|
const firstArg = args[0];
|
|
13445
13952
|
if (typeof firstArg === "string" && Object.prototype.hasOwnProperty.call(definition, firstArg)) {
|
|
13446
13953
|
return Promise.resolve(definition[firstArg]);
|
|
@@ -13452,7 +13959,7 @@ function resolveFixtureMethodResult(methodName, definition, args) {
|
|
|
13452
13959
|
return Promise.resolve(null);
|
|
13453
13960
|
}
|
|
13454
13961
|
function createFixtureService(definition) {
|
|
13455
|
-
const methods =
|
|
13962
|
+
const methods = isPlainObject4(definition) ? definition : {};
|
|
13456
13963
|
return new Proxy(
|
|
13457
13964
|
{},
|
|
13458
13965
|
{
|
|
@@ -13550,7 +14057,7 @@ async function resolveFixtureRuntime(command, services, requirementOptions) {
|
|
|
13550
14057
|
};
|
|
13551
14058
|
}
|
|
13552
14059
|
const scenario = await loadFixtureScenario(command, selector);
|
|
13553
|
-
const scenarioServices =
|
|
14060
|
+
const scenarioServices = isPlainObject4(scenario.services) ? scenario.services : {};
|
|
13554
14061
|
const customServiceNames = /* @__PURE__ */ new Set([
|
|
13555
14062
|
...Object.keys(services),
|
|
13556
14063
|
...Object.keys(scenarioServices).filter((name) => !RESERVED_SERVICE_NAMES.has(name))
|
|
@@ -13832,7 +14339,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13832
14339
|
if (itemSchema.kind !== "object") {
|
|
13833
14340
|
return value;
|
|
13834
14341
|
}
|
|
13835
|
-
if (!
|
|
14342
|
+
if (!isPlainObject4(value)) {
|
|
13836
14343
|
errors2.push({
|
|
13837
14344
|
path: displayPath,
|
|
13838
14345
|
message: `Invalid value for "${displayPath}". Expected indexed object entries, got ${describeReceived(value)}.`
|
|
@@ -13867,7 +14374,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13867
14374
|
);
|
|
13868
14375
|
}
|
|
13869
14376
|
case "object": {
|
|
13870
|
-
if (!
|
|
14377
|
+
if (!isPlainObject4(value)) {
|
|
13871
14378
|
errors2.push({
|
|
13872
14379
|
path: displayPath,
|
|
13873
14380
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -13898,7 +14405,7 @@ function finalizeDynamicValue(schema, value, displayPath, errors2) {
|
|
|
13898
14405
|
return result;
|
|
13899
14406
|
}
|
|
13900
14407
|
case "record": {
|
|
13901
|
-
if (!
|
|
14408
|
+
if (!isPlainObject4(value)) {
|
|
13902
14409
|
errors2.push({
|
|
13903
14410
|
path: displayPath,
|
|
13904
14411
|
message: `Invalid value for "${displayPath}". Expected an object, got ${describeReceived(value)}.`
|
|
@@ -14324,10 +14831,10 @@ async function executeCommand(state, services, requirementOptions, runtimeOption
|
|
|
14324
14831
|
}
|
|
14325
14832
|
}
|
|
14326
14833
|
function isStringRecord(value) {
|
|
14327
|
-
return
|
|
14834
|
+
return isPlainObject4(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
14328
14835
|
}
|
|
14329
14836
|
function isHttpErrorLike(error3) {
|
|
14330
|
-
if (!
|
|
14837
|
+
if (!isPlainObject4(error3)) {
|
|
14331
14838
|
return false;
|
|
14332
14839
|
}
|
|
14333
14840
|
if (error3.name !== "HttpError" || typeof error3.message !== "string") {
|
|
@@ -14335,7 +14842,7 @@ function isHttpErrorLike(error3) {
|
|
|
14335
14842
|
}
|
|
14336
14843
|
const request = error3.request;
|
|
14337
14844
|
const response = error3.response;
|
|
14338
|
-
return
|
|
14845
|
+
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;
|
|
14339
14846
|
}
|
|
14340
14847
|
function hasTypedOptionalField(value, field, type2) {
|
|
14341
14848
|
return !(field in value) || typeof value[field] === type2;
|
|
@@ -14344,7 +14851,7 @@ function isNonEmptyString(value) {
|
|
|
14344
14851
|
return typeof value === "string" && value.trim().length > 0;
|
|
14345
14852
|
}
|
|
14346
14853
|
function isProblemDetailsLike(body) {
|
|
14347
|
-
if (!
|
|
14854
|
+
if (!isPlainObject4(body)) {
|
|
14348
14855
|
return false;
|
|
14349
14856
|
}
|
|
14350
14857
|
if (!hasTypedOptionalField(body, "type", "string")) {
|
|
@@ -14365,11 +14872,11 @@ function isProblemDetailsLike(body) {
|
|
|
14365
14872
|
return isNonEmptyString(body.title) || isNonEmptyString(body.detail);
|
|
14366
14873
|
}
|
|
14367
14874
|
function isGraphQLErrorEnvelopeLike(body) {
|
|
14368
|
-
if (!
|
|
14875
|
+
if (!isPlainObject4(body) || !Array.isArray(body.errors) || body.errors.length === 0) {
|
|
14369
14876
|
return false;
|
|
14370
14877
|
}
|
|
14371
14878
|
return body.errors.every((error3) => {
|
|
14372
|
-
if (!
|
|
14879
|
+
if (!isPlainObject4(error3) || typeof error3.message !== "string") {
|
|
14373
14880
|
return false;
|
|
14374
14881
|
}
|
|
14375
14882
|
if ("path" in error3) {
|
|
@@ -14379,7 +14886,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14379
14886
|
}
|
|
14380
14887
|
}
|
|
14381
14888
|
if ("extensions" in error3) {
|
|
14382
|
-
if (!
|
|
14889
|
+
if (!isPlainObject4(error3.extensions)) {
|
|
14383
14890
|
return false;
|
|
14384
14891
|
}
|
|
14385
14892
|
if ("code" in error3.extensions && typeof error3.extensions.code !== "string") {
|
|
@@ -14390,7 +14897,7 @@ function isGraphQLErrorEnvelopeLike(body) {
|
|
|
14390
14897
|
});
|
|
14391
14898
|
}
|
|
14392
14899
|
function styleHttpErrorLine(value, style) {
|
|
14393
|
-
return process.stdout.isTTY
|
|
14900
|
+
return process.stdout.isTTY !== true ? value : style(value);
|
|
14394
14901
|
}
|
|
14395
14902
|
function formatHttpErrorStatus(value) {
|
|
14396
14903
|
return styleHttpErrorLine(value, text.error);
|
|
@@ -14427,23 +14934,24 @@ function formatGraphQLErrorEnvelopeBody(body) {
|
|
|
14427
14934
|
}).join("\n\n");
|
|
14428
14935
|
}
|
|
14429
14936
|
function formatHttpErrorBody(body) {
|
|
14430
|
-
|
|
14431
|
-
|
|
14937
|
+
const redactedBody = redactHttpBody(body);
|
|
14938
|
+
if (typeof redactedBody === "string") {
|
|
14939
|
+
return redactedBody;
|
|
14432
14940
|
}
|
|
14433
|
-
if (isProblemDetailsLike(
|
|
14434
|
-
return formatProblemDetailsBody(
|
|
14941
|
+
if (isProblemDetailsLike(redactedBody)) {
|
|
14942
|
+
return formatProblemDetailsBody(redactedBody);
|
|
14435
14943
|
}
|
|
14436
|
-
if (isGraphQLErrorEnvelopeLike(
|
|
14437
|
-
return formatGraphQLErrorEnvelopeBody(
|
|
14944
|
+
if (isGraphQLErrorEnvelopeLike(redactedBody)) {
|
|
14945
|
+
return formatGraphQLErrorEnvelopeBody(redactedBody);
|
|
14438
14946
|
}
|
|
14439
|
-
const serialized = JSON.stringify(
|
|
14440
|
-
return serialized === void 0 ? String(
|
|
14947
|
+
const serialized = JSON.stringify(redactedBody, null, 2);
|
|
14948
|
+
return serialized === void 0 ? String(redactedBody) : serialized;
|
|
14441
14949
|
}
|
|
14442
14950
|
function indentHttpErrorBlock(value) {
|
|
14443
14951
|
return value.split("\n").map((line) => ` ${line}`).join("\n");
|
|
14444
14952
|
}
|
|
14445
14953
|
function formatHttpHeaderValue(name, value) {
|
|
14446
|
-
return name
|
|
14954
|
+
return redactHttpHeaderValue(name, value);
|
|
14447
14955
|
}
|
|
14448
14956
|
function formatHttpErrorHeaders(headers) {
|
|
14449
14957
|
return Object.entries(headers).map(
|
|
@@ -14461,7 +14969,11 @@ function renderHttpError(error3, options) {
|
|
|
14461
14969
|
if (detailed) {
|
|
14462
14970
|
lines.push("", "Request headers:", ...formatHttpErrorHeaders(error3.request.headers), "");
|
|
14463
14971
|
if (error3.request.body !== void 0) {
|
|
14464
|
-
lines.push(
|
|
14972
|
+
lines.push(
|
|
14973
|
+
"Request body:",
|
|
14974
|
+
indentHttpErrorBlock(formatHttpErrorBody(error3.request.body)),
|
|
14975
|
+
""
|
|
14976
|
+
);
|
|
14465
14977
|
}
|
|
14466
14978
|
}
|
|
14467
14979
|
lines.push(
|
|
@@ -14867,7 +15379,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14867
15379
|
}
|
|
14868
15380
|
|
|
14869
15381
|
// src/terminal-pilot.ts
|
|
14870
|
-
import { randomUUID as
|
|
15382
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
14871
15383
|
|
|
14872
15384
|
// src/terminal-session.ts
|
|
14873
15385
|
import { EventEmitter } from "node:events";
|
|
@@ -14949,6 +15461,11 @@ function consumeTerminatedString(input, index, allowBellTerminator) {
|
|
|
14949
15461
|
return input.length;
|
|
14950
15462
|
}
|
|
14951
15463
|
|
|
15464
|
+
// src/errors.ts
|
|
15465
|
+
function hasOwnErrorCode(error3, code) {
|
|
15466
|
+
return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === code;
|
|
15467
|
+
}
|
|
15468
|
+
|
|
14952
15469
|
// src/terminal-buffer.ts
|
|
14953
15470
|
var RESET_SGR = "\x1B[0m";
|
|
14954
15471
|
var DEC_SPECIAL_GRAPHICS = {
|
|
@@ -16048,10 +16565,7 @@ function ensureSpawnHelperExecutable() {
|
|
|
16048
16565
|
}
|
|
16049
16566
|
}
|
|
16050
16567
|
function isMissingFileError(error3) {
|
|
16051
|
-
|
|
16052
|
-
return false;
|
|
16053
|
-
}
|
|
16054
|
-
return "code" in error3 && error3.code === "ENOENT";
|
|
16568
|
+
return hasOwnErrorCode(error3, "ENOENT");
|
|
16055
16569
|
}
|
|
16056
16570
|
function matchPattern(buffer, pattern) {
|
|
16057
16571
|
const clean = normalizeHistoryBuffer(stripAnsi4(buffer));
|
|
@@ -16142,7 +16656,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
16142
16656
|
}
|
|
16143
16657
|
async newSession(opts) {
|
|
16144
16658
|
const session = new TerminalSession({
|
|
16145
|
-
id:
|
|
16659
|
+
id: randomUUID6(),
|
|
16146
16660
|
command: opts.command,
|
|
16147
16661
|
args: opts.args,
|
|
16148
16662
|
cwd: opts.cwd,
|
|
@@ -16421,6 +16935,11 @@ var claudeCodeAgent = {
|
|
|
16421
16935
|
aliases: ["claude"],
|
|
16422
16936
|
binaryName: "claude",
|
|
16423
16937
|
apiShapes: ["anthropic-messages"],
|
|
16938
|
+
otelCapture: {
|
|
16939
|
+
env: {
|
|
16940
|
+
CLAUDE_CODE_ENABLE_TELEMETRY: "1"
|
|
16941
|
+
}
|
|
16942
|
+
},
|
|
16424
16943
|
configPath: "~/.claude/settings.json",
|
|
16425
16944
|
branding: {
|
|
16426
16945
|
colors: {
|
|
@@ -16453,6 +16972,16 @@ var codexAgent = {
|
|
|
16453
16972
|
summary: "Configure Codex to use Poe as the model provider.",
|
|
16454
16973
|
binaryName: "codex",
|
|
16455
16974
|
apiShapes: ["openai-responses"],
|
|
16975
|
+
otelCapture: {
|
|
16976
|
+
args: (endpoint, content) => [
|
|
16977
|
+
"-c",
|
|
16978
|
+
`otel.trace_exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/traces`)},protocol="json"}}`,
|
|
16979
|
+
"-c",
|
|
16980
|
+
`otel.exporter={"otlp-http"={endpoint=${JSON.stringify(`${endpoint}/v1/logs`)},protocol="json"}}`,
|
|
16981
|
+
"-c",
|
|
16982
|
+
`otel.log_user_prompt=${content}`
|
|
16983
|
+
]
|
|
16984
|
+
},
|
|
16456
16985
|
configPath: "~/.codex/config.toml",
|
|
16457
16986
|
branding: {
|
|
16458
16987
|
colors: {
|
|
@@ -16488,6 +17017,11 @@ var openCodeAgent = {
|
|
|
16488
17017
|
summary: "Configure OpenCode CLI to use the Poe API.",
|
|
16489
17018
|
binaryName: "opencode",
|
|
16490
17019
|
apiShapes: ["openai-chat-completions"],
|
|
17020
|
+
otelCapture: {
|
|
17021
|
+
env: {
|
|
17022
|
+
OPENCODE_CONFIG_CONTENT: '{"experimental":{"openTelemetry":true}}'
|
|
17023
|
+
}
|
|
17024
|
+
},
|
|
16491
17025
|
configPath: "~/.config/opencode/config.json",
|
|
16492
17026
|
branding: {
|
|
16493
17027
|
colors: {
|
|
@@ -16523,6 +17057,7 @@ var gooseAgent = {
|
|
|
16523
17057
|
summary: "Block's open-source AI agent with ACP support.",
|
|
16524
17058
|
binaryName: "goose",
|
|
16525
17059
|
apiShapes: ["openai-chat-completions"],
|
|
17060
|
+
otelCapture: {},
|
|
16526
17061
|
configPath: "~/.config/goose/config.yaml",
|
|
16527
17062
|
branding: {
|
|
16528
17063
|
colors: {
|
|
@@ -16556,6 +17091,12 @@ function freezeAgent(agent) {
|
|
|
16556
17091
|
if (agent.apiShapes !== void 0) {
|
|
16557
17092
|
Object.freeze(agent.apiShapes);
|
|
16558
17093
|
}
|
|
17094
|
+
if (agent.otelCapture?.env !== void 0) {
|
|
17095
|
+
Object.freeze(agent.otelCapture.env);
|
|
17096
|
+
}
|
|
17097
|
+
if (agent.otelCapture !== void 0) {
|
|
17098
|
+
Object.freeze(agent.otelCapture);
|
|
17099
|
+
}
|
|
16559
17100
|
Object.freeze(agent.branding.colors);
|
|
16560
17101
|
Object.freeze(agent.branding);
|
|
16561
17102
|
return Object.freeze(agent);
|
|
@@ -16616,11 +17157,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
16616
17157
|
if (!resolvedId) {
|
|
16617
17158
|
return { status: "unknown", input };
|
|
16618
17159
|
}
|
|
16619
|
-
const
|
|
16620
|
-
if (!
|
|
17160
|
+
const config2 = registry[resolvedId];
|
|
17161
|
+
if (!config2) {
|
|
16621
17162
|
return { status: "unsupported", input, id: resolvedId };
|
|
16622
17163
|
}
|
|
16623
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
17164
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
16624
17165
|
}
|
|
16625
17166
|
function getAgentConfig(agentId) {
|
|
16626
17167
|
const support = resolveAgentSupport(agentId);
|
|
@@ -16719,6 +17260,7 @@ var templateMutation = {
|
|
|
16719
17260
|
};
|
|
16720
17261
|
|
|
16721
17262
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
17263
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
16722
17264
|
import path17 from "node:path";
|
|
16723
17265
|
|
|
16724
17266
|
// ../config-mutations/src/formats/json.ts
|
|
@@ -16794,7 +17336,7 @@ function merge(base, patch) {
|
|
|
16794
17336
|
if (value === void 0) {
|
|
16795
17337
|
continue;
|
|
16796
17338
|
}
|
|
16797
|
-
const existing = result[key2];
|
|
17339
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
16798
17340
|
if (isConfigObject(existing) && isConfigObject(value)) {
|
|
16799
17341
|
setConfigEntry(result, key2, merge(existing, value));
|
|
16800
17342
|
continue;
|
|
@@ -16922,7 +17464,7 @@ function merge2(base, patch) {
|
|
|
16922
17464
|
if (value === void 0) {
|
|
16923
17465
|
continue;
|
|
16924
17466
|
}
|
|
16925
|
-
const existing = result[key2];
|
|
17467
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
16926
17468
|
if (isConfigObject2(existing) && isConfigObject2(value)) {
|
|
16927
17469
|
setConfigEntry(result, key2, merge2(existing, value));
|
|
16928
17470
|
continue;
|
|
@@ -17002,7 +17544,7 @@ function merge3(base, patch) {
|
|
|
17002
17544
|
if (value === void 0) {
|
|
17003
17545
|
continue;
|
|
17004
17546
|
}
|
|
17005
|
-
const existing = result[key2];
|
|
17547
|
+
const existing = hasConfigEntry(result, key2) ? result[key2] : void 0;
|
|
17006
17548
|
if (isConfigObject3(existing) && isConfigObject3(value)) {
|
|
17007
17549
|
setConfigEntry(result, key2, merge3(existing, value));
|
|
17008
17550
|
continue;
|
|
@@ -17139,7 +17681,7 @@ function resolvePath(rawPath, homeDir, pathMapper) {
|
|
|
17139
17681
|
|
|
17140
17682
|
// ../config-mutations/src/fs-utils.ts
|
|
17141
17683
|
function isNotFound(error3) {
|
|
17142
|
-
return typeof error3 === "object" && error3 !== null && "code"
|
|
17684
|
+
return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT";
|
|
17143
17685
|
}
|
|
17144
17686
|
async function readFileIfExists(fs4, target) {
|
|
17145
17687
|
try {
|
|
@@ -17188,6 +17730,7 @@ async function backupInvalidDocument(context, targetPath, content) {
|
|
|
17188
17730
|
return;
|
|
17189
17731
|
} catch (error3) {
|
|
17190
17732
|
if (!isAlreadyExists(error3)) {
|
|
17733
|
+
await context.fs.unlink(backupPath).catch(() => void 0);
|
|
17191
17734
|
throw error3;
|
|
17192
17735
|
}
|
|
17193
17736
|
attempt += 1;
|
|
@@ -17195,7 +17738,7 @@ async function backupInvalidDocument(context, targetPath, content) {
|
|
|
17195
17738
|
}
|
|
17196
17739
|
}
|
|
17197
17740
|
function isAlreadyExists(error3) {
|
|
17198
|
-
return
|
|
17741
|
+
return typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
|
|
17199
17742
|
}
|
|
17200
17743
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
17201
17744
|
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
@@ -17219,28 +17762,34 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
17219
17762
|
}
|
|
17220
17763
|
async function writeAtomically2(context, targetPath, content) {
|
|
17221
17764
|
await assertRegularWriteTarget(context, targetPath);
|
|
17222
|
-
let attempt = 0;
|
|
17223
|
-
|
|
17224
|
-
|
|
17765
|
+
for (let attempt = 0; attempt < 10; attempt += 1) {
|
|
17766
|
+
const tempPath = `${targetPath}.mutation-tmp-${process.pid}-${randomUUID7()}`;
|
|
17767
|
+
let tempCreated = false;
|
|
17225
17768
|
try {
|
|
17769
|
+
await assertRegularWriteTarget(context, tempPath);
|
|
17226
17770
|
await context.fs.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
17771
|
+
tempCreated = true;
|
|
17227
17772
|
await context.fs.rename(tempPath, targetPath);
|
|
17773
|
+
tempCreated = false;
|
|
17228
17774
|
return;
|
|
17229
17775
|
} catch (error3) {
|
|
17230
|
-
|
|
17231
|
-
|
|
17232
|
-
|
|
17233
|
-
|
|
17234
|
-
|
|
17235
|
-
|
|
17236
|
-
|
|
17237
|
-
|
|
17238
|
-
void cleanupError;
|
|
17776
|
+
const alreadyExists = isAlreadyExists(error3);
|
|
17777
|
+
if (tempCreated || !alreadyExists) {
|
|
17778
|
+
try {
|
|
17779
|
+
await context.fs.unlink(tempPath);
|
|
17780
|
+
} catch (cleanupError) {
|
|
17781
|
+
if (!isNotFound(cleanupError)) {
|
|
17782
|
+
void cleanupError;
|
|
17783
|
+
}
|
|
17239
17784
|
}
|
|
17240
17785
|
}
|
|
17786
|
+
if (alreadyExists) {
|
|
17787
|
+
continue;
|
|
17788
|
+
}
|
|
17241
17789
|
throw error3;
|
|
17242
17790
|
}
|
|
17243
17791
|
}
|
|
17792
|
+
throw new Error(`Unable to create temporary mutation file for ${targetPath}.`);
|
|
17244
17793
|
}
|
|
17245
17794
|
function describeMutation(kind, targetPath) {
|
|
17246
17795
|
const displayPath = targetPath ?? "target";
|
|
@@ -17532,6 +18081,7 @@ async function applyBackup(mutation, context, options) {
|
|
|
17532
18081
|
break;
|
|
17533
18082
|
} catch (error3) {
|
|
17534
18083
|
if (!isAlreadyExists(error3)) {
|
|
18084
|
+
await context.fs.unlink(backupPath).catch(() => void 0);
|
|
17535
18085
|
throw error3;
|
|
17536
18086
|
}
|
|
17537
18087
|
attempt += 1;
|
|
@@ -17939,7 +18489,7 @@ async function pathExists2(fs4, targetPath) {
|
|
|
17939
18489
|
await fs4.stat(targetPath);
|
|
17940
18490
|
return true;
|
|
17941
18491
|
} catch (error3) {
|
|
17942
|
-
if (
|
|
18492
|
+
if (typeof error3 === "object" && error3 !== null && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "ENOENT") {
|
|
17943
18493
|
return false;
|
|
17944
18494
|
}
|
|
17945
18495
|
throw error3;
|
|
@@ -17952,14 +18502,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
17952
18502
|
throw new UnsupportedAgentError(agentId);
|
|
17953
18503
|
}
|
|
17954
18504
|
const scope = options.scope ?? "local";
|
|
17955
|
-
const
|
|
18505
|
+
const config2 = support.config;
|
|
17956
18506
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
17957
18507
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
17958
18508
|
}
|
|
17959
|
-
const skillDir = scope === "global" ?
|
|
18509
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
17960
18510
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
17961
18511
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
17962
|
-
const displayPath = `${scope === "global" ?
|
|
18512
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
17963
18513
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
17964
18514
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
17965
18515
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -17998,12 +18548,13 @@ import path19 from "node:path";
|
|
|
17998
18548
|
|
|
17999
18549
|
// ../agent-skill-config/src/git-exclude.ts
|
|
18000
18550
|
import { execFileSync } from "node:child_process";
|
|
18551
|
+
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
18001
18552
|
import * as fs2 from "node:fs";
|
|
18002
18553
|
import path20 from "node:path";
|
|
18003
18554
|
|
|
18004
18555
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
18005
18556
|
import * as fs3 from "node:fs";
|
|
18006
|
-
import { createHash as createHash4, randomUUID as
|
|
18557
|
+
import { createHash as createHash4, randomUUID as randomUUID9 } from "node:crypto";
|
|
18007
18558
|
import path21 from "node:path";
|
|
18008
18559
|
|
|
18009
18560
|
// src/commands/installer.ts
|
|
@@ -18016,7 +18567,7 @@ var DEFAULT_INSTALL_SCOPE = "local";
|
|
|
18016
18567
|
var TERMINAL_PILOT_SKILL_NAME = "terminal-pilot";
|
|
18017
18568
|
var installableAgents = supportedAgents;
|
|
18018
18569
|
function isNotFoundError2(error3) {
|
|
18019
|
-
return
|
|
18570
|
+
return hasOwnErrorCode(error3, "ENOENT");
|
|
18020
18571
|
}
|
|
18021
18572
|
function resolveInstallerServices(installer) {
|
|
18022
18573
|
return {
|
|
@@ -18080,17 +18631,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
18080
18631
|
return targetPath;
|
|
18081
18632
|
}
|
|
18082
18633
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
18083
|
-
const
|
|
18084
|
-
if (!
|
|
18634
|
+
const config2 = getAgentConfig(agent);
|
|
18635
|
+
if (!config2) {
|
|
18085
18636
|
throwUnsupportedAgent(agent);
|
|
18086
18637
|
}
|
|
18087
18638
|
return {
|
|
18088
18639
|
displayPath: path22.join(
|
|
18089
|
-
scope === "global" ?
|
|
18640
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
18090
18641
|
TERMINAL_PILOT_SKILL_NAME
|
|
18091
18642
|
),
|
|
18092
18643
|
fullPath: path22.join(
|
|
18093
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
18644
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path22.resolve(cwd, config2.localSkillDir),
|
|
18094
18645
|
TERMINAL_PILOT_SKILL_NAME
|
|
18095
18646
|
)
|
|
18096
18647
|
};
|
|
@@ -18247,7 +18798,7 @@ var resize = defineCommand({
|
|
|
18247
18798
|
});
|
|
18248
18799
|
|
|
18249
18800
|
// ../terminal-png/src/index.ts
|
|
18250
|
-
import { randomUUID as
|
|
18801
|
+
import { randomUUID as randomUUID10 } from "node:crypto";
|
|
18251
18802
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
18252
18803
|
|
|
18253
18804
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -19187,21 +19738,28 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
19187
19738
|
});
|
|
19188
19739
|
const png = renderPng(svg);
|
|
19189
19740
|
if (options.output) {
|
|
19190
|
-
const temporaryPath = `${options.output}.${
|
|
19741
|
+
const temporaryPath = `${options.output}.${randomUUID10()}.tmp`;
|
|
19742
|
+
let temporaryCreated = false;
|
|
19191
19743
|
try {
|
|
19192
19744
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
19745
|
+
temporaryCreated = true;
|
|
19193
19746
|
await rename4(temporaryPath, options.output);
|
|
19194
19747
|
} catch (error3) {
|
|
19195
|
-
|
|
19196
|
-
|
|
19197
|
-
|
|
19198
|
-
|
|
19748
|
+
if (temporaryCreated || !isAlreadyExistsError3(error3)) {
|
|
19749
|
+
try {
|
|
19750
|
+
await rm(temporaryPath, { force: true });
|
|
19751
|
+
} catch (cleanupError) {
|
|
19752
|
+
void cleanupError;
|
|
19753
|
+
}
|
|
19199
19754
|
}
|
|
19200
19755
|
throw error3;
|
|
19201
19756
|
}
|
|
19202
19757
|
}
|
|
19203
19758
|
return png;
|
|
19204
19759
|
}
|
|
19760
|
+
function isAlreadyExistsError3(error3) {
|
|
19761
|
+
return error3 instanceof Error && Object.prototype.hasOwnProperty.call(error3, "code") && error3.code === "EEXIST";
|
|
19762
|
+
}
|
|
19205
19763
|
|
|
19206
19764
|
// src/commands/screenshot.ts
|
|
19207
19765
|
var params11 = S.Object({
|
|
@@ -19264,7 +19822,7 @@ var type = defineCommand({
|
|
|
19264
19822
|
});
|
|
19265
19823
|
|
|
19266
19824
|
// src/commands/uninstall.ts
|
|
19267
|
-
import { randomUUID as
|
|
19825
|
+
import { randomUUID as randomUUID11 } from "node:crypto";
|
|
19268
19826
|
var params14 = S.Object({
|
|
19269
19827
|
agent: S.Enum(installableAgents, {
|
|
19270
19828
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19300,7 +19858,7 @@ var uninstall = defineCommand({
|
|
|
19300
19858
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19301
19859
|
continue;
|
|
19302
19860
|
}
|
|
19303
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19861
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID11()}`;
|
|
19304
19862
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19305
19863
|
staged.push({ ...skill, stagingPath });
|
|
19306
19864
|
}
|
|
@@ -19326,7 +19884,7 @@ async function folderExists(fs4, folderPath) {
|
|
|
19326
19884
|
await fs4.stat(folderPath);
|
|
19327
19885
|
return true;
|
|
19328
19886
|
} catch (error3) {
|
|
19329
|
-
if (
|
|
19887
|
+
if (hasOwnErrorCode(error3, "ENOENT")) {
|
|
19330
19888
|
return false;
|
|
19331
19889
|
}
|
|
19332
19890
|
throw error3;
|
|
@@ -19407,6 +19965,7 @@ function createTerminalPilotGroup() {
|
|
|
19407
19965
|
var terminalPilotGroup = Object.freeze(createTerminalPilotGroup());
|
|
19408
19966
|
|
|
19409
19967
|
// src/cli.ts
|
|
19968
|
+
configureTheme({ brand: "green", label: "Terminal Pilot" });
|
|
19410
19969
|
function normalizeArgv(argv) {
|
|
19411
19970
|
if (argv.includes("--json") && !argv.some((argument) => argument === "--output" || argument.startsWith("--output="))) {
|
|
19412
19971
|
return argv.flatMap((argument) => argument === "--json" ? ["--output", "json"] : [argument]);
|
|
@@ -19430,8 +19989,8 @@ async function isDirectExecution(argv) {
|
|
|
19430
19989
|
try {
|
|
19431
19990
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19432
19991
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19433
|
-
|
|
19434
|
-
|
|
19992
|
+
realpath3(path23.resolve(entryPoint)),
|
|
19993
|
+
realpath3(modulePath)
|
|
19435
19994
|
]);
|
|
19436
19995
|
return resolvedEntryPoint === resolvedModulePath;
|
|
19437
19996
|
} catch {
|