enact-cli 1.0.10 → 1.0.11
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/README.md +36 -2
- package/dist/index.js +1521 -134
- package/dist/index.js.bak +1521 -134
- package/dist/mcp-server.js +3006 -303
- package/dist/mcp-server.js.bak +3006 -303
- package/dist/web/static/app.js +591 -0
- package/dist/web/static/index.html +117 -0
- package/dist/web/static/style.css +287 -0
- package/package.json +4 -3
- package/src/web/static/app.js +591 -0
- package/src/web/static/index.html +117 -0
- package/src/web/static/style.css +287 -0
- package/dist/enact +0 -0
- package/dist/enact-linux +0 -0
- package/dist/enact-macos +0 -0
- package/dist/enact-windows.exe +0 -0
- package/dist/lib/enact-direct.js +0 -8223
- package/dist/mcp-direct.js +0 -21593
- package/dist/mcp-direct.js.bak +0 -21593
- package/dist/mcp-entry.js +0 -21665
- package/dist/mcp-entry.js.bak +0 -21665
package/dist/mcp-server.js.bak
CHANGED
|
@@ -25,6 +25,7 @@ var __export = (target, all) => {
|
|
|
25
25
|
set: (newValue) => all[name] = () => newValue
|
|
26
26
|
});
|
|
27
27
|
};
|
|
28
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
28
29
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
29
30
|
|
|
30
31
|
// node_modules/uri-js/dist/es5/uri.all.js
|
|
@@ -6194,6 +6195,1207 @@ var require_ajv = __commonJS((exports, module) => {
|
|
|
6194
6195
|
function noop() {}
|
|
6195
6196
|
});
|
|
6196
6197
|
|
|
6198
|
+
// src/exec/logger.ts
|
|
6199
|
+
var createLogger = () => {
|
|
6200
|
+
let mcpServer = null;
|
|
6201
|
+
const shouldSuppressConsole = process.env.CI === "true" || process.env.ENACT_SKIP_INTERACTIVE === "true";
|
|
6202
|
+
return {
|
|
6203
|
+
info: (message, ...args) => {
|
|
6204
|
+
if (!shouldSuppressConsole) {
|
|
6205
|
+
console.error("[INFO]", message, ...args);
|
|
6206
|
+
}
|
|
6207
|
+
if (mcpServer) {
|
|
6208
|
+
try {
|
|
6209
|
+
mcpServer.server.sendLoggingMessage({ level: "info", data: message });
|
|
6210
|
+
} catch (error) {}
|
|
6211
|
+
}
|
|
6212
|
+
},
|
|
6213
|
+
error: (message, ...args) => {
|
|
6214
|
+
if (!shouldSuppressConsole) {
|
|
6215
|
+
console.error("[ERROR]", message, ...args);
|
|
6216
|
+
}
|
|
6217
|
+
if (mcpServer) {
|
|
6218
|
+
try {
|
|
6219
|
+
mcpServer.server.sendLoggingMessage({ level: "error", data: message });
|
|
6220
|
+
} catch (error) {}
|
|
6221
|
+
}
|
|
6222
|
+
},
|
|
6223
|
+
warn: (message, ...args) => {
|
|
6224
|
+
if (!shouldSuppressConsole) {
|
|
6225
|
+
console.warn("[WARN]", message, ...args);
|
|
6226
|
+
}
|
|
6227
|
+
if (mcpServer) {
|
|
6228
|
+
try {
|
|
6229
|
+
mcpServer.server.sendLoggingMessage({ level: "warning", data: message });
|
|
6230
|
+
} catch (error) {}
|
|
6231
|
+
}
|
|
6232
|
+
},
|
|
6233
|
+
debug: (message, ...args) => {
|
|
6234
|
+
if ((process.env.DEBUG || process.env.VERBOSE) && !shouldSuppressConsole) {
|
|
6235
|
+
console.error("[DEBUG]", message, ...args);
|
|
6236
|
+
}
|
|
6237
|
+
if (mcpServer) {
|
|
6238
|
+
try {
|
|
6239
|
+
mcpServer.server.sendLoggingMessage({ level: "debug", data: message });
|
|
6240
|
+
} catch (error) {}
|
|
6241
|
+
}
|
|
6242
|
+
},
|
|
6243
|
+
setServer: (server) => {
|
|
6244
|
+
mcpServer = server;
|
|
6245
|
+
},
|
|
6246
|
+
clientLoggingEnabled: () => {
|
|
6247
|
+
return !!mcpServer;
|
|
6248
|
+
}
|
|
6249
|
+
};
|
|
6250
|
+
}, logger, logger_default;
|
|
6251
|
+
var init_logger = __esm(() => {
|
|
6252
|
+
logger = createLogger();
|
|
6253
|
+
logger_default = logger;
|
|
6254
|
+
});
|
|
6255
|
+
|
|
6256
|
+
// node_modules/sisteransi/src/index.js
|
|
6257
|
+
var require_src = __commonJS((exports, module) => {
|
|
6258
|
+
var ESC = "\x1B";
|
|
6259
|
+
var CSI = `${ESC}[`;
|
|
6260
|
+
var beep = "\x07";
|
|
6261
|
+
var cursor = {
|
|
6262
|
+
to(x, y) {
|
|
6263
|
+
if (!y)
|
|
6264
|
+
return `${CSI}${x + 1}G`;
|
|
6265
|
+
return `${CSI}${y + 1};${x + 1}H`;
|
|
6266
|
+
},
|
|
6267
|
+
move(x, y) {
|
|
6268
|
+
let ret = "";
|
|
6269
|
+
if (x < 0)
|
|
6270
|
+
ret += `${CSI}${-x}D`;
|
|
6271
|
+
else if (x > 0)
|
|
6272
|
+
ret += `${CSI}${x}C`;
|
|
6273
|
+
if (y < 0)
|
|
6274
|
+
ret += `${CSI}${-y}A`;
|
|
6275
|
+
else if (y > 0)
|
|
6276
|
+
ret += `${CSI}${y}B`;
|
|
6277
|
+
return ret;
|
|
6278
|
+
},
|
|
6279
|
+
up: (count = 1) => `${CSI}${count}A`,
|
|
6280
|
+
down: (count = 1) => `${CSI}${count}B`,
|
|
6281
|
+
forward: (count = 1) => `${CSI}${count}C`,
|
|
6282
|
+
backward: (count = 1) => `${CSI}${count}D`,
|
|
6283
|
+
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
6284
|
+
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
6285
|
+
left: `${CSI}G`,
|
|
6286
|
+
hide: `${CSI}?25l`,
|
|
6287
|
+
show: `${CSI}?25h`,
|
|
6288
|
+
save: `${ESC}7`,
|
|
6289
|
+
restore: `${ESC}8`
|
|
6290
|
+
};
|
|
6291
|
+
var scroll = {
|
|
6292
|
+
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
6293
|
+
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
6294
|
+
};
|
|
6295
|
+
var erase = {
|
|
6296
|
+
screen: `${CSI}2J`,
|
|
6297
|
+
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
6298
|
+
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
6299
|
+
line: `${CSI}2K`,
|
|
6300
|
+
lineEnd: `${CSI}K`,
|
|
6301
|
+
lineStart: `${CSI}1K`,
|
|
6302
|
+
lines(count) {
|
|
6303
|
+
let clear = "";
|
|
6304
|
+
for (let i = 0;i < count; i++)
|
|
6305
|
+
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
6306
|
+
if (count)
|
|
6307
|
+
clear += cursor.left;
|
|
6308
|
+
return clear;
|
|
6309
|
+
}
|
|
6310
|
+
};
|
|
6311
|
+
module.exports = { cursor, scroll, erase, beep };
|
|
6312
|
+
});
|
|
6313
|
+
|
|
6314
|
+
// node_modules/picocolors/picocolors.js
|
|
6315
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
6316
|
+
var p = process || {};
|
|
6317
|
+
var argv = p.argv || [];
|
|
6318
|
+
var env = p.env || {};
|
|
6319
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
6320
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
6321
|
+
let string2 = "" + input, index = string2.indexOf(close, open.length);
|
|
6322
|
+
return ~index ? open + replaceClose(string2, close, replace, index) + close : open + string2 + close;
|
|
6323
|
+
};
|
|
6324
|
+
var replaceClose = (string2, close, replace, index) => {
|
|
6325
|
+
let result = "", cursor = 0;
|
|
6326
|
+
do {
|
|
6327
|
+
result += string2.substring(cursor, index) + replace;
|
|
6328
|
+
cursor = index + close.length;
|
|
6329
|
+
index = string2.indexOf(close, cursor);
|
|
6330
|
+
} while (~index);
|
|
6331
|
+
return result + string2.substring(cursor);
|
|
6332
|
+
};
|
|
6333
|
+
var createColors = (enabled = isColorSupported) => {
|
|
6334
|
+
let f = enabled ? formatter : () => String;
|
|
6335
|
+
return {
|
|
6336
|
+
isColorSupported: enabled,
|
|
6337
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
6338
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
6339
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
6340
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
6341
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
6342
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
6343
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
6344
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
6345
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
6346
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
6347
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
6348
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
6349
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
6350
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
6351
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
6352
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
6353
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
6354
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
6355
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
6356
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
6357
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
6358
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
6359
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
6360
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
6361
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
6362
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
6363
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
6364
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
6365
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
6366
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
6367
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
6368
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
6369
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
6370
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
6371
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
6372
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
6373
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
6374
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
6375
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
6376
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
6377
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
6378
|
+
};
|
|
6379
|
+
};
|
|
6380
|
+
module.exports = createColors();
|
|
6381
|
+
module.exports.createColors = createColors;
|
|
6382
|
+
});
|
|
6383
|
+
|
|
6384
|
+
// node_modules/@clack/core/dist/index.cjs
|
|
6385
|
+
var require_dist = __commonJS((exports) => {
|
|
6386
|
+
var sisteransi = require_src();
|
|
6387
|
+
var node_process = __require("node:process");
|
|
6388
|
+
var s$2 = __require("node:readline");
|
|
6389
|
+
var node_stream = __require("node:stream");
|
|
6390
|
+
var i$1 = require_picocolors();
|
|
6391
|
+
function _interopDefaultCompat(C) {
|
|
6392
|
+
return C && typeof C == "object" && "default" in C ? C.default : C;
|
|
6393
|
+
}
|
|
6394
|
+
function _interopNamespaceCompat(C) {
|
|
6395
|
+
if (C && typeof C == "object" && "default" in C)
|
|
6396
|
+
return C;
|
|
6397
|
+
const t = Object.create(null);
|
|
6398
|
+
if (C)
|
|
6399
|
+
for (const F in C)
|
|
6400
|
+
t[F] = C[F];
|
|
6401
|
+
return t.default = C, t;
|
|
6402
|
+
}
|
|
6403
|
+
var s__namespace = _interopNamespaceCompat(s$2);
|
|
6404
|
+
var s__default = _interopDefaultCompat(s$2);
|
|
6405
|
+
var i__default = _interopDefaultCompat(i$1);
|
|
6406
|
+
function ansiRegex({ onlyFirst: C = false } = {}) {
|
|
6407
|
+
const F = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
|
6408
|
+
return new RegExp(F, C ? undefined : "g");
|
|
6409
|
+
}
|
|
6410
|
+
var regex = ansiRegex();
|
|
6411
|
+
function stripAnsi(C) {
|
|
6412
|
+
if (typeof C != "string")
|
|
6413
|
+
throw new TypeError(`Expected a \`string\`, got \`${typeof C}\``);
|
|
6414
|
+
return C.replace(regex, "");
|
|
6415
|
+
}
|
|
6416
|
+
function getDefaultExportFromCjs(C) {
|
|
6417
|
+
return C && C.__esModule && Object.prototype.hasOwnProperty.call(C, "default") ? C.default : C;
|
|
6418
|
+
}
|
|
6419
|
+
var eastasianwidth = { exports: {} };
|
|
6420
|
+
(function(C) {
|
|
6421
|
+
var t = {};
|
|
6422
|
+
C.exports = t, t.eastAsianWidth = function(E) {
|
|
6423
|
+
var B = E.charCodeAt(0), A = E.length == 2 ? E.charCodeAt(1) : 0, D = B;
|
|
6424
|
+
return 55296 <= B && B <= 56319 && 56320 <= A && A <= 57343 && (B &= 1023, A &= 1023, D = B << 10 | A, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
|
|
6425
|
+
}, t.characterLength = function(E) {
|
|
6426
|
+
var B = this.eastAsianWidth(E);
|
|
6427
|
+
return B == "F" || B == "W" || B == "A" ? 2 : 1;
|
|
6428
|
+
};
|
|
6429
|
+
function F(E) {
|
|
6430
|
+
return E.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
6431
|
+
}
|
|
6432
|
+
t.length = function(E) {
|
|
6433
|
+
for (var B = F(E), A = 0, D = 0;D < B.length; D++)
|
|
6434
|
+
A = A + this.characterLength(B[D]);
|
|
6435
|
+
return A;
|
|
6436
|
+
}, t.slice = function(E, B, A) {
|
|
6437
|
+
textLen = t.length(E), B = B || 0, A = A || 1, B < 0 && (B = textLen + B), A < 0 && (A = textLen + A);
|
|
6438
|
+
for (var D = "", f = 0, y = F(E), d = 0;d < y.length; d++) {
|
|
6439
|
+
var _ = y[d], w = t.length(_);
|
|
6440
|
+
if (f >= B - (w == 2 ? 1 : 0))
|
|
6441
|
+
if (f + w <= A)
|
|
6442
|
+
D += _;
|
|
6443
|
+
else
|
|
6444
|
+
break;
|
|
6445
|
+
f += w;
|
|
6446
|
+
}
|
|
6447
|
+
return D;
|
|
6448
|
+
};
|
|
6449
|
+
})(eastasianwidth);
|
|
6450
|
+
var eastasianwidthExports = eastasianwidth.exports;
|
|
6451
|
+
var eastAsianWidth = getDefaultExportFromCjs(eastasianwidthExports);
|
|
6452
|
+
var emojiRegex3 = function() {
|
|
6453
|
+
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
6454
|
+
};
|
|
6455
|
+
var emojiRegex$1 = getDefaultExportFromCjs(emojiRegex3);
|
|
6456
|
+
function stringWidth(C, t = {}) {
|
|
6457
|
+
if (typeof C != "string" || C.length === 0 || (t = { ambiguousIsNarrow: true, ...t }, C = stripAnsi(C), C.length === 0))
|
|
6458
|
+
return 0;
|
|
6459
|
+
C = C.replace(emojiRegex$1(), " ");
|
|
6460
|
+
const F = t.ambiguousIsNarrow ? 1 : 2;
|
|
6461
|
+
let E = 0;
|
|
6462
|
+
for (const B of C) {
|
|
6463
|
+
const A = B.codePointAt(0);
|
|
6464
|
+
if (A <= 31 || A >= 127 && A <= 159 || A >= 768 && A <= 879)
|
|
6465
|
+
continue;
|
|
6466
|
+
switch (eastAsianWidth.eastAsianWidth(B)) {
|
|
6467
|
+
case "F":
|
|
6468
|
+
case "W":
|
|
6469
|
+
E += 2;
|
|
6470
|
+
break;
|
|
6471
|
+
case "A":
|
|
6472
|
+
E += F;
|
|
6473
|
+
break;
|
|
6474
|
+
default:
|
|
6475
|
+
E += 1;
|
|
6476
|
+
}
|
|
6477
|
+
}
|
|
6478
|
+
return E;
|
|
6479
|
+
}
|
|
6480
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
6481
|
+
var wrapAnsi16 = (C = 0) => (t) => `\x1B[${t + C}m`;
|
|
6482
|
+
var wrapAnsi256 = (C = 0) => (t) => `\x1B[${38 + C};5;${t}m`;
|
|
6483
|
+
var wrapAnsi16m = (C = 0) => (t, F, E) => `\x1B[${38 + C};2;${t};${F};${E}m`;
|
|
6484
|
+
var styles = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
|
|
6485
|
+
Object.keys(styles.modifier);
|
|
6486
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
6487
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
6488
|
+
[...foregroundColorNames];
|
|
6489
|
+
function assembleStyles() {
|
|
6490
|
+
const C = new Map;
|
|
6491
|
+
for (const [t, F] of Object.entries(styles)) {
|
|
6492
|
+
for (const [E, B] of Object.entries(F))
|
|
6493
|
+
styles[E] = { open: `\x1B[${B[0]}m`, close: `\x1B[${B[1]}m` }, F[E] = styles[E], C.set(B[0], B[1]);
|
|
6494
|
+
Object.defineProperty(styles, t, { value: F, enumerable: false });
|
|
6495
|
+
}
|
|
6496
|
+
return Object.defineProperty(styles, "codes", { value: C, enumerable: false }), styles.color.close = "\x1B[39m", styles.bgColor.close = "\x1B[49m", styles.color.ansi = wrapAnsi16(), styles.color.ansi256 = wrapAnsi256(), styles.color.ansi16m = wrapAnsi16m(), styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET), styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET), styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET), Object.defineProperties(styles, { rgbToAnsi256: { value: (t, F, E) => t === F && F === E ? t < 8 ? 16 : t > 248 ? 231 : Math.round((t - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(t / 255 * 5) + 6 * Math.round(F / 255 * 5) + Math.round(E / 255 * 5), enumerable: false }, hexToRgb: { value: (t) => {
|
|
6497
|
+
const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(t.toString(16));
|
|
6498
|
+
if (!F)
|
|
6499
|
+
return [0, 0, 0];
|
|
6500
|
+
let [E] = F;
|
|
6501
|
+
E.length === 3 && (E = [...E].map((A) => A + A).join(""));
|
|
6502
|
+
const B = Number.parseInt(E, 16);
|
|
6503
|
+
return [B >> 16 & 255, B >> 8 & 255, B & 255];
|
|
6504
|
+
}, enumerable: false }, hexToAnsi256: { value: (t) => styles.rgbToAnsi256(...styles.hexToRgb(t)), enumerable: false }, ansi256ToAnsi: { value: (t) => {
|
|
6505
|
+
if (t < 8)
|
|
6506
|
+
return 30 + t;
|
|
6507
|
+
if (t < 16)
|
|
6508
|
+
return 90 + (t - 8);
|
|
6509
|
+
let F, E, B;
|
|
6510
|
+
if (t >= 232)
|
|
6511
|
+
F = ((t - 232) * 10 + 8) / 255, E = F, B = F;
|
|
6512
|
+
else {
|
|
6513
|
+
t -= 16;
|
|
6514
|
+
const f = t % 36;
|
|
6515
|
+
F = Math.floor(t / 36) / 5, E = Math.floor(f / 6) / 5, B = f % 6 / 5;
|
|
6516
|
+
}
|
|
6517
|
+
const A = Math.max(F, E, B) * 2;
|
|
6518
|
+
if (A === 0)
|
|
6519
|
+
return 30;
|
|
6520
|
+
let D = 30 + (Math.round(B) << 2 | Math.round(E) << 1 | Math.round(F));
|
|
6521
|
+
return A === 2 && (D += 60), D;
|
|
6522
|
+
}, enumerable: false }, rgbToAnsi: { value: (t, F, E) => styles.ansi256ToAnsi(styles.rgbToAnsi256(t, F, E)), enumerable: false }, hexToAnsi: { value: (t) => styles.ansi256ToAnsi(styles.hexToAnsi256(t)), enumerable: false } }), styles;
|
|
6523
|
+
}
|
|
6524
|
+
var ansiStyles = assembleStyles();
|
|
6525
|
+
var ESCAPES = new Set(["\x1B", ""]);
|
|
6526
|
+
var END_CODE = 39;
|
|
6527
|
+
var ANSI_ESCAPE_BELL = "\x07";
|
|
6528
|
+
var ANSI_CSI = "[";
|
|
6529
|
+
var ANSI_OSC = "]";
|
|
6530
|
+
var ANSI_SGR_TERMINATOR = "m";
|
|
6531
|
+
var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
6532
|
+
var wrapAnsiCode = (C) => `${ESCAPES.values().next().value}${ANSI_CSI}${C}${ANSI_SGR_TERMINATOR}`;
|
|
6533
|
+
var wrapAnsiHyperlink = (C) => `${ESCAPES.values().next().value}${ANSI_ESCAPE_LINK}${C}${ANSI_ESCAPE_BELL}`;
|
|
6534
|
+
var wordLengths = (C) => C.split(" ").map((t) => stringWidth(t));
|
|
6535
|
+
var wrapWord = (C, t, F) => {
|
|
6536
|
+
const E = [...t];
|
|
6537
|
+
let B = false, A = false, D = stringWidth(stripAnsi(C[C.length - 1]));
|
|
6538
|
+
for (const [f, y] of E.entries()) {
|
|
6539
|
+
const d = stringWidth(y);
|
|
6540
|
+
if (D + d <= F ? C[C.length - 1] += y : (C.push(y), D = 0), ESCAPES.has(y) && (B = true, A = E.slice(f + 1).join("").startsWith(ANSI_ESCAPE_LINK)), B) {
|
|
6541
|
+
A ? y === ANSI_ESCAPE_BELL && (B = false, A = false) : y === ANSI_SGR_TERMINATOR && (B = false);
|
|
6542
|
+
continue;
|
|
6543
|
+
}
|
|
6544
|
+
D += d, D === F && f < E.length - 1 && (C.push(""), D = 0);
|
|
6545
|
+
}
|
|
6546
|
+
!D && C[C.length - 1].length > 0 && C.length > 1 && (C[C.length - 2] += C.pop());
|
|
6547
|
+
};
|
|
6548
|
+
var stringVisibleTrimSpacesRight = (C) => {
|
|
6549
|
+
const t = C.split(" ");
|
|
6550
|
+
let F = t.length;
|
|
6551
|
+
for (;F > 0 && !(stringWidth(t[F - 1]) > 0); )
|
|
6552
|
+
F--;
|
|
6553
|
+
return F === t.length ? C : t.slice(0, F).join(" ") + t.slice(F).join("");
|
|
6554
|
+
};
|
|
6555
|
+
var exec = (C, t, F = {}) => {
|
|
6556
|
+
if (F.trim !== false && C.trim() === "")
|
|
6557
|
+
return "";
|
|
6558
|
+
let E = "", B, A;
|
|
6559
|
+
const D = wordLengths(C);
|
|
6560
|
+
let f = [""];
|
|
6561
|
+
for (const [d, _] of C.split(" ").entries()) {
|
|
6562
|
+
F.trim !== false && (f[f.length - 1] = f[f.length - 1].trimStart());
|
|
6563
|
+
let w = stringWidth(f[f.length - 1]);
|
|
6564
|
+
if (d !== 0 && (w >= t && (F.wordWrap === false || F.trim === false) && (f.push(""), w = 0), (w > 0 || F.trim === false) && (f[f.length - 1] += " ", w++)), F.hard && D[d] > t) {
|
|
6565
|
+
const S = t - w, $ = 1 + Math.floor((D[d] - S - 1) / t);
|
|
6566
|
+
Math.floor((D[d] - 1) / t) < $ && f.push(""), wrapWord(f, _, t);
|
|
6567
|
+
continue;
|
|
6568
|
+
}
|
|
6569
|
+
if (w + D[d] > t && w > 0 && D[d] > 0) {
|
|
6570
|
+
if (F.wordWrap === false && w < t) {
|
|
6571
|
+
wrapWord(f, _, t);
|
|
6572
|
+
continue;
|
|
6573
|
+
}
|
|
6574
|
+
f.push("");
|
|
6575
|
+
}
|
|
6576
|
+
if (w + D[d] > t && F.wordWrap === false) {
|
|
6577
|
+
wrapWord(f, _, t);
|
|
6578
|
+
continue;
|
|
6579
|
+
}
|
|
6580
|
+
f[f.length - 1] += _;
|
|
6581
|
+
}
|
|
6582
|
+
F.trim !== false && (f = f.map((d) => stringVisibleTrimSpacesRight(d)));
|
|
6583
|
+
const y = [...f.join(`
|
|
6584
|
+
`)];
|
|
6585
|
+
for (const [d, _] of y.entries()) {
|
|
6586
|
+
if (E += _, ESCAPES.has(_)) {
|
|
6587
|
+
const { groups: S } = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`).exec(y.slice(d).join("")) || { groups: {} };
|
|
6588
|
+
if (S.code !== undefined) {
|
|
6589
|
+
const $ = Number.parseFloat(S.code);
|
|
6590
|
+
B = $ === END_CODE ? undefined : $;
|
|
6591
|
+
} else
|
|
6592
|
+
S.uri !== undefined && (A = S.uri.length === 0 ? undefined : S.uri);
|
|
6593
|
+
}
|
|
6594
|
+
const w = ansiStyles.codes.get(Number(B));
|
|
6595
|
+
y[d + 1] === `
|
|
6596
|
+
` ? (A && (E += wrapAnsiHyperlink("")), B && w && (E += wrapAnsiCode(w))) : _ === `
|
|
6597
|
+
` && (B && w && (E += wrapAnsiCode(B)), A && (E += wrapAnsiHyperlink(A)));
|
|
6598
|
+
}
|
|
6599
|
+
return E;
|
|
6600
|
+
};
|
|
6601
|
+
function wrapAnsi(C, t, F) {
|
|
6602
|
+
return String(C).normalize().replace(/\r\n/g, `
|
|
6603
|
+
`).split(`
|
|
6604
|
+
`).map((E) => exec(E, t, F)).join(`
|
|
6605
|
+
`);
|
|
6606
|
+
}
|
|
6607
|
+
var a$1 = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
6608
|
+
var settings = { actions: new Set(a$1), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
|
|
6609
|
+
function updateSettings(C) {
|
|
6610
|
+
for (const t in C) {
|
|
6611
|
+
const F = t;
|
|
6612
|
+
if (!Object.hasOwn(C, F))
|
|
6613
|
+
continue;
|
|
6614
|
+
const E = C[F];
|
|
6615
|
+
switch (F) {
|
|
6616
|
+
case "aliases": {
|
|
6617
|
+
for (const B in E)
|
|
6618
|
+
Object.hasOwn(E, B) && (settings.aliases.has(B) || settings.aliases.set(B, E[B]));
|
|
6619
|
+
break;
|
|
6620
|
+
}
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6623
|
+
}
|
|
6624
|
+
function isActionKey(C, t) {
|
|
6625
|
+
if (typeof C == "string")
|
|
6626
|
+
return settings.aliases.get(C) === t;
|
|
6627
|
+
for (const F of C)
|
|
6628
|
+
if (F !== undefined && isActionKey(F, t))
|
|
6629
|
+
return true;
|
|
6630
|
+
return false;
|
|
6631
|
+
}
|
|
6632
|
+
function diffLines(C, t) {
|
|
6633
|
+
if (C === t)
|
|
6634
|
+
return;
|
|
6635
|
+
const F = C.split(`
|
|
6636
|
+
`), E = t.split(`
|
|
6637
|
+
`), B = [];
|
|
6638
|
+
for (let A = 0;A < Math.max(F.length, E.length); A++)
|
|
6639
|
+
F[A] !== E[A] && B.push(A);
|
|
6640
|
+
return B;
|
|
6641
|
+
}
|
|
6642
|
+
var x = globalThis.process.platform.startsWith("win");
|
|
6643
|
+
var CANCEL_SYMBOL = Symbol("clack:cancel");
|
|
6644
|
+
function isCancel(C) {
|
|
6645
|
+
return C === CANCEL_SYMBOL;
|
|
6646
|
+
}
|
|
6647
|
+
function setRawMode(C, t) {
|
|
6648
|
+
const F = C;
|
|
6649
|
+
F.isTTY && F.setRawMode(t);
|
|
6650
|
+
}
|
|
6651
|
+
function block({ input: C = node_process.stdin, output: t = node_process.stdout, overwrite: F = true, hideCursor: E = true } = {}) {
|
|
6652
|
+
const B = s__namespace.createInterface({ input: C, output: t, prompt: "", tabSize: 1 });
|
|
6653
|
+
s__namespace.emitKeypressEvents(C, B), C.isTTY && C.setRawMode(true);
|
|
6654
|
+
const A = (D, { name: f, sequence: y }) => {
|
|
6655
|
+
const d = String(D);
|
|
6656
|
+
if (isActionKey([d, f, y], "cancel")) {
|
|
6657
|
+
E && t.write(sisteransi.cursor.show), process.exit(0);
|
|
6658
|
+
return;
|
|
6659
|
+
}
|
|
6660
|
+
if (!F)
|
|
6661
|
+
return;
|
|
6662
|
+
const _ = f === "return" ? 0 : -1, w = f === "return" ? -1 : 0;
|
|
6663
|
+
s__namespace.moveCursor(t, _, w, () => {
|
|
6664
|
+
s__namespace.clearLine(t, 1, () => {
|
|
6665
|
+
C.once("keypress", A);
|
|
6666
|
+
});
|
|
6667
|
+
});
|
|
6668
|
+
};
|
|
6669
|
+
return E && t.write(sisteransi.cursor.hide), C.once("keypress", A), () => {
|
|
6670
|
+
C.off("keypress", A), E && t.write(sisteransi.cursor.show), C.isTTY && !x && C.setRawMode(false), B.terminal = false, B.close();
|
|
6671
|
+
};
|
|
6672
|
+
}
|
|
6673
|
+
var b = Object.defineProperty;
|
|
6674
|
+
var v$1 = (C, t, F) => (t in C) ? b(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6675
|
+
var s$1 = (C, t, F) => (v$1(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6676
|
+
|
|
6677
|
+
class k {
|
|
6678
|
+
constructor(t, F = true) {
|
|
6679
|
+
s$1(this, "input"), s$1(this, "output"), s$1(this, "_abortSignal"), s$1(this, "rl"), s$1(this, "opts"), s$1(this, "_render"), s$1(this, "_track", false), s$1(this, "_prevFrame", ""), s$1(this, "_subscribers", new Map), s$1(this, "_cursor", 0), s$1(this, "state", "initial"), s$1(this, "error", ""), s$1(this, "value");
|
|
6680
|
+
const { input: E = node_process.stdin, output: B = node_process.stdout, render: A, signal: D, ...f } = t;
|
|
6681
|
+
this.opts = f, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = A.bind(this), this._track = F, this._abortSignal = D, this.input = E, this.output = B;
|
|
6682
|
+
}
|
|
6683
|
+
unsubscribe() {
|
|
6684
|
+
this._subscribers.clear();
|
|
6685
|
+
}
|
|
6686
|
+
setSubscriber(t, F) {
|
|
6687
|
+
const E = this._subscribers.get(t) ?? [];
|
|
6688
|
+
E.push(F), this._subscribers.set(t, E);
|
|
6689
|
+
}
|
|
6690
|
+
on(t, F) {
|
|
6691
|
+
this.setSubscriber(t, { cb: F });
|
|
6692
|
+
}
|
|
6693
|
+
once(t, F) {
|
|
6694
|
+
this.setSubscriber(t, { cb: F, once: true });
|
|
6695
|
+
}
|
|
6696
|
+
emit(t, ...F) {
|
|
6697
|
+
const E = this._subscribers.get(t) ?? [], B = [];
|
|
6698
|
+
for (const A of E)
|
|
6699
|
+
A.cb(...F), A.once && B.push(() => E.splice(E.indexOf(A), 1));
|
|
6700
|
+
for (const A of B)
|
|
6701
|
+
A();
|
|
6702
|
+
}
|
|
6703
|
+
prompt() {
|
|
6704
|
+
return new Promise((t, F) => {
|
|
6705
|
+
if (this._abortSignal) {
|
|
6706
|
+
if (this._abortSignal.aborted)
|
|
6707
|
+
return this.state = "cancel", this.close(), t(CANCEL_SYMBOL);
|
|
6708
|
+
this._abortSignal.addEventListener("abort", () => {
|
|
6709
|
+
this.state = "cancel", this.close();
|
|
6710
|
+
}, { once: true });
|
|
6711
|
+
}
|
|
6712
|
+
const E = new node_stream.Writable;
|
|
6713
|
+
E._write = (B, A, D) => {
|
|
6714
|
+
this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
|
|
6715
|
+
}, this.input.pipe(E), this.rl = s__default.createInterface({ input: this.input, output: E, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), s__default.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), setRawMode(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
6716
|
+
this.output.write(sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t(this.value);
|
|
6717
|
+
}), this.once("cancel", () => {
|
|
6718
|
+
this.output.write(sisteransi.cursor.show), this.output.off("resize", this.render), setRawMode(this.input, false), t(CANCEL_SYMBOL);
|
|
6719
|
+
});
|
|
6720
|
+
});
|
|
6721
|
+
}
|
|
6722
|
+
onKeypress(t, F) {
|
|
6723
|
+
if (this.state === "error" && (this.state = "active"), F?.name && (!this._track && settings.aliases.has(F.name) && this.emit("cursor", settings.aliases.get(F.name)), settings.actions.has(F.name) && this.emit("cursor", F.name)), t && (t.toLowerCase() === "y" || t.toLowerCase() === "n") && this.emit("confirm", t.toLowerCase() === "y"), t === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), t && this.emit("key", t.toLowerCase()), F?.name === "return") {
|
|
6724
|
+
if (!this.value && this.opts.placeholder && (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder)), this.opts.validate) {
|
|
6725
|
+
const E = this.opts.validate(this.value);
|
|
6726
|
+
E && (this.error = E instanceof Error ? E.message : E, this.state = "error", this.rl?.write(this.value));
|
|
6727
|
+
}
|
|
6728
|
+
this.state !== "error" && (this.state = "submit");
|
|
6729
|
+
}
|
|
6730
|
+
isActionKey([t, F?.name, F?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
6731
|
+
}
|
|
6732
|
+
close() {
|
|
6733
|
+
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
6734
|
+
`), setRawMode(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
6735
|
+
}
|
|
6736
|
+
restoreCursor() {
|
|
6737
|
+
const t = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true }).split(`
|
|
6738
|
+
`).length - 1;
|
|
6739
|
+
this.output.write(sisteransi.cursor.move(-999, t * -1));
|
|
6740
|
+
}
|
|
6741
|
+
render() {
|
|
6742
|
+
const t = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true });
|
|
6743
|
+
if (t !== this._prevFrame) {
|
|
6744
|
+
if (this.state === "initial")
|
|
6745
|
+
this.output.write(sisteransi.cursor.hide);
|
|
6746
|
+
else {
|
|
6747
|
+
const F = diffLines(this._prevFrame, t);
|
|
6748
|
+
if (this.restoreCursor(), F && F?.length === 1) {
|
|
6749
|
+
const E = F[0];
|
|
6750
|
+
this.output.write(sisteransi.cursor.move(0, E)), this.output.write(sisteransi.erase.lines(1));
|
|
6751
|
+
const B = t.split(`
|
|
6752
|
+
`);
|
|
6753
|
+
this.output.write(B[E]), this._prevFrame = t, this.output.write(sisteransi.cursor.move(0, B.length - E - 1));
|
|
6754
|
+
return;
|
|
6755
|
+
}
|
|
6756
|
+
if (F && F?.length > 1) {
|
|
6757
|
+
const E = F[0];
|
|
6758
|
+
this.output.write(sisteransi.cursor.move(0, E)), this.output.write(sisteransi.erase.down());
|
|
6759
|
+
const B = t.split(`
|
|
6760
|
+
`).slice(E);
|
|
6761
|
+
this.output.write(B.join(`
|
|
6762
|
+
`)), this._prevFrame = t;
|
|
6763
|
+
return;
|
|
6764
|
+
}
|
|
6765
|
+
this.output.write(sisteransi.erase.down());
|
|
6766
|
+
}
|
|
6767
|
+
this.output.write(t), this.state === "initial" && (this.state = "active"), this._prevFrame = t;
|
|
6768
|
+
}
|
|
6769
|
+
}
|
|
6770
|
+
}
|
|
6771
|
+
|
|
6772
|
+
class s extends k {
|
|
6773
|
+
get cursor() {
|
|
6774
|
+
return this.value ? 0 : 1;
|
|
6775
|
+
}
|
|
6776
|
+
get _value() {
|
|
6777
|
+
return this.cursor === 0;
|
|
6778
|
+
}
|
|
6779
|
+
constructor(t) {
|
|
6780
|
+
super(t, false), this.value = !!t.initialValue, this.on("value", () => {
|
|
6781
|
+
this.value = this._value;
|
|
6782
|
+
}), this.on("confirm", (F) => {
|
|
6783
|
+
this.output.write(sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
|
|
6784
|
+
}), this.on("cursor", () => {
|
|
6785
|
+
this.value = !this.value;
|
|
6786
|
+
});
|
|
6787
|
+
}
|
|
6788
|
+
}
|
|
6789
|
+
var v = Object.defineProperty;
|
|
6790
|
+
var g = (C, t, F) => (t in C) ? v(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6791
|
+
var n$2 = (C, t, F) => (g(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6792
|
+
var c$1 = (C, t, F) => {
|
|
6793
|
+
if (!t.has(C))
|
|
6794
|
+
throw TypeError("Cannot " + F);
|
|
6795
|
+
};
|
|
6796
|
+
var l$2 = (C, t, F) => (c$1(C, t, "read from private field"), F ? F.call(C) : t.get(C));
|
|
6797
|
+
var h = (C, t, F) => {
|
|
6798
|
+
if (t.has(C))
|
|
6799
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
6800
|
+
t instanceof WeakSet ? t.add(C) : t.set(C, F);
|
|
6801
|
+
};
|
|
6802
|
+
var p$1 = (C, t, F, E) => (c$1(C, t, "write to private field"), E ? E.call(C, F) : t.set(C, F), F);
|
|
6803
|
+
var u$3;
|
|
6804
|
+
var m$1 = class extends k {
|
|
6805
|
+
constructor(t) {
|
|
6806
|
+
super(t, false), n$2(this, "options"), n$2(this, "cursor", 0), h(this, u$3, undefined);
|
|
6807
|
+
const { options: F } = t;
|
|
6808
|
+
p$1(this, u$3, t.selectableGroups !== false), this.options = Object.entries(F).flatMap(([E, B]) => [{ value: E, group: true, label: E }, ...B.map((A) => ({ ...A, group: E }))]), this.value = [...t.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: E }) => E === t.cursorAt), l$2(this, u$3) ? 0 : 1), this.on("cursor", (E) => {
|
|
6809
|
+
switch (E) {
|
|
6810
|
+
case "left":
|
|
6811
|
+
case "up": {
|
|
6812
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
6813
|
+
const B = this.options[this.cursor]?.group === true;
|
|
6814
|
+
!l$2(this, u$3) && B && (this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1);
|
|
6815
|
+
break;
|
|
6816
|
+
}
|
|
6817
|
+
case "down":
|
|
6818
|
+
case "right": {
|
|
6819
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
6820
|
+
const B = this.options[this.cursor]?.group === true;
|
|
6821
|
+
!l$2(this, u$3) && B && (this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1);
|
|
6822
|
+
break;
|
|
6823
|
+
}
|
|
6824
|
+
case "space":
|
|
6825
|
+
this.toggleValue();
|
|
6826
|
+
break;
|
|
6827
|
+
}
|
|
6828
|
+
});
|
|
6829
|
+
}
|
|
6830
|
+
getGroupItems(t) {
|
|
6831
|
+
return this.options.filter((F) => F.group === t);
|
|
6832
|
+
}
|
|
6833
|
+
isGroupSelected(t) {
|
|
6834
|
+
return this.getGroupItems(t).every((F) => this.value.includes(F.value));
|
|
6835
|
+
}
|
|
6836
|
+
toggleValue() {
|
|
6837
|
+
const t = this.options[this.cursor];
|
|
6838
|
+
if (t.group === true) {
|
|
6839
|
+
const F = t.value, E = this.getGroupItems(F);
|
|
6840
|
+
this.isGroupSelected(F) ? this.value = this.value.filter((B) => E.findIndex((A) => A.value === B) === -1) : this.value = [...this.value, ...E.map((B) => B.value)], this.value = Array.from(new Set(this.value));
|
|
6841
|
+
} else {
|
|
6842
|
+
const F = this.value.includes(t.value);
|
|
6843
|
+
this.value = F ? this.value.filter((E) => E !== t.value) : [...this.value, t.value];
|
|
6844
|
+
}
|
|
6845
|
+
}
|
|
6846
|
+
};
|
|
6847
|
+
u$3 = new WeakMap;
|
|
6848
|
+
var o$2 = Object.defineProperty;
|
|
6849
|
+
var a = (C, t, F) => (t in C) ? o$2(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6850
|
+
var l$1 = (C, t, F) => (a(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6851
|
+
var u$2 = class extends k {
|
|
6852
|
+
constructor(t) {
|
|
6853
|
+
super(t, false), l$1(this, "options"), l$1(this, "cursor", 0), this.options = t.options, this.value = [...t.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === t.cursorAt), 0), this.on("key", (F) => {
|
|
6854
|
+
F === "a" && this.toggleAll();
|
|
6855
|
+
}), this.on("cursor", (F) => {
|
|
6856
|
+
switch (F) {
|
|
6857
|
+
case "left":
|
|
6858
|
+
case "up":
|
|
6859
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
6860
|
+
break;
|
|
6861
|
+
case "down":
|
|
6862
|
+
case "right":
|
|
6863
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
6864
|
+
break;
|
|
6865
|
+
case "space":
|
|
6866
|
+
this.toggleValue();
|
|
6867
|
+
break;
|
|
6868
|
+
}
|
|
6869
|
+
});
|
|
6870
|
+
}
|
|
6871
|
+
get _value() {
|
|
6872
|
+
return this.options[this.cursor].value;
|
|
6873
|
+
}
|
|
6874
|
+
toggleAll() {
|
|
6875
|
+
const t = this.value.length === this.options.length;
|
|
6876
|
+
this.value = t ? [] : this.options.map((F) => F.value);
|
|
6877
|
+
}
|
|
6878
|
+
toggleValue() {
|
|
6879
|
+
const t = this.value.includes(this._value);
|
|
6880
|
+
this.value = t ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
|
|
6881
|
+
}
|
|
6882
|
+
};
|
|
6883
|
+
var u$1 = Object.defineProperty;
|
|
6884
|
+
var n$1 = (C, t, F) => (t in C) ? u$1(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6885
|
+
var e = (C, t, F) => (n$1(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6886
|
+
|
|
6887
|
+
class m extends k {
|
|
6888
|
+
constructor({ mask: t, ...F }) {
|
|
6889
|
+
super(F), e(this, "valueWithCursor", ""), e(this, "_mask", "•"), this._mask = t ?? "•", this.on("finalize", () => {
|
|
6890
|
+
this.valueWithCursor = this.masked;
|
|
6891
|
+
}), this.on("value", () => {
|
|
6892
|
+
if (this.cursor >= this.value.length)
|
|
6893
|
+
this.valueWithCursor = `${this.masked}${i__default.inverse(i__default.hidden("_"))}`;
|
|
6894
|
+
else {
|
|
6895
|
+
const E = this.masked.slice(0, this.cursor), B = this.masked.slice(this.cursor);
|
|
6896
|
+
this.valueWithCursor = `${E}${i__default.inverse(B[0])}${B.slice(1)}`;
|
|
6897
|
+
}
|
|
6898
|
+
});
|
|
6899
|
+
}
|
|
6900
|
+
get cursor() {
|
|
6901
|
+
return this._cursor;
|
|
6902
|
+
}
|
|
6903
|
+
get masked() {
|
|
6904
|
+
return this.value.replaceAll(/./g, this._mask);
|
|
6905
|
+
}
|
|
6906
|
+
}
|
|
6907
|
+
var o$1 = Object.defineProperty;
|
|
6908
|
+
var n = (C, t, F) => (t in C) ? o$1(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6909
|
+
var r = (C, t, F) => (n(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6910
|
+
|
|
6911
|
+
class u extends k {
|
|
6912
|
+
constructor(t) {
|
|
6913
|
+
super(t, false), r(this, "options"), r(this, "cursor", 0), this.options = t.options, this.cursor = this.options.findIndex(({ value: F }) => F === t.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (F) => {
|
|
6914
|
+
switch (F) {
|
|
6915
|
+
case "left":
|
|
6916
|
+
case "up":
|
|
6917
|
+
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
6918
|
+
break;
|
|
6919
|
+
case "down":
|
|
6920
|
+
case "right":
|
|
6921
|
+
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
6922
|
+
break;
|
|
6923
|
+
}
|
|
6924
|
+
this.changeValue();
|
|
6925
|
+
});
|
|
6926
|
+
}
|
|
6927
|
+
get _value() {
|
|
6928
|
+
return this.options[this.cursor];
|
|
6929
|
+
}
|
|
6930
|
+
changeValue() {
|
|
6931
|
+
this.value = this._value.value;
|
|
6932
|
+
}
|
|
6933
|
+
}
|
|
6934
|
+
var p = Object.defineProperty;
|
|
6935
|
+
var l = (C, t, F) => (t in C) ? p(C, t, { enumerable: true, configurable: true, writable: true, value: F }) : C[t] = F;
|
|
6936
|
+
var i = (C, t, F) => (l(C, typeof t != "symbol" ? t + "" : t, F), F);
|
|
6937
|
+
|
|
6938
|
+
class c extends k {
|
|
6939
|
+
constructor(t) {
|
|
6940
|
+
super(t, false), i(this, "options"), i(this, "cursor", 0), this.options = t.options;
|
|
6941
|
+
const F = this.options.map(({ value: [E] }) => E?.toLowerCase());
|
|
6942
|
+
this.cursor = Math.max(F.indexOf(t.initialValue), 0), this.on("key", (E) => {
|
|
6943
|
+
if (!F.includes(E))
|
|
6944
|
+
return;
|
|
6945
|
+
const B = this.options.find(({ value: [A] }) => A?.toLowerCase() === E);
|
|
6946
|
+
B && (this.value = B.value, this.state = "submit", this.emit("submit"));
|
|
6947
|
+
});
|
|
6948
|
+
}
|
|
6949
|
+
}
|
|
6950
|
+
|
|
6951
|
+
class o extends k {
|
|
6952
|
+
get valueWithCursor() {
|
|
6953
|
+
if (this.state === "submit")
|
|
6954
|
+
return this.value;
|
|
6955
|
+
if (this.cursor >= this.value.length)
|
|
6956
|
+
return `${this.value}█`;
|
|
6957
|
+
const t = this.value.slice(0, this.cursor), [F, ...E] = this.value.slice(this.cursor);
|
|
6958
|
+
return `${t}${i__default.inverse(F)}${E.join("")}`;
|
|
6959
|
+
}
|
|
6960
|
+
get cursor() {
|
|
6961
|
+
return this._cursor;
|
|
6962
|
+
}
|
|
6963
|
+
constructor(t) {
|
|
6964
|
+
super(t), this.on("finalize", () => {
|
|
6965
|
+
this.value || (this.value = t.defaultValue);
|
|
6966
|
+
});
|
|
6967
|
+
}
|
|
6968
|
+
}
|
|
6969
|
+
exports.ConfirmPrompt = s, exports.GroupMultiSelectPrompt = m$1, exports.MultiSelectPrompt = u$2, exports.PasswordPrompt = m, exports.Prompt = k, exports.SelectKeyPrompt = c, exports.SelectPrompt = u, exports.TextPrompt = o, exports.block = block, exports.isCancel = isCancel, exports.updateSettings = updateSettings;
|
|
6970
|
+
});
|
|
6971
|
+
|
|
6972
|
+
// node_modules/@clack/prompts/dist/index.cjs
|
|
6973
|
+
var require_dist2 = __commonJS((exports) => {
|
|
6974
|
+
var node_util = __require("node:util");
|
|
6975
|
+
var core = require_dist();
|
|
6976
|
+
var process$1 = __require("node:process");
|
|
6977
|
+
var e = require_picocolors();
|
|
6978
|
+
var sisteransi = require_src();
|
|
6979
|
+
function _interopDefaultCompat(t) {
|
|
6980
|
+
return t && typeof t == "object" && "default" in t ? t.default : t;
|
|
6981
|
+
}
|
|
6982
|
+
var process__default = _interopDefaultCompat(process$1);
|
|
6983
|
+
var e__default = _interopDefaultCompat(e);
|
|
6984
|
+
function isUnicodeSupported() {
|
|
6985
|
+
return process__default.platform !== "win32" ? process__default.env.TERM !== "linux" : !!process__default.env.CI || !!process__default.env.WT_SESSION || !!process__default.env.TERMINUS_SUBLIME || process__default.env.ConEmuTask === "{cmd::Cmder}" || process__default.env.TERM_PROGRAM === "Terminus-Sublime" || process__default.env.TERM_PROGRAM === "vscode" || process__default.env.TERM === "xterm-256color" || process__default.env.TERM === "alacritty" || process__default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
6986
|
+
}
|
|
6987
|
+
var P = isUnicodeSupported();
|
|
6988
|
+
var u = (t, o) => P ? t : o;
|
|
6989
|
+
var ie = u("◆", "*");
|
|
6990
|
+
var G = u("■", "x");
|
|
6991
|
+
var L = u("▲", "x");
|
|
6992
|
+
var S = u("◇", "o");
|
|
6993
|
+
var ae = u("┌", "T");
|
|
6994
|
+
var a = u("│", "|");
|
|
6995
|
+
var g = u("└", "—");
|
|
6996
|
+
var _ = u("●", ">");
|
|
6997
|
+
var A = u("○", " ");
|
|
6998
|
+
var C = u("◻", "[•]");
|
|
6999
|
+
var V = u("◼", "[+]");
|
|
7000
|
+
var N = u("◻", "[ ]");
|
|
7001
|
+
var oe = u("▪", "•");
|
|
7002
|
+
var j = u("─", "-");
|
|
7003
|
+
var le = u("╮", "+");
|
|
7004
|
+
var ce = u("├", "+");
|
|
7005
|
+
var ue = u("╯", "+");
|
|
7006
|
+
var B = u("●", "•");
|
|
7007
|
+
var W = u("◆", "*");
|
|
7008
|
+
var H = u("▲", "!");
|
|
7009
|
+
var q = u("■", "x");
|
|
7010
|
+
var b = (t) => {
|
|
7011
|
+
switch (t) {
|
|
7012
|
+
case "initial":
|
|
7013
|
+
case "active":
|
|
7014
|
+
return e__default.cyan(ie);
|
|
7015
|
+
case "cancel":
|
|
7016
|
+
return e__default.red(G);
|
|
7017
|
+
case "error":
|
|
7018
|
+
return e__default.yellow(L);
|
|
7019
|
+
case "submit":
|
|
7020
|
+
return e__default.green(S);
|
|
7021
|
+
}
|
|
7022
|
+
};
|
|
7023
|
+
var E = (t) => {
|
|
7024
|
+
const { cursor: o, options: s, style: i } = t, r = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), n = Math.min(c, Math.max(r, 5));
|
|
7025
|
+
let l = 0;
|
|
7026
|
+
o >= l + n - 3 ? l = Math.max(Math.min(o - n + 3, s.length - n), 0) : o < l + 2 && (l = Math.max(o - 2, 0));
|
|
7027
|
+
const $ = n < s.length && l > 0, h = n < s.length && l + n < s.length;
|
|
7028
|
+
return s.slice(l, l + n).map((m, y, w) => {
|
|
7029
|
+
const x = y === 0 && $, M = y === w.length - 1 && h;
|
|
7030
|
+
return x || M ? e__default.dim("...") : i(m, y + l === o);
|
|
7031
|
+
});
|
|
7032
|
+
};
|
|
7033
|
+
var text = (t) => new core.TextPrompt({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
7034
|
+
const o = `${e__default.gray(a)}
|
|
7035
|
+
${b(this.state)} ${t.message}
|
|
7036
|
+
`, s = t.placeholder ? e__default.inverse(t.placeholder[0]) + e__default.dim(t.placeholder.slice(1)) : e__default.inverse(e__default.hidden("_")), i = this.value ? this.valueWithCursor : s;
|
|
7037
|
+
switch (this.state) {
|
|
7038
|
+
case "error":
|
|
7039
|
+
return `${o.trim()}
|
|
7040
|
+
${e__default.yellow(a)} ${i}
|
|
7041
|
+
${e__default.yellow(g)} ${e__default.yellow(this.error)}
|
|
7042
|
+
`;
|
|
7043
|
+
case "submit":
|
|
7044
|
+
return `${o}${e__default.gray(a)} ${e__default.dim(this.value || t.placeholder)}`;
|
|
7045
|
+
case "cancel":
|
|
7046
|
+
return `${o}${e__default.gray(a)} ${e__default.strikethrough(e__default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
|
7047
|
+
${e__default.gray(a)}` : ""}`;
|
|
7048
|
+
default:
|
|
7049
|
+
return `${o}${e__default.cyan(a)} ${i}
|
|
7050
|
+
${e__default.cyan(g)}
|
|
7051
|
+
`;
|
|
7052
|
+
}
|
|
7053
|
+
} }).prompt();
|
|
7054
|
+
var password = (t) => new core.PasswordPrompt({ validate: t.validate, mask: t.mask ?? oe, render() {
|
|
7055
|
+
const o = `${e__default.gray(a)}
|
|
7056
|
+
${b(this.state)} ${t.message}
|
|
7057
|
+
`, s = this.valueWithCursor, i = this.masked;
|
|
7058
|
+
switch (this.state) {
|
|
7059
|
+
case "error":
|
|
7060
|
+
return `${o.trim()}
|
|
7061
|
+
${e__default.yellow(a)} ${i}
|
|
7062
|
+
${e__default.yellow(g)} ${e__default.yellow(this.error)}
|
|
7063
|
+
`;
|
|
7064
|
+
case "submit":
|
|
7065
|
+
return `${o}${e__default.gray(a)} ${e__default.dim(i)}`;
|
|
7066
|
+
case "cancel":
|
|
7067
|
+
return `${o}${e__default.gray(a)} ${e__default.strikethrough(e__default.dim(i ?? ""))}${i ? `
|
|
7068
|
+
${e__default.gray(a)}` : ""}`;
|
|
7069
|
+
default:
|
|
7070
|
+
return `${o}${e__default.cyan(a)} ${s}
|
|
7071
|
+
${e__default.cyan(g)}
|
|
7072
|
+
`;
|
|
7073
|
+
}
|
|
7074
|
+
} }).prompt();
|
|
7075
|
+
var confirm = (t) => {
|
|
7076
|
+
const o = t.active ?? "Yes", s = t.inactive ?? "No";
|
|
7077
|
+
return new core.ConfirmPrompt({ active: o, inactive: s, initialValue: t.initialValue ?? true, render() {
|
|
7078
|
+
const i = `${e__default.gray(a)}
|
|
7079
|
+
${b(this.state)} ${t.message}
|
|
7080
|
+
`, r = this.value ? o : s;
|
|
7081
|
+
switch (this.state) {
|
|
7082
|
+
case "submit":
|
|
7083
|
+
return `${i}${e__default.gray(a)} ${e__default.dim(r)}`;
|
|
7084
|
+
case "cancel":
|
|
7085
|
+
return `${i}${e__default.gray(a)} ${e__default.strikethrough(e__default.dim(r))}
|
|
7086
|
+
${e__default.gray(a)}`;
|
|
7087
|
+
default:
|
|
7088
|
+
return `${i}${e__default.cyan(a)} ${this.value ? `${e__default.green(_)} ${o}` : `${e__default.dim(A)} ${e__default.dim(o)}`} ${e__default.dim("/")} ${this.value ? `${e__default.dim(A)} ${e__default.dim(s)}` : `${e__default.green(_)} ${s}`}
|
|
7089
|
+
${e__default.cyan(g)}
|
|
7090
|
+
`;
|
|
7091
|
+
}
|
|
7092
|
+
} }).prompt();
|
|
7093
|
+
};
|
|
7094
|
+
var select = (t) => {
|
|
7095
|
+
const o = (s, i) => {
|
|
7096
|
+
const r = s.label ?? String(s.value);
|
|
7097
|
+
switch (i) {
|
|
7098
|
+
case "selected":
|
|
7099
|
+
return `${e__default.dim(r)}`;
|
|
7100
|
+
case "active":
|
|
7101
|
+
return `${e__default.green(_)} ${r} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}`;
|
|
7102
|
+
case "cancelled":
|
|
7103
|
+
return `${e__default.strikethrough(e__default.dim(r))}`;
|
|
7104
|
+
default:
|
|
7105
|
+
return `${e__default.dim(A)} ${e__default.dim(r)}`;
|
|
7106
|
+
}
|
|
7107
|
+
};
|
|
7108
|
+
return new core.SelectPrompt({ options: t.options, initialValue: t.initialValue, render() {
|
|
7109
|
+
const s = `${e__default.gray(a)}
|
|
7110
|
+
${b(this.state)} ${t.message}
|
|
7111
|
+
`;
|
|
7112
|
+
switch (this.state) {
|
|
7113
|
+
case "submit":
|
|
7114
|
+
return `${s}${e__default.gray(a)} ${o(this.options[this.cursor], "selected")}`;
|
|
7115
|
+
case "cancel":
|
|
7116
|
+
return `${s}${e__default.gray(a)} ${o(this.options[this.cursor], "cancelled")}
|
|
7117
|
+
${e__default.gray(a)}`;
|
|
7118
|
+
default:
|
|
7119
|
+
return `${s}${e__default.cyan(a)} ${E({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, r) => o(i, r ? "active" : "inactive") }).join(`
|
|
7120
|
+
${e__default.cyan(a)} `)}
|
|
7121
|
+
${e__default.cyan(g)}
|
|
7122
|
+
`;
|
|
7123
|
+
}
|
|
7124
|
+
} }).prompt();
|
|
7125
|
+
};
|
|
7126
|
+
var selectKey = (t) => {
|
|
7127
|
+
const o = (s, i = "inactive") => {
|
|
7128
|
+
const r = s.label ?? String(s.value);
|
|
7129
|
+
return i === "selected" ? `${e__default.dim(r)}` : i === "cancelled" ? `${e__default.strikethrough(e__default.dim(r))}` : i === "active" ? `${e__default.bgCyan(e__default.gray(` ${s.value} `))} ${r} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}` : `${e__default.gray(e__default.bgWhite(e__default.inverse(` ${s.value} `)))} ${r} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}`;
|
|
7130
|
+
};
|
|
7131
|
+
return new core.SelectKeyPrompt({ options: t.options, initialValue: t.initialValue, render() {
|
|
7132
|
+
const s = `${e__default.gray(a)}
|
|
7133
|
+
${b(this.state)} ${t.message}
|
|
7134
|
+
`;
|
|
7135
|
+
switch (this.state) {
|
|
7136
|
+
case "submit":
|
|
7137
|
+
return `${s}${e__default.gray(a)} ${o(this.options.find((i) => i.value === this.value) ?? t.options[0], "selected")}`;
|
|
7138
|
+
case "cancel":
|
|
7139
|
+
return `${s}${e__default.gray(a)} ${o(this.options[0], "cancelled")}
|
|
7140
|
+
${e__default.gray(a)}`;
|
|
7141
|
+
default:
|
|
7142
|
+
return `${s}${e__default.cyan(a)} ${this.options.map((i, r) => o(i, r === this.cursor ? "active" : "inactive")).join(`
|
|
7143
|
+
${e__default.cyan(a)} `)}
|
|
7144
|
+
${e__default.cyan(g)}
|
|
7145
|
+
`;
|
|
7146
|
+
}
|
|
7147
|
+
} }).prompt();
|
|
7148
|
+
};
|
|
7149
|
+
var multiselect = (t) => {
|
|
7150
|
+
const o = (s, i) => {
|
|
7151
|
+
const r = s.label ?? String(s.value);
|
|
7152
|
+
return i === "active" ? `${e__default.cyan(C)} ${r} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}` : i === "selected" ? `${e__default.green(V)} ${e__default.dim(r)} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}` : i === "cancelled" ? `${e__default.strikethrough(e__default.dim(r))}` : i === "active-selected" ? `${e__default.green(V)} ${r} ${s.hint ? e__default.dim(`(${s.hint})`) : ""}` : i === "submitted" ? `${e__default.dim(r)}` : `${e__default.dim(N)} ${e__default.dim(r)}`;
|
|
7153
|
+
};
|
|
7154
|
+
return new core.MultiSelectPrompt({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(s) {
|
|
7155
|
+
if (this.required && s.length === 0)
|
|
7156
|
+
return `Please select at least one option.
|
|
7157
|
+
${e__default.reset(e__default.dim(`Press ${e__default.gray(e__default.bgWhite(e__default.inverse(" space ")))} to select, ${e__default.gray(e__default.bgWhite(e__default.inverse(" enter ")))} to submit`))}`;
|
|
7158
|
+
}, render() {
|
|
7159
|
+
const s = `${e__default.gray(a)}
|
|
7160
|
+
${b(this.state)} ${t.message}
|
|
7161
|
+
`, i = (r, c) => {
|
|
7162
|
+
const n = this.value.includes(r.value);
|
|
7163
|
+
return c && n ? o(r, "active-selected") : n ? o(r, "selected") : o(r, c ? "active" : "inactive");
|
|
7164
|
+
};
|
|
7165
|
+
switch (this.state) {
|
|
7166
|
+
case "submit":
|
|
7167
|
+
return `${s}${e__default.gray(a)} ${this.options.filter(({ value: r }) => this.value.includes(r)).map((r) => o(r, "submitted")).join(e__default.dim(", ")) || e__default.dim("none")}`;
|
|
7168
|
+
case "cancel": {
|
|
7169
|
+
const r = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => o(c, "cancelled")).join(e__default.dim(", "));
|
|
7170
|
+
return `${s}${e__default.gray(a)} ${r.trim() ? `${r}
|
|
7171
|
+
${e__default.gray(a)}` : ""}`;
|
|
7172
|
+
}
|
|
7173
|
+
case "error": {
|
|
7174
|
+
const r = this.error.split(`
|
|
7175
|
+
`).map((c, n) => n === 0 ? `${e__default.yellow(g)} ${e__default.yellow(c)}` : ` ${c}`).join(`
|
|
7176
|
+
`);
|
|
7177
|
+
return `${s + e__default.yellow(a)} ${E({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
7178
|
+
${e__default.yellow(a)} `)}
|
|
7179
|
+
${r}
|
|
7180
|
+
`;
|
|
7181
|
+
}
|
|
7182
|
+
default:
|
|
7183
|
+
return `${s}${e__default.cyan(a)} ${E({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
|
|
7184
|
+
${e__default.cyan(a)} `)}
|
|
7185
|
+
${e__default.cyan(g)}
|
|
7186
|
+
`;
|
|
7187
|
+
}
|
|
7188
|
+
} }).prompt();
|
|
7189
|
+
};
|
|
7190
|
+
var groupMultiselect = (t) => {
|
|
7191
|
+
const { selectableGroups: o = true } = t, s = (i, r, c = []) => {
|
|
7192
|
+
const n = i.label ?? String(i.value), l = typeof i.group == "string", $ = l && (c[c.indexOf(i) + 1] ?? { group: true }), h = l && $.group === true, m = l ? o ? `${h ? g : a} ` : " " : "";
|
|
7193
|
+
if (r === "active")
|
|
7194
|
+
return `${e__default.dim(m)}${e__default.cyan(C)} ${n} ${i.hint ? e__default.dim(`(${i.hint})`) : ""}`;
|
|
7195
|
+
if (r === "group-active")
|
|
7196
|
+
return `${m}${e__default.cyan(C)} ${e__default.dim(n)}`;
|
|
7197
|
+
if (r === "group-active-selected")
|
|
7198
|
+
return `${m}${e__default.green(V)} ${e__default.dim(n)}`;
|
|
7199
|
+
if (r === "selected") {
|
|
7200
|
+
const w = l || o ? e__default.green(V) : "";
|
|
7201
|
+
return `${e__default.dim(m)}${w} ${e__default.dim(n)} ${i.hint ? e__default.dim(`(${i.hint})`) : ""}`;
|
|
7202
|
+
}
|
|
7203
|
+
if (r === "cancelled")
|
|
7204
|
+
return `${e__default.strikethrough(e__default.dim(n))}`;
|
|
7205
|
+
if (r === "active-selected")
|
|
7206
|
+
return `${e__default.dim(m)}${e__default.green(V)} ${n} ${i.hint ? e__default.dim(`(${i.hint})`) : ""}`;
|
|
7207
|
+
if (r === "submitted")
|
|
7208
|
+
return `${e__default.dim(n)}`;
|
|
7209
|
+
const y = l || o ? e__default.dim(N) : "";
|
|
7210
|
+
return `${e__default.dim(m)}${y} ${e__default.dim(n)}`;
|
|
7211
|
+
};
|
|
7212
|
+
return new core.GroupMultiSelectPrompt({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, selectableGroups: o, validate(i) {
|
|
7213
|
+
if (this.required && i.length === 0)
|
|
7214
|
+
return `Please select at least one option.
|
|
7215
|
+
${e__default.reset(e__default.dim(`Press ${e__default.gray(e__default.bgWhite(e__default.inverse(" space ")))} to select, ${e__default.gray(e__default.bgWhite(e__default.inverse(" enter ")))} to submit`))}`;
|
|
7216
|
+
}, render() {
|
|
7217
|
+
const i = `${e__default.gray(a)}
|
|
7218
|
+
${b(this.state)} ${t.message}
|
|
7219
|
+
`;
|
|
7220
|
+
switch (this.state) {
|
|
7221
|
+
case "submit":
|
|
7222
|
+
return `${i}${e__default.gray(a)} ${this.options.filter(({ value: r }) => this.value.includes(r)).map((r) => s(r, "submitted")).join(e__default.dim(", "))}`;
|
|
7223
|
+
case "cancel": {
|
|
7224
|
+
const r = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => s(c, "cancelled")).join(e__default.dim(", "));
|
|
7225
|
+
return `${i}${e__default.gray(a)} ${r.trim() ? `${r}
|
|
7226
|
+
${e__default.gray(a)}` : ""}`;
|
|
7227
|
+
}
|
|
7228
|
+
case "error": {
|
|
7229
|
+
const r = this.error.split(`
|
|
7230
|
+
`).map((c, n) => n === 0 ? `${e__default.yellow(g)} ${e__default.yellow(c)}` : ` ${c}`).join(`
|
|
7231
|
+
`);
|
|
7232
|
+
return `${i}${e__default.yellow(a)} ${this.options.map((c, n, l) => {
|
|
7233
|
+
const $ = this.value.includes(c.value) || c.group === true && this.isGroupSelected(`${c.value}`), h = n === this.cursor;
|
|
7234
|
+
return !h && typeof c.group == "string" && this.options[this.cursor].value === c.group ? s(c, $ ? "group-active-selected" : "group-active", l) : h && $ ? s(c, "active-selected", l) : $ ? s(c, "selected", l) : s(c, h ? "active" : "inactive", l);
|
|
7235
|
+
}).join(`
|
|
7236
|
+
${e__default.yellow(a)} `)}
|
|
7237
|
+
${r}
|
|
7238
|
+
`;
|
|
7239
|
+
}
|
|
7240
|
+
default:
|
|
7241
|
+
return `${i}${e__default.cyan(a)} ${this.options.map((r, c, n) => {
|
|
7242
|
+
const l = this.value.includes(r.value) || r.group === true && this.isGroupSelected(`${r.value}`), $ = c === this.cursor;
|
|
7243
|
+
return !$ && typeof r.group == "string" && this.options[this.cursor].value === r.group ? s(r, l ? "group-active-selected" : "group-active", n) : $ && l ? s(r, "active-selected", n) : l ? s(r, "selected", n) : s(r, $ ? "active" : "inactive", n);
|
|
7244
|
+
}).join(`
|
|
7245
|
+
${e__default.cyan(a)} `)}
|
|
7246
|
+
${e__default.cyan(g)}
|
|
7247
|
+
`;
|
|
7248
|
+
}
|
|
7249
|
+
} }).prompt();
|
|
7250
|
+
};
|
|
7251
|
+
var note = (t = "", o = "") => {
|
|
7252
|
+
const s = `
|
|
7253
|
+
${t}
|
|
7254
|
+
`.split(`
|
|
7255
|
+
`), i = node_util.stripVTControlCharacters(o).length, r = Math.max(s.reduce((n, l) => {
|
|
7256
|
+
const $ = node_util.stripVTControlCharacters(l);
|
|
7257
|
+
return $.length > n ? $.length : n;
|
|
7258
|
+
}, 0), i) + 2, c = s.map((n) => `${e__default.gray(a)} ${e__default.dim(n)}${" ".repeat(r - node_util.stripVTControlCharacters(n).length)}${e__default.gray(a)}`).join(`
|
|
7259
|
+
`);
|
|
7260
|
+
process.stdout.write(`${e__default.gray(a)}
|
|
7261
|
+
${e__default.green(S)} ${e__default.reset(o)} ${e__default.gray(j.repeat(Math.max(r - i - 1, 1)) + le)}
|
|
7262
|
+
${c}
|
|
7263
|
+
${e__default.gray(ce + j.repeat(r + 2) + ue)}
|
|
7264
|
+
`);
|
|
7265
|
+
};
|
|
7266
|
+
var cancel = (t = "") => {
|
|
7267
|
+
process.stdout.write(`${e__default.gray(g)} ${e__default.red(t)}
|
|
7268
|
+
|
|
7269
|
+
`);
|
|
7270
|
+
};
|
|
7271
|
+
var intro = (t = "") => {
|
|
7272
|
+
process.stdout.write(`${e__default.gray(ae)} ${t}
|
|
7273
|
+
`);
|
|
7274
|
+
};
|
|
7275
|
+
var outro = (t = "") => {
|
|
7276
|
+
process.stdout.write(`${e__default.gray(a)}
|
|
7277
|
+
${e__default.gray(g)} ${t}
|
|
7278
|
+
|
|
7279
|
+
`);
|
|
7280
|
+
};
|
|
7281
|
+
var log = { message: (t = "", { symbol: o = e__default.gray(a) } = {}) => {
|
|
7282
|
+
const s = [`${e__default.gray(a)}`];
|
|
7283
|
+
if (t) {
|
|
7284
|
+
const [i, ...r] = t.split(`
|
|
7285
|
+
`);
|
|
7286
|
+
s.push(`${o} ${i}`, ...r.map((c) => `${e__default.gray(a)} ${c}`));
|
|
7287
|
+
}
|
|
7288
|
+
process.stdout.write(`${s.join(`
|
|
7289
|
+
`)}
|
|
7290
|
+
`);
|
|
7291
|
+
}, info: (t) => {
|
|
7292
|
+
log.message(t, { symbol: e__default.blue(B) });
|
|
7293
|
+
}, success: (t) => {
|
|
7294
|
+
log.message(t, { symbol: e__default.green(W) });
|
|
7295
|
+
}, step: (t) => {
|
|
7296
|
+
log.message(t, { symbol: e__default.green(S) });
|
|
7297
|
+
}, warn: (t) => {
|
|
7298
|
+
log.message(t, { symbol: e__default.yellow(H) });
|
|
7299
|
+
}, warning: (t) => {
|
|
7300
|
+
log.warn(t);
|
|
7301
|
+
}, error: (t) => {
|
|
7302
|
+
log.message(t, { symbol: e__default.red(q) });
|
|
7303
|
+
} };
|
|
7304
|
+
var D = `${e__default.gray(a)} `;
|
|
7305
|
+
var stream = { message: async (t, { symbol: o = e__default.gray(a) } = {}) => {
|
|
7306
|
+
process.stdout.write(`${e__default.gray(a)}
|
|
7307
|
+
${o} `);
|
|
7308
|
+
let s = 3;
|
|
7309
|
+
for await (let i of t) {
|
|
7310
|
+
i = i.replace(/\n/g, `
|
|
7311
|
+
${D}`), i.includes(`
|
|
7312
|
+
`) && (s = 3 + node_util.stripVTControlCharacters(i.slice(i.lastIndexOf(`
|
|
7313
|
+
`))).length);
|
|
7314
|
+
const r = node_util.stripVTControlCharacters(i).length;
|
|
7315
|
+
s + r < process.stdout.columns ? (s += r, process.stdout.write(i)) : (process.stdout.write(`
|
|
7316
|
+
${D}${i.trimStart()}`), s = 3 + node_util.stripVTControlCharacters(i.trimStart()).length);
|
|
7317
|
+
}
|
|
7318
|
+
process.stdout.write(`
|
|
7319
|
+
`);
|
|
7320
|
+
}, info: (t) => stream.message(t, { symbol: e__default.blue(B) }), success: (t) => stream.message(t, { symbol: e__default.green(W) }), step: (t) => stream.message(t, { symbol: e__default.green(S) }), warn: (t) => stream.message(t, { symbol: e__default.yellow(H) }), warning: (t) => stream.warn(t), error: (t) => stream.message(t, { symbol: e__default.red(q) }) };
|
|
7321
|
+
var spinner = ({ indicator: t = "dots" } = {}) => {
|
|
7322
|
+
const o = P ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], s = P ? 80 : 120, i = process.env.CI === "true";
|
|
7323
|
+
let r, c, n = false, l = "", $, h = performance.now();
|
|
7324
|
+
const m = (p) => {
|
|
7325
|
+
const d = p > 1 ? "Something went wrong" : "Canceled";
|
|
7326
|
+
n && R(d, p);
|
|
7327
|
+
}, y = () => m(2), w = () => m(1), x = () => {
|
|
7328
|
+
process.on("uncaughtExceptionMonitor", y), process.on("unhandledRejection", y), process.on("SIGINT", w), process.on("SIGTERM", w), process.on("exit", m);
|
|
7329
|
+
}, M = () => {
|
|
7330
|
+
process.removeListener("uncaughtExceptionMonitor", y), process.removeListener("unhandledRejection", y), process.removeListener("SIGINT", w), process.removeListener("SIGTERM", w), process.removeListener("exit", m);
|
|
7331
|
+
}, T = () => {
|
|
7332
|
+
if ($ === undefined)
|
|
7333
|
+
return;
|
|
7334
|
+
i && process.stdout.write(`
|
|
7335
|
+
`);
|
|
7336
|
+
const p = $.split(`
|
|
7337
|
+
`);
|
|
7338
|
+
process.stdout.write(sisteransi.cursor.move(-999, p.length - 1)), process.stdout.write(sisteransi.erase.down(p.length));
|
|
7339
|
+
}, I = (p) => p.replace(/\.+$/, ""), k = (p) => {
|
|
7340
|
+
const d = (performance.now() - p) / 1000, v = Math.floor(d / 60), f = Math.floor(d % 60);
|
|
7341
|
+
return v > 0 ? `[${v}m ${f}s]` : `[${f}s]`;
|
|
7342
|
+
}, O = (p = "") => {
|
|
7343
|
+
n = true, r = core.block(), l = I(p), h = performance.now(), process.stdout.write(`${e__default.gray(a)}
|
|
7344
|
+
`);
|
|
7345
|
+
let d = 0, v = 0;
|
|
7346
|
+
x(), c = setInterval(() => {
|
|
7347
|
+
if (i && l === $)
|
|
7348
|
+
return;
|
|
7349
|
+
T(), $ = l;
|
|
7350
|
+
const f = e__default.magenta(o[d]);
|
|
7351
|
+
if (i)
|
|
7352
|
+
process.stdout.write(`${f} ${l}...`);
|
|
7353
|
+
else if (t === "timer")
|
|
7354
|
+
process.stdout.write(`${f} ${l} ${k(h)}`);
|
|
7355
|
+
else {
|
|
7356
|
+
const F = ".".repeat(Math.floor(v)).slice(0, 3);
|
|
7357
|
+
process.stdout.write(`${f} ${l}${F}`);
|
|
7358
|
+
}
|
|
7359
|
+
d = d + 1 < o.length ? d + 1 : 0, v = v < o.length ? v + 0.125 : 0;
|
|
7360
|
+
}, s);
|
|
7361
|
+
}, R = (p = "", d = 0) => {
|
|
7362
|
+
n = false, clearInterval(c), T();
|
|
7363
|
+
const v = d === 0 ? e__default.green(S) : d === 1 ? e__default.red(G) : e__default.red(L);
|
|
7364
|
+
l = I(p ?? l), t === "timer" ? process.stdout.write(`${v} ${l} ${k(h)}
|
|
7365
|
+
`) : process.stdout.write(`${v} ${l}
|
|
7366
|
+
`), M(), r();
|
|
7367
|
+
};
|
|
7368
|
+
return { start: O, stop: R, message: (p = "") => {
|
|
7369
|
+
l = I(p ?? l);
|
|
7370
|
+
} };
|
|
7371
|
+
};
|
|
7372
|
+
var group = async (t, o) => {
|
|
7373
|
+
const s = {}, i = Object.keys(t);
|
|
7374
|
+
for (const r of i) {
|
|
7375
|
+
const c = t[r], n = await c({ results: s })?.catch((l) => {
|
|
7376
|
+
throw l;
|
|
7377
|
+
});
|
|
7378
|
+
if (typeof o?.onCancel == "function" && core.isCancel(n)) {
|
|
7379
|
+
s[r] = "canceled", o.onCancel({ results: s });
|
|
7380
|
+
continue;
|
|
7381
|
+
}
|
|
7382
|
+
s[r] = n;
|
|
7383
|
+
}
|
|
7384
|
+
return s;
|
|
7385
|
+
};
|
|
7386
|
+
var tasks = async (t) => {
|
|
7387
|
+
for (const o of t) {
|
|
7388
|
+
if (o.enabled === false)
|
|
7389
|
+
continue;
|
|
7390
|
+
const s = spinner();
|
|
7391
|
+
s.start(o.title);
|
|
7392
|
+
const i = await o.task(s.message);
|
|
7393
|
+
s.stop(i || o.title);
|
|
7394
|
+
}
|
|
7395
|
+
};
|
|
7396
|
+
exports.isCancel = core.isCancel, exports.updateSettings = core.updateSettings, exports.cancel = cancel, exports.confirm = confirm, exports.group = group, exports.groupMultiselect = groupMultiselect, exports.intro = intro, exports.log = log, exports.multiselect = multiselect, exports.note = note, exports.outro = outro, exports.password = password, exports.select = select, exports.selectKey = selectKey, exports.spinner = spinner, exports.stream = stream, exports.tasks = tasks, exports.text = text;
|
|
7397
|
+
});
|
|
7398
|
+
|
|
6197
7399
|
// node_modules/dotenv/package.json
|
|
6198
7400
|
var require_package = __commonJS((exports, module) => {
|
|
6199
7401
|
module.exports = {
|
|
@@ -6527,6 +7729,194 @@ var require_main = __commonJS((exports, module) => {
|
|
|
6527
7729
|
module.exports = DotenvModule;
|
|
6528
7730
|
});
|
|
6529
7731
|
|
|
7732
|
+
// src/utils/env-loader.ts
|
|
7733
|
+
var exports_env_loader = {};
|
|
7734
|
+
__export(exports_env_loader, {
|
|
7735
|
+
validateRequiredEnvironmentVariables: () => validateRequiredEnvironmentVariables,
|
|
7736
|
+
resolveToolEnvironmentVariables: () => resolveToolEnvironmentVariables,
|
|
7737
|
+
loadPackageEnvironmentVariables: () => loadPackageEnvironmentVariables,
|
|
7738
|
+
getWebServerUrl: () => getWebServerUrl,
|
|
7739
|
+
getPackageEnvironmentVariables: () => getPackageEnvironmentVariables,
|
|
7740
|
+
generateConfigLink: () => generateConfigLink,
|
|
7741
|
+
extractPackageNamespace: () => extractPackageNamespace
|
|
7742
|
+
});
|
|
7743
|
+
import { join } from "path";
|
|
7744
|
+
import { homedir } from "os";
|
|
7745
|
+
import { existsSync } from "fs";
|
|
7746
|
+
import { readFile } from "fs/promises";
|
|
7747
|
+
function extractPackageNamespace(toolName) {
|
|
7748
|
+
const parts = toolName.split("/");
|
|
7749
|
+
if (parts.length < 2) {
|
|
7750
|
+
throw new Error('Tool name must be in format "org/package" or "org/package/tool"');
|
|
7751
|
+
}
|
|
7752
|
+
if (parts.length >= 2) {
|
|
7753
|
+
return parts.slice(0, -1).join("/");
|
|
7754
|
+
}
|
|
7755
|
+
return parts[0];
|
|
7756
|
+
}
|
|
7757
|
+
function getPackageEnvPath(packageNamespace) {
|
|
7758
|
+
return join(CONFIG_DIR, "env", packageNamespace, ".env");
|
|
7759
|
+
}
|
|
7760
|
+
function decryptValue(encryptedValue) {
|
|
7761
|
+
try {
|
|
7762
|
+
return Buffer.from(encryptedValue, "base64").toString("utf8");
|
|
7763
|
+
} catch {
|
|
7764
|
+
return encryptedValue;
|
|
7765
|
+
}
|
|
7766
|
+
}
|
|
7767
|
+
async function readPackageEnvConfig(packageNamespace) {
|
|
7768
|
+
const envFile = getPackageEnvPath(packageNamespace);
|
|
7769
|
+
if (!existsSync(envFile)) {
|
|
7770
|
+
return { variables: {} };
|
|
7771
|
+
}
|
|
7772
|
+
try {
|
|
7773
|
+
const data = await readFile(envFile, "utf8");
|
|
7774
|
+
if (data.trim().startsWith("{")) {
|
|
7775
|
+
return JSON.parse(data);
|
|
7776
|
+
} else {
|
|
7777
|
+
return { variables: {} };
|
|
7778
|
+
}
|
|
7779
|
+
} catch (error) {
|
|
7780
|
+
if (!error.message.includes("Unexpected token")) {
|
|
7781
|
+
console.warn(`Failed to read env config from ${envFile}: ${error.message}`);
|
|
7782
|
+
}
|
|
7783
|
+
return { variables: {} };
|
|
7784
|
+
}
|
|
7785
|
+
}
|
|
7786
|
+
async function loadPackageEnvironmentVariables(packageNamespace) {
|
|
7787
|
+
const config = await readPackageEnvConfig(packageNamespace);
|
|
7788
|
+
const envVars = {};
|
|
7789
|
+
for (const [name, envVar] of Object.entries(config.variables)) {
|
|
7790
|
+
const value = envVar.encrypted ? decryptValue(envVar.value) : envVar.value;
|
|
7791
|
+
envVars[name] = value;
|
|
7792
|
+
}
|
|
7793
|
+
return envVars;
|
|
7794
|
+
}
|
|
7795
|
+
function loadPackageEnvFile(toolName) {
|
|
7796
|
+
if (!toolName) {
|
|
7797
|
+
return {};
|
|
7798
|
+
}
|
|
7799
|
+
try {
|
|
7800
|
+
const packageNamespace = extractPackageNamespace(toolName);
|
|
7801
|
+
const packageEnvPath = getPackageEnvPath(packageNamespace);
|
|
7802
|
+
if (!existsSync(packageEnvPath)) {
|
|
7803
|
+
return {};
|
|
7804
|
+
}
|
|
7805
|
+
const result = import_dotenv.config({ path: packageEnvPath });
|
|
7806
|
+
return result.parsed || {};
|
|
7807
|
+
} catch (error) {
|
|
7808
|
+
console.warn(`Warning: Failed to load package .env file: ${error.message}`);
|
|
7809
|
+
return {};
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
async function resolveToolEnvironmentVariables(toolName, toolEnvConfig) {
|
|
7813
|
+
const resolved = { ...process.env };
|
|
7814
|
+
const packageEnvVars = loadPackageEnvFile(toolName);
|
|
7815
|
+
Object.assign(resolved, packageEnvVars);
|
|
7816
|
+
if (toolName) {
|
|
7817
|
+
try {
|
|
7818
|
+
const packageNamespace = extractPackageNamespace(toolName);
|
|
7819
|
+
const packageJsonEnvVars = await loadPackageEnvironmentVariables(packageNamespace);
|
|
7820
|
+
Object.assign(resolved, packageJsonEnvVars);
|
|
7821
|
+
} catch (error) {
|
|
7822
|
+
console.warn(`Warning: Could not load package environment variables: ${error.message}`);
|
|
7823
|
+
}
|
|
7824
|
+
}
|
|
7825
|
+
const missing = [];
|
|
7826
|
+
if (toolEnvConfig) {
|
|
7827
|
+
for (const [varName, config] of Object.entries(toolEnvConfig)) {
|
|
7828
|
+
if (typeof config === "object" && config !== null) {
|
|
7829
|
+
const isRequired = config.required === true;
|
|
7830
|
+
const defaultValue = config.default;
|
|
7831
|
+
const source = config.source;
|
|
7832
|
+
if (!(varName in resolved) || resolved[varName] === "") {
|
|
7833
|
+
if (defaultValue !== undefined) {
|
|
7834
|
+
resolved[varName] = String(defaultValue);
|
|
7835
|
+
} else if (isRequired) {
|
|
7836
|
+
missing.push(varName);
|
|
7837
|
+
}
|
|
7838
|
+
}
|
|
7839
|
+
if (source && resolved[varName]) {}
|
|
7840
|
+
}
|
|
7841
|
+
}
|
|
7842
|
+
}
|
|
7843
|
+
let configLink;
|
|
7844
|
+
if (missing.length > 0) {
|
|
7845
|
+
configLink = generateConfigLink(missing, toolName) || undefined;
|
|
7846
|
+
if (configLink) {
|
|
7847
|
+
console.log(`
|
|
7848
|
+
\uD83D\uDD27 Missing environment variables: ${missing.join(", ")}`);
|
|
7849
|
+
console.log(`\uD83D\uDCCB Configure them here: ${configLink}
|
|
7850
|
+
`);
|
|
7851
|
+
} else {
|
|
7852
|
+
console.log(`
|
|
7853
|
+
⚠️ Missing required environment variables: ${missing.join(", ")}`);
|
|
7854
|
+
console.log(`\uD83D\uDCA1 Set them using the 'enact env set' command or your system environment
|
|
7855
|
+
`);
|
|
7856
|
+
}
|
|
7857
|
+
}
|
|
7858
|
+
return { resolved, missing, configLink };
|
|
7859
|
+
}
|
|
7860
|
+
async function getPackageEnvironmentVariables(packageNamespace) {
|
|
7861
|
+
const packageConfig = await readPackageEnvConfig(packageNamespace);
|
|
7862
|
+
const packageVars = {};
|
|
7863
|
+
for (const [name, envVar] of Object.entries(packageConfig.variables)) {
|
|
7864
|
+
packageVars[name] = {
|
|
7865
|
+
value: envVar.encrypted ? "[encrypted]" : envVar.value,
|
|
7866
|
+
encrypted: envVar.encrypted || false,
|
|
7867
|
+
description: envVar.description
|
|
7868
|
+
};
|
|
7869
|
+
}
|
|
7870
|
+
const system = Object.fromEntries(Object.entries(process.env).filter(([key]) => key.includes("API") || key.includes("TOKEN") || key.includes("KEY") || key.includes("URL") || key.includes("HOST") || key.includes("PORT") || key.startsWith("ENACT_") || key.startsWith("NODE_") || key.startsWith("NPM_")).map(([key, value]) => [key, value || ""]));
|
|
7871
|
+
return { package: packageVars, system };
|
|
7872
|
+
}
|
|
7873
|
+
function validateRequiredEnvironmentVariables(toolEnvConfig, availableVars) {
|
|
7874
|
+
const missing = [];
|
|
7875
|
+
const errors2 = [];
|
|
7876
|
+
if (!toolEnvConfig) {
|
|
7877
|
+
return { valid: true, missing, errors: errors2 };
|
|
7878
|
+
}
|
|
7879
|
+
for (const [varName, config] of Object.entries(toolEnvConfig)) {
|
|
7880
|
+
if (typeof config === "object" && config !== null) {
|
|
7881
|
+
const isRequired = config.required === true;
|
|
7882
|
+
const hasDefault = config.default !== undefined;
|
|
7883
|
+
const description = config.description || "";
|
|
7884
|
+
const source = config.source || "";
|
|
7885
|
+
if (isRequired && !hasDefault && (!(varName in availableVars) || availableVars[varName] === "")) {
|
|
7886
|
+
missing.push(varName);
|
|
7887
|
+
const errorMsg = `Required environment variable '${varName}' is not set`;
|
|
7888
|
+
const detailMsg = description ? ` - ${description}` : "";
|
|
7889
|
+
const sourceMsg = source ? ` (source: ${source})` : "";
|
|
7890
|
+
errors2.push(`${errorMsg}${detailMsg}${sourceMsg}`);
|
|
7891
|
+
}
|
|
7892
|
+
}
|
|
7893
|
+
}
|
|
7894
|
+
return {
|
|
7895
|
+
valid: missing.length === 0,
|
|
7896
|
+
missing,
|
|
7897
|
+
errors: errors2
|
|
7898
|
+
};
|
|
7899
|
+
}
|
|
7900
|
+
function getWebServerUrl() {
|
|
7901
|
+
return "http://localhost:5555";
|
|
7902
|
+
}
|
|
7903
|
+
function generateConfigLink(missingVars, toolName) {
|
|
7904
|
+
const webUrl = getWebServerUrl();
|
|
7905
|
+
if (!webUrl) {
|
|
7906
|
+
return null;
|
|
7907
|
+
}
|
|
7908
|
+
const packageNamespace = extractPackageNamespace(toolName);
|
|
7909
|
+
const encodedVars = encodeURIComponent(JSON.stringify(missingVars));
|
|
7910
|
+
const encodedPackage = encodeURIComponent(packageNamespace);
|
|
7911
|
+
return `${webUrl}/?vars=${encodedVars}&package=${encodedPackage}`;
|
|
7912
|
+
}
|
|
7913
|
+
var import_dotenv, CONFIG_DIR;
|
|
7914
|
+
var init_env_loader = __esm(() => {
|
|
7915
|
+
import_dotenv = __toESM(require_main(), 1);
|
|
7916
|
+
CONFIG_DIR = join(homedir(), ".enact");
|
|
7917
|
+
import_dotenv.config();
|
|
7918
|
+
});
|
|
7919
|
+
|
|
6530
7920
|
// node_modules/yaml/dist/nodes/identity.js
|
|
6531
7921
|
var require_identity = __commonJS((exports) => {
|
|
6532
7922
|
var ALIAS = Symbol.for("yaml.alias");
|
|
@@ -13430,7 +14820,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
13430
14820
|
});
|
|
13431
14821
|
|
|
13432
14822
|
// node_modules/yaml/dist/index.js
|
|
13433
|
-
var
|
|
14823
|
+
var require_dist3 = __commonJS((exports) => {
|
|
13434
14824
|
var composer = require_composer();
|
|
13435
14825
|
var Document = require_Document();
|
|
13436
14826
|
var Schema = require_Schema();
|
|
@@ -13478,6 +14868,300 @@ var require_dist = __commonJS((exports) => {
|
|
|
13478
14868
|
exports.visitAsync = visit.visitAsync;
|
|
13479
14869
|
});
|
|
13480
14870
|
|
|
14871
|
+
// src/web/env-manager-server.ts
|
|
14872
|
+
var exports_env_manager_server = {};
|
|
14873
|
+
__export(exports_env_manager_server, {
|
|
14874
|
+
startEnvManagerServer: () => startEnvManagerServer,
|
|
14875
|
+
setPackageEnvVar: () => setPackageEnvVar,
|
|
14876
|
+
getPackageEnvVars: () => getPackageEnvVars,
|
|
14877
|
+
getAllPackageNamespaces: () => getAllPackageNamespaces,
|
|
14878
|
+
deletePackageEnvVar: () => deletePackageEnvVar
|
|
14879
|
+
});
|
|
14880
|
+
import { createServer } from "http";
|
|
14881
|
+
import { parse as parse2 } from "url";
|
|
14882
|
+
import { readFile as readFile2, writeFile, mkdir, readdir, stat } from "fs/promises";
|
|
14883
|
+
import { existsSync as existsSync3 } from "fs";
|
|
14884
|
+
import { join as join3, dirname } from "path";
|
|
14885
|
+
import { homedir as homedir2 } from "os";
|
|
14886
|
+
import { fileURLToPath } from "url";
|
|
14887
|
+
function findStaticDir() {
|
|
14888
|
+
const candidates = [
|
|
14889
|
+
join3(__dirname2, "web", "static"),
|
|
14890
|
+
join3(__dirname2, "static"),
|
|
14891
|
+
join3(__dirname2, "..", "src", "web", "static"),
|
|
14892
|
+
join3(__dirname2, "..", "..", "src", "web", "static"),
|
|
14893
|
+
join3(process.cwd(), "src", "web", "static"),
|
|
14894
|
+
join3(__dirname2, "..", "..", "..", "src", "web", "static"),
|
|
14895
|
+
join3(__dirname2, "..", "..", "src", "web", "static")
|
|
14896
|
+
];
|
|
14897
|
+
for (const candidate of candidates) {
|
|
14898
|
+
if (existsSync3(join3(candidate, "index.html"))) {
|
|
14899
|
+
logger_default.debug(`Found static directory: ${candidate}`);
|
|
14900
|
+
return candidate;
|
|
14901
|
+
}
|
|
14902
|
+
}
|
|
14903
|
+
throw new Error("Could not find static directory. Tried: " + candidates.join(", "));
|
|
14904
|
+
}
|
|
14905
|
+
function parseDotEnv(content) {
|
|
14906
|
+
const vars = {};
|
|
14907
|
+
const lines = content.split(`
|
|
14908
|
+
`);
|
|
14909
|
+
for (const line of lines) {
|
|
14910
|
+
const trimmed = line.trim();
|
|
14911
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
14912
|
+
continue;
|
|
14913
|
+
}
|
|
14914
|
+
const equalIndex = trimmed.indexOf("=");
|
|
14915
|
+
if (equalIndex === -1) {
|
|
14916
|
+
continue;
|
|
14917
|
+
}
|
|
14918
|
+
const key = trimmed.slice(0, equalIndex).trim();
|
|
14919
|
+
let value = trimmed.slice(equalIndex + 1).trim();
|
|
14920
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
14921
|
+
value = value.slice(1, -1);
|
|
14922
|
+
}
|
|
14923
|
+
if (key) {
|
|
14924
|
+
vars[key] = value;
|
|
14925
|
+
}
|
|
14926
|
+
}
|
|
14927
|
+
return vars;
|
|
14928
|
+
}
|
|
14929
|
+
function generateDotEnv(vars) {
|
|
14930
|
+
return Object.entries(vars).map(([key, value]) => {
|
|
14931
|
+
const needsQuotes = value.includes(" ") || value.includes("\t") || value.includes(`
|
|
14932
|
+
`) || value.includes('"');
|
|
14933
|
+
const escapedValue = needsQuotes ? `"${value.replace(/"/g, "\\\"")}"` : value;
|
|
14934
|
+
return `${key}=${escapedValue}`;
|
|
14935
|
+
}).join(`
|
|
14936
|
+
`) + `
|
|
14937
|
+
`;
|
|
14938
|
+
}
|
|
14939
|
+
async function getAllPackageNamespaces() {
|
|
14940
|
+
const packages = [];
|
|
14941
|
+
if (!existsSync3(ENV_BASE_DIR)) {
|
|
14942
|
+
return packages;
|
|
14943
|
+
}
|
|
14944
|
+
try {
|
|
14945
|
+
await scanDirectory(ENV_BASE_DIR, "", packages);
|
|
14946
|
+
} catch (error) {
|
|
14947
|
+
logger_default.error("Failed to scan env directory:", error);
|
|
14948
|
+
}
|
|
14949
|
+
return packages;
|
|
14950
|
+
}
|
|
14951
|
+
async function scanDirectory(dir, relativePath, packages) {
|
|
14952
|
+
try {
|
|
14953
|
+
const entries = await readdir(dir);
|
|
14954
|
+
for (const entry of entries) {
|
|
14955
|
+
const fullPath = join3(dir, entry);
|
|
14956
|
+
const stats = await stat(fullPath);
|
|
14957
|
+
if (stats.isDirectory()) {
|
|
14958
|
+
const newRelativePath = relativePath ? `${relativePath}/${entry}` : entry;
|
|
14959
|
+
await scanDirectory(fullPath, newRelativePath, packages);
|
|
14960
|
+
} else if (entry === ".env") {
|
|
14961
|
+
const namespace = relativePath || "root";
|
|
14962
|
+
try {
|
|
14963
|
+
const content = await readFile2(fullPath, "utf8");
|
|
14964
|
+
const variables = parseDotEnv(content);
|
|
14965
|
+
packages.push({
|
|
14966
|
+
namespace,
|
|
14967
|
+
path: fullPath,
|
|
14968
|
+
variables
|
|
14969
|
+
});
|
|
14970
|
+
} catch (error) {
|
|
14971
|
+
logger_default.error(`Failed to read .env file at ${fullPath}:`, error);
|
|
14972
|
+
}
|
|
14973
|
+
}
|
|
14974
|
+
}
|
|
14975
|
+
} catch (error) {
|
|
14976
|
+
logger_default.error(`Failed to scan directory ${dir}:`, error);
|
|
14977
|
+
}
|
|
14978
|
+
}
|
|
14979
|
+
async function getPackageEnvVars(namespace) {
|
|
14980
|
+
const envFile = join3(ENV_BASE_DIR, namespace, ".env");
|
|
14981
|
+
if (!existsSync3(envFile)) {
|
|
14982
|
+
return {};
|
|
14983
|
+
}
|
|
14984
|
+
try {
|
|
14985
|
+
const content = await readFile2(envFile, "utf8");
|
|
14986
|
+
return parseDotEnv(content);
|
|
14987
|
+
} catch (error) {
|
|
14988
|
+
logger_default.error(`Failed to read env file for ${namespace}:`, error);
|
|
14989
|
+
return {};
|
|
14990
|
+
}
|
|
14991
|
+
}
|
|
14992
|
+
async function setPackageEnvVar(namespace, key, value) {
|
|
14993
|
+
const envFile = join3(ENV_BASE_DIR, namespace, ".env");
|
|
14994
|
+
const envDir = dirname(envFile);
|
|
14995
|
+
if (!existsSync3(envDir)) {
|
|
14996
|
+
await mkdir(envDir, { recursive: true });
|
|
14997
|
+
}
|
|
14998
|
+
const existingVars = await getPackageEnvVars(namespace);
|
|
14999
|
+
existingVars[key] = value;
|
|
15000
|
+
const envContent = generateDotEnv(existingVars);
|
|
15001
|
+
await writeFile(envFile, envContent, "utf8");
|
|
15002
|
+
}
|
|
15003
|
+
async function deletePackageEnvVar(namespace, key) {
|
|
15004
|
+
const existingVars = await getPackageEnvVars(namespace);
|
|
15005
|
+
if (!(key in existingVars)) {
|
|
15006
|
+
throw new Error(`Environment variable '${key}' not found in package '${namespace}'`);
|
|
15007
|
+
}
|
|
15008
|
+
delete existingVars[key];
|
|
15009
|
+
const envFile = join3(ENV_BASE_DIR, namespace, ".env");
|
|
15010
|
+
const envContent = generateDotEnv(existingVars);
|
|
15011
|
+
await writeFile(envFile, envContent, "utf8");
|
|
15012
|
+
}
|
|
15013
|
+
async function serveStaticFile(filePath, res) {
|
|
15014
|
+
try {
|
|
15015
|
+
const content = await readFile2(filePath, "utf8");
|
|
15016
|
+
const ext = filePath.split(".").pop()?.toLowerCase();
|
|
15017
|
+
let contentType = "text/plain";
|
|
15018
|
+
switch (ext) {
|
|
15019
|
+
case "html":
|
|
15020
|
+
contentType = "text/html";
|
|
15021
|
+
break;
|
|
15022
|
+
case "css":
|
|
15023
|
+
contentType = "text/css";
|
|
15024
|
+
break;
|
|
15025
|
+
case "js":
|
|
15026
|
+
contentType = "application/javascript";
|
|
15027
|
+
break;
|
|
15028
|
+
case "json":
|
|
15029
|
+
contentType = "application/json";
|
|
15030
|
+
break;
|
|
15031
|
+
}
|
|
15032
|
+
res.writeHead(200, { "Content-Type": contentType });
|
|
15033
|
+
res.end(content);
|
|
15034
|
+
} catch (error) {
|
|
15035
|
+
logger_default.error("Error serving static file:", error);
|
|
15036
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
15037
|
+
res.end("File not found");
|
|
15038
|
+
}
|
|
15039
|
+
}
|
|
15040
|
+
async function handleRequest(req, res) {
|
|
15041
|
+
const urlParts = parse2(req.url || "", true);
|
|
15042
|
+
const pathname = urlParts.pathname || "/";
|
|
15043
|
+
const method = req.method || "GET";
|
|
15044
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
15045
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
15046
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
15047
|
+
if (method === "OPTIONS") {
|
|
15048
|
+
res.writeHead(200);
|
|
15049
|
+
res.end();
|
|
15050
|
+
return;
|
|
15051
|
+
}
|
|
15052
|
+
try {
|
|
15053
|
+
if (pathname === "/") {
|
|
15054
|
+
await serveStaticFile(join3(STATIC_DIR, "index.html"), res);
|
|
15055
|
+
} else if (pathname === "/style.css") {
|
|
15056
|
+
await serveStaticFile(join3(STATIC_DIR, "style.css"), res);
|
|
15057
|
+
} else if (pathname === "/app.js") {
|
|
15058
|
+
await serveStaticFile(join3(STATIC_DIR, "app.js"), res);
|
|
15059
|
+
} else if (pathname === "/favicon.ico") {
|
|
15060
|
+
const favicon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><text y=".9em" font-size="90">\uD83C\uDF10</text></svg>`;
|
|
15061
|
+
res.writeHead(200, { "Content-Type": "image/svg+xml" });
|
|
15062
|
+
res.end(favicon);
|
|
15063
|
+
} else if (pathname === "/api/packages" && method === "GET") {
|
|
15064
|
+
const packages = await getAllPackageNamespaces();
|
|
15065
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15066
|
+
res.end(JSON.stringify({ packages }));
|
|
15067
|
+
} else if (pathname === "/api/packages" && method === "POST") {
|
|
15068
|
+
const body = await getRequestBody(req);
|
|
15069
|
+
const { namespace } = JSON.parse(body);
|
|
15070
|
+
if (!namespace) {
|
|
15071
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
15072
|
+
res.end(JSON.stringify({ error: "Namespace is required" }));
|
|
15073
|
+
return;
|
|
15074
|
+
}
|
|
15075
|
+
const envDir = join3(ENV_BASE_DIR, namespace);
|
|
15076
|
+
const envFile = join3(envDir, ".env");
|
|
15077
|
+
if (!existsSync3(envDir)) {
|
|
15078
|
+
await mkdir(envDir, { recursive: true });
|
|
15079
|
+
}
|
|
15080
|
+
if (!existsSync3(envFile)) {
|
|
15081
|
+
await writeFile(envFile, "", "utf8");
|
|
15082
|
+
}
|
|
15083
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15084
|
+
res.end(JSON.stringify({ success: true }));
|
|
15085
|
+
} else if (pathname?.startsWith("/api/packages/") && method === "GET") {
|
|
15086
|
+
const namespace = decodeURIComponent(pathname.replace("/api/packages/", ""));
|
|
15087
|
+
const variables = await getPackageEnvVars(namespace);
|
|
15088
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15089
|
+
res.end(JSON.stringify({ namespace, variables }));
|
|
15090
|
+
} else if (pathname?.startsWith("/api/packages/") && pathname.endsWith("/variables") && method === "POST") {
|
|
15091
|
+
const namespace = decodeURIComponent(pathname.replace("/api/packages/", "").replace("/variables", ""));
|
|
15092
|
+
const body = await getRequestBody(req);
|
|
15093
|
+
const { key, value } = JSON.parse(body);
|
|
15094
|
+
if (!key || value === undefined) {
|
|
15095
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
15096
|
+
res.end(JSON.stringify({ error: "Key and value are required" }));
|
|
15097
|
+
return;
|
|
15098
|
+
}
|
|
15099
|
+
await setPackageEnvVar(namespace, key, value);
|
|
15100
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15101
|
+
res.end(JSON.stringify({ success: true }));
|
|
15102
|
+
} else if (pathname?.includes("/variables/") && method === "DELETE") {
|
|
15103
|
+
const pathParts = pathname.split("/");
|
|
15104
|
+
const variableIndex = pathParts.indexOf("variables");
|
|
15105
|
+
const namespace = decodeURIComponent(pathParts.slice(3, variableIndex).join("/"));
|
|
15106
|
+
const key = decodeURIComponent(pathParts[variableIndex + 1]);
|
|
15107
|
+
await deletePackageEnvVar(namespace, key);
|
|
15108
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
15109
|
+
res.end(JSON.stringify({ success: true }));
|
|
15110
|
+
} else {
|
|
15111
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
15112
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
15113
|
+
}
|
|
15114
|
+
} catch (error) {
|
|
15115
|
+
logger_default.error("Web server error:", error);
|
|
15116
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
15117
|
+
res.end(JSON.stringify({
|
|
15118
|
+
error: error instanceof Error ? error.message : "Internal server error"
|
|
15119
|
+
}));
|
|
15120
|
+
}
|
|
15121
|
+
}
|
|
15122
|
+
function getRequestBody(req) {
|
|
15123
|
+
return new Promise((resolve, reject) => {
|
|
15124
|
+
let body = "";
|
|
15125
|
+
req.on("data", (chunk) => {
|
|
15126
|
+
body += chunk.toString();
|
|
15127
|
+
});
|
|
15128
|
+
req.on("end", () => {
|
|
15129
|
+
resolve(body);
|
|
15130
|
+
});
|
|
15131
|
+
req.on("error", reject);
|
|
15132
|
+
});
|
|
15133
|
+
}
|
|
15134
|
+
function startEnvManagerServer(port = 5555) {
|
|
15135
|
+
return new Promise((resolve, reject) => {
|
|
15136
|
+
const server = createServer(handleRequest);
|
|
15137
|
+
server.listen(port, () => {
|
|
15138
|
+
const actualPort = server.address()?.port || port;
|
|
15139
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort}`);
|
|
15140
|
+
resolve({ server, port: actualPort });
|
|
15141
|
+
});
|
|
15142
|
+
server.on("error", (error) => {
|
|
15143
|
+
if (error.code === "EADDRINUSE") {
|
|
15144
|
+
server.listen(0, () => {
|
|
15145
|
+
const actualPort = server.address()?.port;
|
|
15146
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager web server started on http://localhost:${actualPort} (port ${port} was in use)`);
|
|
15147
|
+
resolve({ server, port: actualPort });
|
|
15148
|
+
});
|
|
15149
|
+
} else {
|
|
15150
|
+
reject(error);
|
|
15151
|
+
}
|
|
15152
|
+
});
|
|
15153
|
+
});
|
|
15154
|
+
}
|
|
15155
|
+
var __filename2, __dirname2, CONFIG_DIR2, ENV_BASE_DIR, STATIC_DIR;
|
|
15156
|
+
var init_env_manager_server = __esm(() => {
|
|
15157
|
+
init_logger();
|
|
15158
|
+
__filename2 = fileURLToPath(import.meta.url);
|
|
15159
|
+
__dirname2 = dirname(__filename2);
|
|
15160
|
+
CONFIG_DIR2 = join3(homedir2(), ".enact");
|
|
15161
|
+
ENV_BASE_DIR = join3(CONFIG_DIR2, "env");
|
|
15162
|
+
STATIC_DIR = findStaticDir();
|
|
15163
|
+
});
|
|
15164
|
+
|
|
13481
15165
|
// node_modules/zod/dist/esm/v3/external.js
|
|
13482
15166
|
var exports_external = {};
|
|
13483
15167
|
__export(exports_external, {
|
|
@@ -20457,21 +22141,41 @@ class EnactApiClient {
|
|
|
20457
22141
|
}
|
|
20458
22142
|
async searchTools(query) {
|
|
20459
22143
|
const endpoint = "/functions/v1/tools-search";
|
|
20460
|
-
|
|
20461
|
-
|
|
20462
|
-
|
|
20463
|
-
|
|
20464
|
-
|
|
20465
|
-
|
|
20466
|
-
|
|
20467
|
-
|
|
20468
|
-
|
|
20469
|
-
|
|
20470
|
-
|
|
20471
|
-
|
|
20472
|
-
|
|
20473
|
-
|
|
20474
|
-
|
|
22144
|
+
try {
|
|
22145
|
+
if (true) {
|
|
22146
|
+
console.error(`Search request to ${endpoint}:`, JSON.stringify(query, null, 2));
|
|
22147
|
+
}
|
|
22148
|
+
const response = await this.makeRequest(endpoint, {
|
|
22149
|
+
method: "POST",
|
|
22150
|
+
body: JSON.stringify(query)
|
|
22151
|
+
});
|
|
22152
|
+
if (Array.isArray(response)) {
|
|
22153
|
+
return response;
|
|
22154
|
+
} else if (response.data && Array.isArray(response.data)) {
|
|
22155
|
+
return response.data;
|
|
22156
|
+
} else if (response.results && Array.isArray(response.results)) {
|
|
22157
|
+
return response.results;
|
|
22158
|
+
} else if (response.tools && Array.isArray(response.tools)) {
|
|
22159
|
+
return response.tools;
|
|
22160
|
+
} else {
|
|
22161
|
+
console.warn("Unexpected response structure for searchTools:", response);
|
|
22162
|
+
return [];
|
|
22163
|
+
}
|
|
22164
|
+
} catch (error) {
|
|
22165
|
+
if (error instanceof EnactApiError) {
|
|
22166
|
+
console.error(`Search API error (${error.statusCode}): ${error.message}`);
|
|
22167
|
+
console.error(`Endpoint: ${error.endpoint}`);
|
|
22168
|
+
if (error.statusCode === 502) {
|
|
22169
|
+
console.error("502 Bad Gateway error - this usually indicates:");
|
|
22170
|
+
console.error("• The API server is temporarily unavailable");
|
|
22171
|
+
console.error("• The search service is overloaded");
|
|
22172
|
+
console.error("• Network connectivity issues");
|
|
22173
|
+
console.error("• Try again in a few moments");
|
|
22174
|
+
}
|
|
22175
|
+
} else {
|
|
22176
|
+
console.error("Unexpected search error:", error);
|
|
22177
|
+
}
|
|
22178
|
+
throw error;
|
|
20475
22179
|
}
|
|
20476
22180
|
}
|
|
20477
22181
|
async publishTool(tool, token, tokenType = "cli") {
|
|
@@ -20663,90 +22367,8 @@ class EnactApiError extends Error {
|
|
|
20663
22367
|
}
|
|
20664
22368
|
}
|
|
20665
22369
|
|
|
20666
|
-
// src/exec/logger.ts
|
|
20667
|
-
var createLogger = () => {
|
|
20668
|
-
let mcpServer = null;
|
|
20669
|
-
const shouldSuppressConsole = process.env.CI === "true" || process.env.ENACT_SKIP_INTERACTIVE === "true";
|
|
20670
|
-
return {
|
|
20671
|
-
info: (message, ...args) => {
|
|
20672
|
-
if (!shouldSuppressConsole) {
|
|
20673
|
-
console.error("[INFO]", message, ...args);
|
|
20674
|
-
}
|
|
20675
|
-
if (mcpServer) {
|
|
20676
|
-
try {
|
|
20677
|
-
mcpServer.server.sendLoggingMessage({ level: "info", data: message });
|
|
20678
|
-
} catch (error) {}
|
|
20679
|
-
}
|
|
20680
|
-
},
|
|
20681
|
-
error: (message, ...args) => {
|
|
20682
|
-
if (!shouldSuppressConsole) {
|
|
20683
|
-
console.error("[ERROR]", message, ...args);
|
|
20684
|
-
}
|
|
20685
|
-
if (mcpServer) {
|
|
20686
|
-
try {
|
|
20687
|
-
mcpServer.server.sendLoggingMessage({ level: "error", data: message });
|
|
20688
|
-
} catch (error) {}
|
|
20689
|
-
}
|
|
20690
|
-
},
|
|
20691
|
-
warn: (message, ...args) => {
|
|
20692
|
-
if (!shouldSuppressConsole) {
|
|
20693
|
-
console.warn("[WARN]", message, ...args);
|
|
20694
|
-
}
|
|
20695
|
-
if (mcpServer) {
|
|
20696
|
-
try {
|
|
20697
|
-
mcpServer.server.sendLoggingMessage({ level: "warning", data: message });
|
|
20698
|
-
} catch (error) {}
|
|
20699
|
-
}
|
|
20700
|
-
},
|
|
20701
|
-
debug: (message, ...args) => {
|
|
20702
|
-
if ((process.env.DEBUG || process.env.VERBOSE) && !shouldSuppressConsole) {
|
|
20703
|
-
console.error("[DEBUG]", message, ...args);
|
|
20704
|
-
}
|
|
20705
|
-
if (mcpServer) {
|
|
20706
|
-
try {
|
|
20707
|
-
mcpServer.server.sendLoggingMessage({ level: "debug", data: message });
|
|
20708
|
-
} catch (error) {}
|
|
20709
|
-
}
|
|
20710
|
-
},
|
|
20711
|
-
setServer: (server) => {
|
|
20712
|
-
mcpServer = server;
|
|
20713
|
-
},
|
|
20714
|
-
clientLoggingEnabled: () => {
|
|
20715
|
-
return !!mcpServer;
|
|
20716
|
-
}
|
|
20717
|
-
};
|
|
20718
|
-
};
|
|
20719
|
-
var logger = createLogger();
|
|
20720
|
-
var logger_default = logger;
|
|
20721
|
-
|
|
20722
22370
|
// src/security/security.ts
|
|
20723
|
-
|
|
20724
|
-
const hasSignature = tool.signature || tool.signatures && Object.keys(tool.signatures).length > 0;
|
|
20725
|
-
if (!hasSignature) {
|
|
20726
|
-
logger_default.warn(`Tool ${tool.name} has no signature`);
|
|
20727
|
-
return false;
|
|
20728
|
-
}
|
|
20729
|
-
try {
|
|
20730
|
-
if (tool.signatures && Object.keys(tool.signatures).length > 0) {
|
|
20731
|
-
logger_default.info(`Tool ${tool.name} has verified signatures from database`);
|
|
20732
|
-
return true;
|
|
20733
|
-
}
|
|
20734
|
-
if (tool.signature) {
|
|
20735
|
-
const isValid2 = true;
|
|
20736
|
-
const message = `Signature verification for tool ${tool.name} with algorithm ${tool.signature.algorithm}`;
|
|
20737
|
-
if (!isValid2) {
|
|
20738
|
-
logger_default.warn(`Invalid signature for tool ${tool.name}: ${message}`);
|
|
20739
|
-
} else {
|
|
20740
|
-
logger_default.info(`Signature verified for tool ${tool.name}: ${message}`);
|
|
20741
|
-
}
|
|
20742
|
-
return isValid2;
|
|
20743
|
-
}
|
|
20744
|
-
return false;
|
|
20745
|
-
} catch (error) {
|
|
20746
|
-
logger_default.error(`Error verifying signature: ${error.message}`);
|
|
20747
|
-
return false;
|
|
20748
|
-
}
|
|
20749
|
-
}
|
|
22371
|
+
init_logger();
|
|
20750
22372
|
function verifyCommandSafety(command, tool) {
|
|
20751
22373
|
const warnings = [];
|
|
20752
22374
|
const blocked = [];
|
|
@@ -21006,6 +22628,29 @@ import { spawn } from "child_process";
|
|
|
21006
22628
|
class ExecutionProvider {
|
|
21007
22629
|
}
|
|
21008
22630
|
|
|
22631
|
+
// src/core/DirectExecutionProvider.ts
|
|
22632
|
+
init_logger();
|
|
22633
|
+
|
|
22634
|
+
// src/utils/timeout.ts
|
|
22635
|
+
function parseTimeout(timeout) {
|
|
22636
|
+
const match = timeout.match(/^(\d+)([smh])$/);
|
|
22637
|
+
if (!match) {
|
|
22638
|
+
return 30000;
|
|
22639
|
+
}
|
|
22640
|
+
const value = parseInt(match[1]);
|
|
22641
|
+
const unit = match[2];
|
|
22642
|
+
switch (unit) {
|
|
22643
|
+
case "s":
|
|
22644
|
+
return value * 1000;
|
|
22645
|
+
case "m":
|
|
22646
|
+
return value * 60 * 1000;
|
|
22647
|
+
case "h":
|
|
22648
|
+
return value * 60 * 60 * 1000;
|
|
22649
|
+
default:
|
|
22650
|
+
return 30000;
|
|
22651
|
+
}
|
|
22652
|
+
}
|
|
22653
|
+
|
|
21009
22654
|
// src/core/DirectExecutionProvider.ts
|
|
21010
22655
|
class DirectExecutionProvider extends ExecutionProvider {
|
|
21011
22656
|
async resolveEnvironmentVariables(envConfig, namespace) {
|
|
@@ -21028,15 +22673,53 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21028
22673
|
}
|
|
21029
22674
|
return resolved;
|
|
21030
22675
|
}
|
|
21031
|
-
async executeCommand(command, inputs, environment, timeout) {
|
|
22676
|
+
async executeCommand(command, inputs, environment, timeout, options) {
|
|
21032
22677
|
return new Promise((resolve, reject) => {
|
|
21033
22678
|
let stdout = "";
|
|
21034
22679
|
let stderr = "";
|
|
22680
|
+
const verbose = options?.verbose ?? false;
|
|
22681
|
+
const showSpinner = options?.showSpinner ?? false;
|
|
22682
|
+
const streamOutput = options?.streamOutput ?? true;
|
|
22683
|
+
let spinner = null;
|
|
22684
|
+
if (showSpinner) {
|
|
22685
|
+
try {
|
|
22686
|
+
const p = require_dist2();
|
|
22687
|
+
spinner = p.spinner();
|
|
22688
|
+
spinner.start("Executing tool...");
|
|
22689
|
+
} catch (e) {
|
|
22690
|
+
console.log("Executing tool...");
|
|
22691
|
+
}
|
|
22692
|
+
}
|
|
22693
|
+
if (verbose) {
|
|
22694
|
+
try {
|
|
22695
|
+
const pc = require_picocolors();
|
|
22696
|
+
console.error(pc.cyan(`
|
|
22697
|
+
\uD83D\uDE80 Executing command:`));
|
|
22698
|
+
console.error(pc.white(command));
|
|
22699
|
+
} catch (e) {
|
|
22700
|
+
console.error(`
|
|
22701
|
+
\uD83D\uDE80 Executing command:`);
|
|
22702
|
+
console.error(command);
|
|
22703
|
+
}
|
|
22704
|
+
}
|
|
22705
|
+
let substitutedCommand = command;
|
|
22706
|
+
for (const [key, value] of Object.entries(inputs)) {
|
|
22707
|
+
const templateVar = `\${${key}}`;
|
|
22708
|
+
let substitutionValue;
|
|
22709
|
+
if (typeof value === "string") {
|
|
22710
|
+
substitutionValue = value;
|
|
22711
|
+
} else if (typeof value === "object") {
|
|
22712
|
+
substitutionValue = JSON.stringify(value);
|
|
22713
|
+
} else {
|
|
22714
|
+
substitutionValue = String(value);
|
|
22715
|
+
}
|
|
22716
|
+
substitutedCommand = substitutedCommand.replace(new RegExp(`\\$\\{${key}\\}`, "g"), substitutionValue);
|
|
22717
|
+
}
|
|
21035
22718
|
const env = {
|
|
21036
22719
|
...process.env,
|
|
21037
22720
|
...environment.vars
|
|
21038
22721
|
};
|
|
21039
|
-
const commandParts = this.parseCommand(
|
|
22722
|
+
const commandParts = this.parseCommand(substitutedCommand);
|
|
21040
22723
|
const cmd = commandParts[0];
|
|
21041
22724
|
const args = commandParts.slice(1);
|
|
21042
22725
|
logger_default.info(`Executing command: ${command}`);
|
|
@@ -21046,20 +22729,34 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21046
22729
|
stdio: ["pipe", "pipe", "pipe"],
|
|
21047
22730
|
detached: process.platform !== "win32"
|
|
21048
22731
|
});
|
|
22732
|
+
let isCleanedUp = false;
|
|
22733
|
+
let cleanupTimer = null;
|
|
21049
22734
|
const cleanup = () => {
|
|
22735
|
+
if (isCleanedUp)
|
|
22736
|
+
return;
|
|
22737
|
+
isCleanedUp = true;
|
|
22738
|
+
if (cleanupTimer) {
|
|
22739
|
+
clearTimeout(cleanupTimer);
|
|
22740
|
+
cleanupTimer = null;
|
|
22741
|
+
}
|
|
21050
22742
|
if (proc && !proc.killed) {
|
|
21051
22743
|
try {
|
|
21052
22744
|
console.log(`[DEBUG] Cleaning up process PID: ${proc.pid}`);
|
|
21053
22745
|
if (process.platform === "win32") {
|
|
21054
22746
|
proc.kill("SIGKILL");
|
|
21055
22747
|
} else {
|
|
21056
|
-
|
|
21057
|
-
setTimeout(() => {
|
|
21058
|
-
if (!proc.killed) {
|
|
22748
|
+
proc.kill("SIGTERM");
|
|
22749
|
+
cleanupTimer = setTimeout(() => {
|
|
22750
|
+
if (!proc.killed && !isCleanedUp) {
|
|
21059
22751
|
console.log(`[DEBUG] Force killing process PID: ${proc.pid}`);
|
|
21060
|
-
|
|
22752
|
+
try {
|
|
22753
|
+
proc.kill("SIGKILL");
|
|
22754
|
+
} catch (killError) {
|
|
22755
|
+
logger_default.debug(`Force kill error (likely harmless): ${killError}`);
|
|
22756
|
+
}
|
|
21061
22757
|
}
|
|
21062
|
-
|
|
22758
|
+
cleanupTimer = null;
|
|
22759
|
+
}, 1000);
|
|
21063
22760
|
}
|
|
21064
22761
|
} catch (killError) {
|
|
21065
22762
|
logger_default.debug(`Process cleanup error (likely harmless): ${killError}`);
|
|
@@ -21069,16 +22766,76 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21069
22766
|
proc.stdout.on("data", (data) => {
|
|
21070
22767
|
const chunk = data.toString();
|
|
21071
22768
|
stdout += chunk;
|
|
21072
|
-
|
|
22769
|
+
if (streamOutput) {
|
|
22770
|
+
process.stdout.write(chunk);
|
|
22771
|
+
}
|
|
21073
22772
|
});
|
|
21074
22773
|
proc.stderr.on("data", (data) => {
|
|
21075
22774
|
const chunk = data.toString();
|
|
21076
22775
|
stderr += chunk;
|
|
21077
|
-
|
|
22776
|
+
if (streamOutput) {
|
|
22777
|
+
process.stderr.write(chunk);
|
|
22778
|
+
}
|
|
21078
22779
|
});
|
|
21079
22780
|
proc.on("close", (code) => {
|
|
21080
22781
|
console.log(`[DEBUG] Process closed with code: ${code}, PID: ${proc.pid}`);
|
|
21081
22782
|
cleanup();
|
|
22783
|
+
if (spinner) {
|
|
22784
|
+
spinner.stop("Execution completed");
|
|
22785
|
+
}
|
|
22786
|
+
if (code === 0) {
|
|
22787
|
+
if (showSpinner || verbose) {
|
|
22788
|
+
try {
|
|
22789
|
+
const pc = require_picocolors();
|
|
22790
|
+
console.error(pc.green(`
|
|
22791
|
+
✅ Tool executed successfully`));
|
|
22792
|
+
if (stdout.trim() && !streamOutput) {
|
|
22793
|
+
console.error(pc.cyan(`
|
|
22794
|
+
\uD83D\uDCE4 Output:`));
|
|
22795
|
+
console.error(stdout.trim());
|
|
22796
|
+
}
|
|
22797
|
+
} catch (e) {
|
|
22798
|
+
console.error(`
|
|
22799
|
+
✅ Tool executed successfully`);
|
|
22800
|
+
if (stdout.trim() && !streamOutput) {
|
|
22801
|
+
console.error(`
|
|
22802
|
+
\uD83D\uDCE4 Output:`);
|
|
22803
|
+
console.error(stdout.trim());
|
|
22804
|
+
}
|
|
22805
|
+
}
|
|
22806
|
+
}
|
|
22807
|
+
} else {
|
|
22808
|
+
if (showSpinner || verbose) {
|
|
22809
|
+
try {
|
|
22810
|
+
const pc = require_picocolors();
|
|
22811
|
+
console.error(pc.red(`
|
|
22812
|
+
❌ Tool execution failed (exit code: ${code})`));
|
|
22813
|
+
if (stderr.trim() && !streamOutput) {
|
|
22814
|
+
console.error(pc.red(`
|
|
22815
|
+
\uD83D\uDCE4 Error output:`));
|
|
22816
|
+
console.error(stderr.trim());
|
|
22817
|
+
}
|
|
22818
|
+
if (stdout.trim() && !streamOutput) {
|
|
22819
|
+
console.error(pc.yellow(`
|
|
22820
|
+
\uD83D\uDCE4 Standard output:`));
|
|
22821
|
+
console.error(stdout.trim());
|
|
22822
|
+
}
|
|
22823
|
+
} catch (e) {
|
|
22824
|
+
console.error(`
|
|
22825
|
+
❌ Tool execution failed (exit code: ${code})`);
|
|
22826
|
+
if (stderr.trim() && !streamOutput) {
|
|
22827
|
+
console.error(`
|
|
22828
|
+
\uD83D\uDCE4 Error output:`);
|
|
22829
|
+
console.error(stderr.trim());
|
|
22830
|
+
}
|
|
22831
|
+
if (stdout.trim() && !streamOutput) {
|
|
22832
|
+
console.error(`
|
|
22833
|
+
\uD83D\uDCE4 Standard output:`);
|
|
22834
|
+
console.error(stdout.trim());
|
|
22835
|
+
}
|
|
22836
|
+
}
|
|
22837
|
+
}
|
|
22838
|
+
}
|
|
21082
22839
|
resolve({
|
|
21083
22840
|
stdout: stdout.trim(),
|
|
21084
22841
|
stderr: stderr.trim(),
|
|
@@ -21087,12 +22844,28 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21087
22844
|
});
|
|
21088
22845
|
proc.on("error", (error) => {
|
|
21089
22846
|
cleanup();
|
|
22847
|
+
if (spinner) {
|
|
22848
|
+
spinner.stop("Execution failed");
|
|
22849
|
+
}
|
|
22850
|
+
if (showSpinner || verbose) {
|
|
22851
|
+
try {
|
|
22852
|
+
const pc = require_picocolors();
|
|
22853
|
+
console.error(pc.red(`
|
|
22854
|
+
❌ Failed to execute command: ${error.message}`));
|
|
22855
|
+
} catch (e) {
|
|
22856
|
+
console.error(`
|
|
22857
|
+
❌ Failed to execute command: ${error.message}`);
|
|
22858
|
+
}
|
|
22859
|
+
}
|
|
21090
22860
|
reject(new Error(`Command execution error: ${error.message}`));
|
|
21091
22861
|
});
|
|
21092
22862
|
if (timeout) {
|
|
21093
|
-
const timeoutMs =
|
|
22863
|
+
const timeoutMs = parseTimeout(timeout);
|
|
21094
22864
|
setTimeout(() => {
|
|
21095
22865
|
cleanup();
|
|
22866
|
+
if (spinner) {
|
|
22867
|
+
spinner.stop("Execution failed");
|
|
22868
|
+
}
|
|
21096
22869
|
reject(new Error(`Command timed out after ${timeout}`));
|
|
21097
22870
|
}, timeoutMs);
|
|
21098
22871
|
}
|
|
@@ -21101,6 +22874,20 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21101
22874
|
}
|
|
21102
22875
|
});
|
|
21103
22876
|
}
|
|
22877
|
+
async executeCommandExecStyle(command, timeout, verbose = false, envVars = {}) {
|
|
22878
|
+
const environment = {
|
|
22879
|
+
vars: envVars,
|
|
22880
|
+
resources: { timeout }
|
|
22881
|
+
};
|
|
22882
|
+
const result = await this.executeCommand(command, {}, environment, timeout, {
|
|
22883
|
+
verbose,
|
|
22884
|
+
showSpinner: true,
|
|
22885
|
+
streamOutput: false
|
|
22886
|
+
});
|
|
22887
|
+
if (result.exitCode !== 0) {
|
|
22888
|
+
throw new Error(`Command failed with exit code ${result.exitCode}`);
|
|
22889
|
+
}
|
|
22890
|
+
}
|
|
21104
22891
|
async setup(tool) {
|
|
21105
22892
|
logger_default.debug(`Setting up direct execution for tool: ${tool.name}`);
|
|
21106
22893
|
return true;
|
|
@@ -21181,24 +22968,6 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21181
22968
|
generateExecutionId() {
|
|
21182
22969
|
return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
21183
22970
|
}
|
|
21184
|
-
parseTimeout(timeout) {
|
|
21185
|
-
const match = timeout.match(/^(\d+)([smh])$/);
|
|
21186
|
-
if (!match) {
|
|
21187
|
-
throw new Error(`Invalid timeout format: ${timeout}`);
|
|
21188
|
-
}
|
|
21189
|
-
const value = parseInt(match[1]);
|
|
21190
|
-
const unit = match[2];
|
|
21191
|
-
switch (unit) {
|
|
21192
|
-
case "s":
|
|
21193
|
-
return value * 1000;
|
|
21194
|
-
case "m":
|
|
21195
|
-
return value * 60 * 1000;
|
|
21196
|
-
case "h":
|
|
21197
|
-
return value * 60 * 60 * 1000;
|
|
21198
|
-
default:
|
|
21199
|
-
throw new Error(`Unknown timeout unit: ${unit}`);
|
|
21200
|
-
}
|
|
21201
|
-
}
|
|
21202
22971
|
parseCommand(command) {
|
|
21203
22972
|
const parts = [];
|
|
21204
22973
|
let current = "";
|
|
@@ -21233,115 +23002,461 @@ class DirectExecutionProvider extends ExecutionProvider {
|
|
|
21233
23002
|
}
|
|
21234
23003
|
}
|
|
21235
23004
|
|
|
21236
|
-
// src/
|
|
21237
|
-
|
|
21238
|
-
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
|
|
21242
|
-
var
|
|
21243
|
-
|
|
21244
|
-
|
|
21245
|
-
|
|
21246
|
-
|
|
23005
|
+
// src/core/EnactCore.ts
|
|
23006
|
+
init_env_loader();
|
|
23007
|
+
init_logger();
|
|
23008
|
+
var import_yaml2 = __toESM(require_dist3(), 1);
|
|
23009
|
+
|
|
23010
|
+
// src/security/sign.ts
|
|
23011
|
+
var import_yaml = __toESM(require_dist3(), 1);
|
|
23012
|
+
import * as crypto from "crypto";
|
|
23013
|
+
import * as fs from "fs";
|
|
23014
|
+
import * as path from "path";
|
|
23015
|
+
function createCanonicalToolDefinition(tool) {
|
|
23016
|
+
const canonical = {};
|
|
23017
|
+
const orderedFields = [
|
|
23018
|
+
"name",
|
|
23019
|
+
"description",
|
|
23020
|
+
"command",
|
|
23021
|
+
"protocol_version",
|
|
23022
|
+
"version",
|
|
23023
|
+
"timeout",
|
|
23024
|
+
"tags",
|
|
23025
|
+
"input_schema",
|
|
23026
|
+
"output_schema",
|
|
23027
|
+
"annotations",
|
|
23028
|
+
"env_vars",
|
|
23029
|
+
"examples",
|
|
23030
|
+
"resources",
|
|
23031
|
+
"doc",
|
|
23032
|
+
"authors",
|
|
23033
|
+
"enact"
|
|
23034
|
+
];
|
|
23035
|
+
for (const field of orderedFields) {
|
|
23036
|
+
if (tool[field] !== undefined) {
|
|
23037
|
+
canonical[field] = tool[field];
|
|
23038
|
+
}
|
|
21247
23039
|
}
|
|
21248
|
-
|
|
21249
|
-
|
|
23040
|
+
const remainingFields = Object.keys(tool).filter((key) => !orderedFields.includes(key)).sort();
|
|
23041
|
+
for (const field of remainingFields) {
|
|
23042
|
+
if (tool[field] !== undefined) {
|
|
23043
|
+
canonical[field] = tool[field];
|
|
23044
|
+
}
|
|
21250
23045
|
}
|
|
21251
|
-
return
|
|
23046
|
+
return canonical;
|
|
21252
23047
|
}
|
|
21253
|
-
function
|
|
21254
|
-
|
|
23048
|
+
function createCanonicalToolJson(toolData) {
|
|
23049
|
+
const toolRecord = {
|
|
23050
|
+
name: toolData.name,
|
|
23051
|
+
description: toolData.description,
|
|
23052
|
+
command: toolData.command,
|
|
23053
|
+
protocol_version: toolData.protocol_version,
|
|
23054
|
+
version: toolData.version,
|
|
23055
|
+
timeout: toolData.timeout,
|
|
23056
|
+
tags: toolData.tags,
|
|
23057
|
+
input_schema: toolData.input_schema,
|
|
23058
|
+
output_schema: toolData.output_schema,
|
|
23059
|
+
annotations: toolData.annotations,
|
|
23060
|
+
env_vars: toolData.env_vars,
|
|
23061
|
+
examples: toolData.examples,
|
|
23062
|
+
resources: toolData.resources,
|
|
23063
|
+
doc: toolData.doc,
|
|
23064
|
+
authors: toolData.authors,
|
|
23065
|
+
enact: toolData.enact || "1.0.0"
|
|
23066
|
+
};
|
|
23067
|
+
const canonical = createCanonicalToolDefinition(toolRecord);
|
|
23068
|
+
return JSON.stringify(canonical, Object.keys(canonical).sort());
|
|
21255
23069
|
}
|
|
21256
|
-
|
|
21257
|
-
|
|
21258
|
-
|
|
21259
|
-
|
|
21260
|
-
|
|
23070
|
+
var DEFAULT_POLICY = {
|
|
23071
|
+
minimumSignatures: 1,
|
|
23072
|
+
allowedAlgorithms: ["sha256"]
|
|
23073
|
+
};
|
|
23074
|
+
var TRUSTED_KEYS_DIR = path.join(process.env.HOME || ".", ".enact", "trusted-keys");
|
|
23075
|
+
function getTrustedPublicKeysMap() {
|
|
23076
|
+
const trustedKeys = new Map;
|
|
23077
|
+
if (fs.existsSync(TRUSTED_KEYS_DIR)) {
|
|
23078
|
+
try {
|
|
23079
|
+
const files = fs.readdirSync(TRUSTED_KEYS_DIR);
|
|
23080
|
+
for (const file of files) {
|
|
23081
|
+
if (file.endsWith(".pem")) {
|
|
23082
|
+
const keyPath = path.join(TRUSTED_KEYS_DIR, file);
|
|
23083
|
+
const pemContent = fs.readFileSync(keyPath, "utf8");
|
|
23084
|
+
const base64Key = pemToBase64(pemContent);
|
|
23085
|
+
trustedKeys.set(base64Key, pemContent);
|
|
23086
|
+
}
|
|
23087
|
+
}
|
|
23088
|
+
} catch (error) {
|
|
23089
|
+
console.error(`Error reading trusted keys: ${error.message}`);
|
|
23090
|
+
}
|
|
21261
23091
|
}
|
|
23092
|
+
return trustedKeys;
|
|
21262
23093
|
}
|
|
21263
|
-
|
|
21264
|
-
|
|
21265
|
-
|
|
21266
|
-
|
|
23094
|
+
function pemToBase64(pem) {
|
|
23095
|
+
return pem.replace(/-----BEGIN PUBLIC KEY-----/, "").replace(/-----END PUBLIC KEY-----/, "").replace(/\s/g, "");
|
|
23096
|
+
}
|
|
23097
|
+
function base64ToPem(base64) {
|
|
23098
|
+
return `-----BEGIN PUBLIC KEY-----
|
|
23099
|
+
${base64.match(/.{1,64}/g)?.join(`
|
|
23100
|
+
`)}
|
|
23101
|
+
-----END PUBLIC KEY-----`;
|
|
23102
|
+
}
|
|
23103
|
+
async function hashTool(tool) {
|
|
23104
|
+
const canonical = createCanonicalToolDefinition(tool);
|
|
23105
|
+
const { signature, ...toolForSigning } = canonical;
|
|
23106
|
+
const canonicalJson = JSON.stringify(toolForSigning, Object.keys(toolForSigning).sort());
|
|
23107
|
+
console.error("\uD83D\uDD0D Canonical JSON for hashing:", canonicalJson);
|
|
23108
|
+
console.error("\uD83D\uDD0D Canonical JSON length:", canonicalJson.length);
|
|
23109
|
+
const encoder = new TextEncoder;
|
|
23110
|
+
const data = encoder.encode(canonicalJson);
|
|
23111
|
+
const { webcrypto } = await import("node:crypto");
|
|
23112
|
+
const hashBuffer = await webcrypto.subtle.digest("SHA-256", data);
|
|
23113
|
+
const hashBytes = new Uint8Array(hashBuffer);
|
|
23114
|
+
console.error("\uD83D\uDD0D SHA-256 hash length:", hashBytes.length, "bytes (should be 32)");
|
|
23115
|
+
return hashBytes;
|
|
23116
|
+
}
|
|
23117
|
+
async function verifyToolSignature(toolObject, signatureB64, publicKeyObj) {
|
|
23118
|
+
try {
|
|
23119
|
+
const toolHash = await hashTool(toolObject);
|
|
23120
|
+
const signatureBytes = new Uint8Array(atob(signatureB64).split("").map((char) => char.charCodeAt(0)));
|
|
23121
|
+
console.error("\uD83D\uDD0D Tool hash byte length:", toolHash.length, "(should be 32 for SHA-256)");
|
|
23122
|
+
console.error("\uD83D\uDD0D Signature bytes length:", signatureBytes.length, "(should be 64 for P-256)");
|
|
23123
|
+
const { webcrypto } = await import("node:crypto");
|
|
23124
|
+
const isValid2 = await webcrypto.subtle.verify({ name: "ECDSA", hash: { name: "SHA-256" } }, publicKeyObj, signatureBytes, toolHash);
|
|
23125
|
+
console.error("\uD83C\uDFAF Web Crypto API verification result:", isValid2);
|
|
23126
|
+
return isValid2;
|
|
23127
|
+
} catch (error) {
|
|
23128
|
+
console.error("❌ Verification error:", error);
|
|
23129
|
+
return false;
|
|
21267
23130
|
}
|
|
23131
|
+
}
|
|
23132
|
+
async function verifyTool(toolYaml, policy = DEFAULT_POLICY) {
|
|
23133
|
+
const errors2 = [];
|
|
23134
|
+
const verifiedSigners = [];
|
|
21268
23135
|
try {
|
|
21269
|
-
const
|
|
21270
|
-
if (
|
|
21271
|
-
return
|
|
23136
|
+
const trustedKeys = getTrustedPublicKeysMap();
|
|
23137
|
+
if (trustedKeys.size === 0) {
|
|
23138
|
+
return {
|
|
23139
|
+
isValid: false,
|
|
23140
|
+
message: "No trusted public keys available",
|
|
23141
|
+
validSignatures: 0,
|
|
23142
|
+
totalSignatures: 0,
|
|
23143
|
+
verifiedSigners: [],
|
|
23144
|
+
errors: ["No trusted keys configured"]
|
|
23145
|
+
};
|
|
23146
|
+
}
|
|
23147
|
+
if (process.env.DEBUG) {
|
|
23148
|
+
console.error("Trusted keys available:");
|
|
23149
|
+
for (const [key, pem] of trustedKeys.entries()) {
|
|
23150
|
+
console.error(` Key: ${key.substring(0, 20)}...`);
|
|
23151
|
+
}
|
|
23152
|
+
}
|
|
23153
|
+
const tool = typeof toolYaml === "string" ? import_yaml.parse(toolYaml) : toolYaml;
|
|
23154
|
+
if (!tool.signatures || Object.keys(tool.signatures).length === 0) {
|
|
23155
|
+
return {
|
|
23156
|
+
isValid: false,
|
|
23157
|
+
message: "No signatures found in the tool",
|
|
23158
|
+
validSignatures: 0,
|
|
23159
|
+
totalSignatures: 0,
|
|
23160
|
+
verifiedSigners: [],
|
|
23161
|
+
errors: ["No signatures found"]
|
|
23162
|
+
};
|
|
23163
|
+
}
|
|
23164
|
+
const totalSignatures = Object.keys(tool.signatures).length;
|
|
23165
|
+
const toolForVerification = { ...tool };
|
|
23166
|
+
delete toolForVerification.signatures;
|
|
23167
|
+
const toolHashBytes = await hashTool(toolForVerification);
|
|
23168
|
+
if (true) {
|
|
23169
|
+
console.error("=== VERIFICATION DEBUG (WEBAPP COMPATIBLE) ===");
|
|
23170
|
+
console.error("Original tool signature field:", Object.keys(tool.signatures || {}));
|
|
23171
|
+
console.error("Tool before removing signatures:", JSON.stringify(tool, null, 2));
|
|
23172
|
+
console.error("Tool for verification:", JSON.stringify(toolForVerification, null, 2));
|
|
23173
|
+
console.error("Tool hash bytes length:", toolHashBytes.length, "(should be 32 for SHA-256)");
|
|
23174
|
+
console.error("==============================================");
|
|
23175
|
+
}
|
|
23176
|
+
let validSignatures = 0;
|
|
23177
|
+
for (const [publicKeyBase64, signatureData] of Object.entries(tool.signatures)) {
|
|
23178
|
+
try {
|
|
23179
|
+
if (policy.allowedAlgorithms && !policy.allowedAlgorithms.includes(signatureData.algorithm)) {
|
|
23180
|
+
errors2.push(`Signature by ${signatureData.signer}: unsupported algorithm ${signatureData.algorithm}`);
|
|
23181
|
+
continue;
|
|
23182
|
+
}
|
|
23183
|
+
if (policy.trustedSigners && !policy.trustedSigners.includes(signatureData.signer)) {
|
|
23184
|
+
errors2.push(`Signature by ${signatureData.signer}: signer not in trusted list`);
|
|
23185
|
+
continue;
|
|
23186
|
+
}
|
|
23187
|
+
const publicKeyPem = trustedKeys.get(publicKeyBase64);
|
|
23188
|
+
if (!publicKeyPem) {
|
|
23189
|
+
const reconstructedPem = base64ToPem(publicKeyBase64);
|
|
23190
|
+
if (!trustedKeys.has(pemToBase64(reconstructedPem))) {
|
|
23191
|
+
errors2.push(`Signature by ${signatureData.signer}: public key not trusted`);
|
|
23192
|
+
continue;
|
|
23193
|
+
}
|
|
23194
|
+
}
|
|
23195
|
+
if (process.env.DEBUG) {
|
|
23196
|
+
console.error("Looking for public key:", publicKeyBase64);
|
|
23197
|
+
console.error("Key found in trusted keys:", !!publicKeyPem);
|
|
23198
|
+
}
|
|
23199
|
+
let isValid3 = false;
|
|
23200
|
+
try {
|
|
23201
|
+
const publicKeyToUse = publicKeyPem || base64ToPem(publicKeyBase64);
|
|
23202
|
+
if (process.env.DEBUG) {
|
|
23203
|
+
console.error("Signature base64:", signatureData.value);
|
|
23204
|
+
console.error("Signature buffer length (should be 64):", Buffer.from(signatureData.value, "base64").length);
|
|
23205
|
+
console.error("Public key base64:", publicKeyBase64);
|
|
23206
|
+
}
|
|
23207
|
+
if (signatureData.type === "ecdsa-p256") {
|
|
23208
|
+
const { webcrypto } = await import("node:crypto");
|
|
23209
|
+
const publicKeyData = crypto.createPublicKey({
|
|
23210
|
+
key: publicKeyToUse,
|
|
23211
|
+
format: "pem",
|
|
23212
|
+
type: "spki"
|
|
23213
|
+
}).export({ format: "der", type: "spki" });
|
|
23214
|
+
const publicKeyObj = await webcrypto.subtle.importKey("spki", publicKeyData, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
|
|
23215
|
+
isValid3 = await verifyToolSignature(toolForVerification, signatureData.value, publicKeyObj);
|
|
23216
|
+
if (process.env.DEBUG) {
|
|
23217
|
+
console.error("Web Crypto API verification result (webapp compatible):", isValid3);
|
|
23218
|
+
}
|
|
23219
|
+
} else {
|
|
23220
|
+
const verify = crypto.createVerify("SHA256");
|
|
23221
|
+
const canonicalJson = createCanonicalToolJson(toolForVerification);
|
|
23222
|
+
verify.update(canonicalJson, "utf8");
|
|
23223
|
+
const signature = Buffer.from(signatureData.value, "base64");
|
|
23224
|
+
isValid3 = verify.verify(publicKeyToUse, signature);
|
|
23225
|
+
}
|
|
23226
|
+
} catch (verifyError) {
|
|
23227
|
+
errors2.push(`Signature by ${signatureData.signer}: verification error - ${verifyError.message}`);
|
|
23228
|
+
continue;
|
|
23229
|
+
}
|
|
23230
|
+
if (isValid3) {
|
|
23231
|
+
validSignatures++;
|
|
23232
|
+
verifiedSigners.push({
|
|
23233
|
+
signer: signatureData.signer,
|
|
23234
|
+
role: signatureData.role,
|
|
23235
|
+
keyId: publicKeyBase64.substring(0, 8)
|
|
23236
|
+
});
|
|
23237
|
+
} else {
|
|
23238
|
+
errors2.push(`Signature by ${signatureData.signer}: cryptographic verification failed`);
|
|
23239
|
+
}
|
|
23240
|
+
} catch (error) {
|
|
23241
|
+
errors2.push(`Signature by ${signatureData.signer}: verification error - ${error.message}`);
|
|
23242
|
+
}
|
|
23243
|
+
}
|
|
23244
|
+
const policyErrors = [];
|
|
23245
|
+
if (policy.minimumSignatures && validSignatures < policy.minimumSignatures) {
|
|
23246
|
+
policyErrors.push(`Policy requires ${policy.minimumSignatures} signatures, but only ${validSignatures} valid`);
|
|
23247
|
+
}
|
|
23248
|
+
if (policy.requireRoles && policy.requireRoles.length > 0) {
|
|
23249
|
+
const verifiedRoles = verifiedSigners.map((s) => s.role).filter(Boolean);
|
|
23250
|
+
const missingRoles = policy.requireRoles.filter((role) => !verifiedRoles.includes(role));
|
|
23251
|
+
if (missingRoles.length > 0) {
|
|
23252
|
+
policyErrors.push(`Policy requires roles: ${missingRoles.join(", ")}`);
|
|
23253
|
+
}
|
|
23254
|
+
}
|
|
23255
|
+
const isValid2 = policyErrors.length === 0 && validSignatures > 0;
|
|
23256
|
+
const allErrors = [...errors2, ...policyErrors];
|
|
23257
|
+
let message;
|
|
23258
|
+
if (isValid2) {
|
|
23259
|
+
message = `Tool "${tool.name}" verified with ${validSignatures}/${totalSignatures} valid signatures`;
|
|
23260
|
+
if (verifiedSigners.length > 0) {
|
|
23261
|
+
const signerInfo = verifiedSigners.map((s) => `${s.signer}${s.role ? ` (${s.role})` : ""}`).join(", ");
|
|
23262
|
+
message += ` from: ${signerInfo}`;
|
|
23263
|
+
}
|
|
21272
23264
|
} else {
|
|
21273
|
-
|
|
23265
|
+
message = `Tool "${tool.name}" verification failed: ${allErrors[0] || "Unknown error"}`;
|
|
21274
23266
|
}
|
|
23267
|
+
return {
|
|
23268
|
+
isValid: isValid2,
|
|
23269
|
+
message,
|
|
23270
|
+
validSignatures,
|
|
23271
|
+
totalSignatures,
|
|
23272
|
+
verifiedSigners,
|
|
23273
|
+
errors: allErrors
|
|
23274
|
+
};
|
|
21275
23275
|
} catch (error) {
|
|
21276
|
-
|
|
21277
|
-
|
|
21278
|
-
|
|
21279
|
-
|
|
21280
|
-
|
|
21281
|
-
|
|
21282
|
-
|
|
21283
|
-
|
|
21284
|
-
const envVars = {};
|
|
21285
|
-
for (const [name, envVar] of Object.entries(config.variables)) {
|
|
21286
|
-
const value = envVar.encrypted ? decryptValue(envVar.value) : envVar.value;
|
|
21287
|
-
envVars[name] = value;
|
|
23276
|
+
return {
|
|
23277
|
+
isValid: false,
|
|
23278
|
+
message: `Verification error: ${error.message}`,
|
|
23279
|
+
validSignatures: 0,
|
|
23280
|
+
totalSignatures: 0,
|
|
23281
|
+
verifiedSigners: [],
|
|
23282
|
+
errors: [error.message]
|
|
23283
|
+
};
|
|
21288
23284
|
}
|
|
21289
|
-
return envVars;
|
|
21290
23285
|
}
|
|
21291
|
-
|
|
21292
|
-
|
|
21293
|
-
|
|
23286
|
+
var VERIFICATION_POLICIES = {
|
|
23287
|
+
PERMISSIVE: {
|
|
23288
|
+
minimumSignatures: 1,
|
|
23289
|
+
allowedAlgorithms: ["sha256"]
|
|
23290
|
+
},
|
|
23291
|
+
ENTERPRISE: {
|
|
23292
|
+
minimumSignatures: 2,
|
|
23293
|
+
requireRoles: ["author", "reviewer"],
|
|
23294
|
+
allowedAlgorithms: ["sha256"]
|
|
23295
|
+
},
|
|
23296
|
+
PARANOID: {
|
|
23297
|
+
minimumSignatures: 3,
|
|
23298
|
+
requireRoles: ["author", "reviewer", "approver"],
|
|
23299
|
+
allowedAlgorithms: ["sha256"]
|
|
21294
23300
|
}
|
|
21295
|
-
|
|
21296
|
-
|
|
21297
|
-
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
|
|
21302
|
-
|
|
21303
|
-
|
|
21304
|
-
|
|
21305
|
-
|
|
23301
|
+
};
|
|
23302
|
+
|
|
23303
|
+
// src/security/verification-enforcer.ts
|
|
23304
|
+
init_logger();
|
|
23305
|
+
async function enforceSignatureVerification(tool, options = {}) {
|
|
23306
|
+
const toolName = tool.name || "unknown";
|
|
23307
|
+
if (options.skipVerification) {
|
|
23308
|
+
logger_default.warn(`\uD83D\uDEA8 SECURITY WARNING: Signature verification skipped for tool: ${toolName}`);
|
|
23309
|
+
logger_default.warn(` This bypasses security measures and is NOT recommended for production use!`);
|
|
23310
|
+
return {
|
|
23311
|
+
allowed: true,
|
|
23312
|
+
reason: `Verification skipped by request for tool: ${toolName}`,
|
|
23313
|
+
verificationResult: {
|
|
23314
|
+
isValid: false,
|
|
23315
|
+
message: "Verification skipped",
|
|
23316
|
+
validSignatures: 0,
|
|
23317
|
+
totalSignatures: 0,
|
|
23318
|
+
verifiedSigners: [],
|
|
23319
|
+
errors: ["Signature verification was explicitly skipped"]
|
|
23320
|
+
}
|
|
23321
|
+
};
|
|
21306
23322
|
}
|
|
21307
|
-
|
|
21308
|
-
|
|
21309
|
-
|
|
21310
|
-
|
|
21311
|
-
|
|
21312
|
-
|
|
21313
|
-
|
|
21314
|
-
|
|
21315
|
-
|
|
21316
|
-
|
|
21317
|
-
|
|
21318
|
-
|
|
23323
|
+
const hasSignatures = !!(tool.signatures && Object.keys(tool.signatures).length > 0) || !!tool.signature;
|
|
23324
|
+
if (!hasSignatures) {
|
|
23325
|
+
logger_default.warn(`⚠️ Tool has no signatures: ${toolName}`);
|
|
23326
|
+
if (options.allowUnsigned) {
|
|
23327
|
+
logger_default.warn(` Allowing unsigned tool execution due to allowUnsigned flag (DEV/TEST ONLY)`);
|
|
23328
|
+
return {
|
|
23329
|
+
allowed: true,
|
|
23330
|
+
reason: `Unsigned tool allowed by explicit permission: ${toolName}`,
|
|
23331
|
+
verificationResult: {
|
|
23332
|
+
isValid: false,
|
|
23333
|
+
message: "No signatures found, but execution allowed",
|
|
23334
|
+
validSignatures: 0,
|
|
23335
|
+
totalSignatures: 0,
|
|
23336
|
+
verifiedSigners: [],
|
|
23337
|
+
errors: ["Tool has no signatures but execution was explicitly allowed"]
|
|
23338
|
+
}
|
|
23339
|
+
};
|
|
21319
23340
|
}
|
|
23341
|
+
return {
|
|
23342
|
+
allowed: false,
|
|
23343
|
+
reason: `Tool has no signatures and unsigned execution is not permitted: ${toolName}`,
|
|
23344
|
+
error: {
|
|
23345
|
+
message: `Tool "${toolName}" has no cryptographic signatures. For security, only signed tools can be executed.`,
|
|
23346
|
+
code: "NO_SIGNATURES_FOUND",
|
|
23347
|
+
details: {
|
|
23348
|
+
toolName,
|
|
23349
|
+
hasSignature: !!tool.signature,
|
|
23350
|
+
hasSignatures: !!tool.signatures,
|
|
23351
|
+
signatureCount: tool.signatures ? Object.keys(tool.signatures).length : 0
|
|
23352
|
+
}
|
|
23353
|
+
}
|
|
23354
|
+
};
|
|
21320
23355
|
}
|
|
21321
|
-
|
|
21322
|
-
|
|
21323
|
-
|
|
21324
|
-
|
|
21325
|
-
|
|
21326
|
-
|
|
21327
|
-
|
|
21328
|
-
|
|
21329
|
-
|
|
21330
|
-
|
|
21331
|
-
|
|
21332
|
-
|
|
23356
|
+
try {
|
|
23357
|
+
logger_default.info(`\uD83D\uDD10 Verifying signatures for tool: ${toolName}`);
|
|
23358
|
+
const policyKey = (options.verifyPolicy || "permissive").toUpperCase();
|
|
23359
|
+
const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
|
|
23360
|
+
logger_default.info(` Using verification policy: ${policyKey.toLowerCase()}`);
|
|
23361
|
+
if (policy.minimumSignatures) {
|
|
23362
|
+
logger_default.info(` Minimum signatures required: ${policy.minimumSignatures}`);
|
|
23363
|
+
}
|
|
23364
|
+
if (policy.requireRoles) {
|
|
23365
|
+
logger_default.info(` Required roles: ${policy.requireRoles.join(", ")}`);
|
|
23366
|
+
}
|
|
23367
|
+
const verificationResult = await verifyTool(tool, policy);
|
|
23368
|
+
if (verificationResult.isValid) {
|
|
23369
|
+
logger_default.info(`✅ Signature verification passed for tool: ${toolName}`);
|
|
23370
|
+
logger_default.info(` Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}`);
|
|
23371
|
+
if (verificationResult.verifiedSigners.length > 0) {
|
|
23372
|
+
logger_default.info(` Verified signers: ${verificationResult.verifiedSigners.map((s) => `${s.signer}${s.role ? ` (${s.role})` : ""}`).join(", ")}`);
|
|
23373
|
+
}
|
|
23374
|
+
return {
|
|
23375
|
+
allowed: true,
|
|
23376
|
+
reason: `Tool signature verification passed: ${verificationResult.message}`,
|
|
23377
|
+
verificationResult
|
|
23378
|
+
};
|
|
23379
|
+
} else {
|
|
23380
|
+
logger_default.error(`❌ Signature verification failed for tool: ${toolName}`);
|
|
23381
|
+
logger_default.error(` Policy: ${policyKey.toLowerCase()}`);
|
|
23382
|
+
logger_default.error(` Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}`);
|
|
23383
|
+
if (verificationResult.errors.length > 0) {
|
|
23384
|
+
logger_default.error(` Errors:`);
|
|
23385
|
+
verificationResult.errors.forEach((error) => logger_default.error(` - ${error}`));
|
|
23386
|
+
}
|
|
23387
|
+
return {
|
|
23388
|
+
allowed: false,
|
|
23389
|
+
reason: `Tool signature verification failed: ${verificationResult.message}`,
|
|
23390
|
+
verificationResult,
|
|
23391
|
+
error: {
|
|
23392
|
+
message: `Tool "${toolName}" failed signature verification. ${verificationResult.message}`,
|
|
23393
|
+
code: "SIGNATURE_VERIFICATION_FAILED",
|
|
23394
|
+
details: {
|
|
23395
|
+
toolName,
|
|
23396
|
+
policy: policyKey.toLowerCase(),
|
|
23397
|
+
validSignatures: verificationResult.validSignatures,
|
|
23398
|
+
totalSignatures: verificationResult.totalSignatures,
|
|
23399
|
+
errors: verificationResult.errors,
|
|
23400
|
+
verifiedSigners: verificationResult.verifiedSigners
|
|
21333
23401
|
}
|
|
21334
23402
|
}
|
|
21335
|
-
|
|
21336
|
-
}
|
|
23403
|
+
};
|
|
21337
23404
|
}
|
|
23405
|
+
} catch (error) {
|
|
23406
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown verification error";
|
|
23407
|
+
logger_default.error(`\uD83D\uDCA5 Signature verification error for tool: ${toolName} - ${errorMessage}`);
|
|
23408
|
+
return {
|
|
23409
|
+
allowed: false,
|
|
23410
|
+
reason: `Signature verification error: ${errorMessage}`,
|
|
23411
|
+
error: {
|
|
23412
|
+
message: `Signature verification failed due to error: ${errorMessage}`,
|
|
23413
|
+
code: "VERIFICATION_ERROR",
|
|
23414
|
+
details: { toolName, originalError: error }
|
|
23415
|
+
}
|
|
23416
|
+
};
|
|
21338
23417
|
}
|
|
21339
|
-
return { resolved, missing };
|
|
21340
23418
|
}
|
|
21341
|
-
|
|
23419
|
+
function createVerificationFailureResult(tool, verificationResult, executionId) {
|
|
23420
|
+
return {
|
|
23421
|
+
success: false,
|
|
23422
|
+
error: verificationResult.error || {
|
|
23423
|
+
message: verificationResult.reason,
|
|
23424
|
+
code: "VERIFICATION_FAILED"
|
|
23425
|
+
},
|
|
23426
|
+
metadata: {
|
|
23427
|
+
executionId,
|
|
23428
|
+
toolName: tool.name || "unknown",
|
|
23429
|
+
version: tool.version,
|
|
23430
|
+
executedAt: new Date().toISOString(),
|
|
23431
|
+
environment: "direct",
|
|
23432
|
+
command: tool.command
|
|
23433
|
+
}
|
|
23434
|
+
};
|
|
23435
|
+
}
|
|
23436
|
+
function logSecurityAudit(tool, verificationResult, executionAllowed, options) {
|
|
23437
|
+
const auditLog = {
|
|
23438
|
+
timestamp: new Date().toISOString(),
|
|
23439
|
+
tool: tool.name || "unknown",
|
|
23440
|
+
version: tool.version,
|
|
23441
|
+
command: tool.command,
|
|
23442
|
+
executionAllowed,
|
|
23443
|
+
verificationSkipped: options.skipVerification || false,
|
|
23444
|
+
verificationPolicy: options.verifyPolicy || "permissive",
|
|
23445
|
+
verificationResult: verificationResult.verificationResult ? {
|
|
23446
|
+
isValid: verificationResult.verificationResult.isValid,
|
|
23447
|
+
validSignatures: verificationResult.verificationResult.validSignatures,
|
|
23448
|
+
totalSignatures: verificationResult.verificationResult.totalSignatures,
|
|
23449
|
+
verifiedSigners: verificationResult.verificationResult.verifiedSigners
|
|
23450
|
+
} : null,
|
|
23451
|
+
errors: verificationResult.error ? [verificationResult.error.message] : []
|
|
23452
|
+
};
|
|
23453
|
+
logger_default.info(`\uD83D\uDD0D Security Audit Log:`, auditLog);
|
|
23454
|
+
}
|
|
21342
23455
|
|
|
21343
23456
|
// src/core/EnactCore.ts
|
|
21344
|
-
|
|
23457
|
+
import fs2 from "fs";
|
|
23458
|
+
import path2 from "path";
|
|
23459
|
+
var __dirname = "/Users/keithgroves/projects/keithagroves/enact-project/enact-cli/src/core";
|
|
21345
23460
|
|
|
21346
23461
|
class EnactCore {
|
|
21347
23462
|
apiClient;
|
|
@@ -21388,9 +23503,48 @@ class EnactCore {
|
|
|
21388
23503
|
return tools;
|
|
21389
23504
|
} catch (error) {
|
|
21390
23505
|
logger_default.error("Error searching tools:", error);
|
|
23506
|
+
if (error instanceof Error && error.message.includes("502")) {
|
|
23507
|
+
logger_default.info("Search API unavailable, trying fallback to local filtering...");
|
|
23508
|
+
return this.searchToolsFallback(options);
|
|
23509
|
+
}
|
|
21391
23510
|
throw new Error(`Search failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
21392
23511
|
}
|
|
21393
23512
|
}
|
|
23513
|
+
async searchToolsFallback(options) {
|
|
23514
|
+
try {
|
|
23515
|
+
logger_default.info("Using fallback search method...");
|
|
23516
|
+
const allTools = await this.apiClient.getTools({
|
|
23517
|
+
limit: options.limit || 100
|
|
23518
|
+
});
|
|
23519
|
+
const filteredTools = [];
|
|
23520
|
+
const query = options.query.toLowerCase();
|
|
23521
|
+
for (const result of allTools) {
|
|
23522
|
+
if (result.name) {
|
|
23523
|
+
try {
|
|
23524
|
+
const tool = await this.getToolByName(result.name);
|
|
23525
|
+
if (tool) {
|
|
23526
|
+
const matchesQuery = tool.name.toLowerCase().includes(query) || tool.description && tool.description.toLowerCase().includes(query) || tool.tags && tool.tags.some((tag) => tag.toLowerCase().includes(query));
|
|
23527
|
+
const matchesTags = !options.tags || !options.tags.length || tool.tags && options.tags.some((searchTag) => tool.tags.some((toolTag) => toolTag.toLowerCase().includes(searchTag.toLowerCase())));
|
|
23528
|
+
const matchesAuthor = !options.author || tool.authors && tool.authors.some((author) => author.name && author.name.toLowerCase().includes(options.author.toLowerCase()));
|
|
23529
|
+
if (matchesQuery && matchesTags && matchesAuthor) {
|
|
23530
|
+
filteredTools.push(tool);
|
|
23531
|
+
if (options.limit && filteredTools.length >= options.limit) {
|
|
23532
|
+
break;
|
|
23533
|
+
}
|
|
23534
|
+
}
|
|
23535
|
+
}
|
|
23536
|
+
} catch (error) {
|
|
23537
|
+
logger_default.warn(`Failed to fetch tool ${result.name} in fallback search:`, error);
|
|
23538
|
+
}
|
|
23539
|
+
}
|
|
23540
|
+
}
|
|
23541
|
+
logger_default.info(`Fallback search found ${filteredTools.length} tools`);
|
|
23542
|
+
return filteredTools;
|
|
23543
|
+
} catch (fallbackError) {
|
|
23544
|
+
logger_default.error("Fallback search also failed:", fallbackError);
|
|
23545
|
+
throw new Error(`Search failed (including fallback): ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
|
|
23546
|
+
}
|
|
23547
|
+
}
|
|
21394
23548
|
async getToolByName(name, version) {
|
|
21395
23549
|
try {
|
|
21396
23550
|
logger_default.info(`Fetching tool: ${name}${version ? `@${version}` : ""}`);
|
|
@@ -21401,12 +23555,12 @@ class EnactCore {
|
|
|
21401
23555
|
}
|
|
21402
23556
|
let tool;
|
|
21403
23557
|
if (response.content && typeof response.content === "string") {
|
|
21404
|
-
tool =
|
|
23558
|
+
tool = import_yaml2.default.parse(response.content);
|
|
21405
23559
|
} else if (response.raw_content && typeof response.raw_content === "string") {
|
|
21406
23560
|
try {
|
|
21407
23561
|
tool = JSON.parse(response.raw_content);
|
|
21408
23562
|
} catch {
|
|
21409
|
-
tool =
|
|
23563
|
+
tool = import_yaml2.default.parse(response.raw_content);
|
|
21410
23564
|
}
|
|
21411
23565
|
if (response.signature || response.signatures) {
|
|
21412
23566
|
tool.signature = response.signature;
|
|
@@ -21485,25 +23639,19 @@ class EnactCore {
|
|
|
21485
23639
|
try {
|
|
21486
23640
|
logger_default.info(`Executing tool: ${tool.name}`);
|
|
21487
23641
|
validateToolStructure(tool);
|
|
21488
|
-
|
|
21489
|
-
|
|
21490
|
-
|
|
21491
|
-
|
|
21492
|
-
|
|
21493
|
-
|
|
21494
|
-
|
|
21495
|
-
|
|
21496
|
-
|
|
21497
|
-
|
|
21498
|
-
|
|
21499
|
-
|
|
21500
|
-
|
|
21501
|
-
executedAt: new Date().toISOString(),
|
|
21502
|
-
environment: "direct",
|
|
21503
|
-
command: tool.command
|
|
21504
|
-
}
|
|
21505
|
-
};
|
|
21506
|
-
}
|
|
23642
|
+
const verificationResult = await enforceSignatureVerification(tool, {
|
|
23643
|
+
skipVerification: options.skipVerification,
|
|
23644
|
+
verifyPolicy: options.verifyPolicy,
|
|
23645
|
+
force: options.force,
|
|
23646
|
+
allowUnsigned: false
|
|
23647
|
+
});
|
|
23648
|
+
logSecurityAudit(tool, verificationResult, verificationResult.allowed, {
|
|
23649
|
+
skipVerification: options.skipVerification,
|
|
23650
|
+
verifyPolicy: options.verifyPolicy,
|
|
23651
|
+
force: options.force
|
|
23652
|
+
});
|
|
23653
|
+
if (!verificationResult.allowed) {
|
|
23654
|
+
return createVerificationFailureResult(tool, verificationResult, executionId);
|
|
21507
23655
|
}
|
|
21508
23656
|
const validatedInputs = validateInputs(tool, inputs);
|
|
21509
23657
|
const safetyCheck = verifyCommandSafety(tool.command, tool);
|
|
@@ -21599,7 +23747,7 @@ class EnactCore {
|
|
|
21599
23747
|
}
|
|
21600
23748
|
async executeRawTool(toolYaml, inputs = {}, options = {}) {
|
|
21601
23749
|
try {
|
|
21602
|
-
const tool =
|
|
23750
|
+
const tool = import_yaml2.default.parse(toolYaml);
|
|
21603
23751
|
if (!tool || typeof tool !== "object") {
|
|
21604
23752
|
throw new Error("Invalid tool definition: YAML must contain a tool object");
|
|
21605
23753
|
}
|
|
@@ -21635,7 +23783,32 @@ class EnactCore {
|
|
|
21635
23783
|
errors: [`Tool not found: ${name}`]
|
|
21636
23784
|
};
|
|
21637
23785
|
}
|
|
21638
|
-
|
|
23786
|
+
let publicKey;
|
|
23787
|
+
try {
|
|
23788
|
+
const keyPath = path2.resolve(__dirname, "../../keys/file-public.pem");
|
|
23789
|
+
publicKey = fs2.readFileSync(keyPath, "utf8");
|
|
23790
|
+
} catch (e) {
|
|
23791
|
+
logger_default.warn("Could not load public key for signature verification:", e);
|
|
23792
|
+
}
|
|
23793
|
+
if (!publicKey) {
|
|
23794
|
+
return {
|
|
23795
|
+
verified: false,
|
|
23796
|
+
signatures: [],
|
|
23797
|
+
policy: policy || "permissive",
|
|
23798
|
+
errors: ["Public key not found for signature verification"]
|
|
23799
|
+
};
|
|
23800
|
+
}
|
|
23801
|
+
const policyKey = (policy || "permissive").toUpperCase();
|
|
23802
|
+
const policyObj = VERIFICATION_POLICIES[policyKey];
|
|
23803
|
+
const verificationResult = await verifyTool(tool, policyObj);
|
|
23804
|
+
if (!verificationResult.isValid) {
|
|
23805
|
+
return {
|
|
23806
|
+
verified: false,
|
|
23807
|
+
signatures: [],
|
|
23808
|
+
policy: policy || "permissive",
|
|
23809
|
+
errors: verificationResult.errors
|
|
23810
|
+
};
|
|
23811
|
+
}
|
|
21639
23812
|
const signatures = [];
|
|
21640
23813
|
if (tool.signature) {
|
|
21641
23814
|
signatures.push(tool.signature);
|
|
@@ -21644,7 +23817,7 @@ class EnactCore {
|
|
|
21644
23817
|
signatures.push(...Object.values(tool.signatures));
|
|
21645
23818
|
}
|
|
21646
23819
|
return {
|
|
21647
|
-
verified,
|
|
23820
|
+
verified: verificationResult.isValid,
|
|
21648
23821
|
signatures,
|
|
21649
23822
|
policy: policy || "permissive"
|
|
21650
23823
|
};
|
|
@@ -21747,6 +23920,9 @@ class EnactCore {
|
|
|
21747
23920
|
}
|
|
21748
23921
|
var enactCore = new EnactCore;
|
|
21749
23922
|
|
|
23923
|
+
// src/mcp-server.ts
|
|
23924
|
+
init_logger();
|
|
23925
|
+
|
|
21750
23926
|
// src/utils/silent-monitor.ts
|
|
21751
23927
|
class McpSilentOperationMonitor {
|
|
21752
23928
|
isMonitoring = false;
|
|
@@ -21884,6 +24060,8 @@ function validateSilentEnvironment() {
|
|
|
21884
24060
|
}
|
|
21885
24061
|
|
|
21886
24062
|
// src/mcp-server.ts
|
|
24063
|
+
init_env_manager_server();
|
|
24064
|
+
init_env_loader();
|
|
21887
24065
|
process.env.CI = process.env.CI || "true";
|
|
21888
24066
|
process.env.ENACT_SKIP_INTERACTIVE = process.env.ENACT_SKIP_INTERACTIVE || "true";
|
|
21889
24067
|
if (true) {
|
|
@@ -21912,6 +24090,8 @@ var server = new McpServer({
|
|
|
21912
24090
|
}
|
|
21913
24091
|
});
|
|
21914
24092
|
var runningOperations = new Map;
|
|
24093
|
+
var webServerPort = null;
|
|
24094
|
+
var webServerInstance = null;
|
|
21915
24095
|
function safeJsonStringify(obj, fallback = "Unable to stringify object") {
|
|
21916
24096
|
try {
|
|
21917
24097
|
return JSON.stringify(obj, null, 2);
|
|
@@ -21920,6 +24100,58 @@ function safeJsonStringify(obj, fallback = "Unable to stringify object") {
|
|
|
21920
24100
|
return fallback;
|
|
21921
24101
|
}
|
|
21922
24102
|
}
|
|
24103
|
+
async function validateMcpToolEnvironmentVariables(toolName, toolEnv) {
|
|
24104
|
+
if (!toolEnv || Object.keys(toolEnv).length === 0) {
|
|
24105
|
+
return { valid: true };
|
|
24106
|
+
}
|
|
24107
|
+
try {
|
|
24108
|
+
const { resolved: envVars } = await resolveToolEnvironmentVariables(toolName, toolEnv);
|
|
24109
|
+
const validation = validateRequiredEnvironmentVariables(toolEnv, envVars);
|
|
24110
|
+
if (!validation.valid) {
|
|
24111
|
+
let errorMessage = `❌ Missing required environment variables:
|
|
24112
|
+
|
|
24113
|
+
`;
|
|
24114
|
+
validation.missing.forEach((varName) => {
|
|
24115
|
+
const config = toolEnv[varName];
|
|
24116
|
+
const description = config?.description ? ` - ${config.description}` : "";
|
|
24117
|
+
const source = config?.source ? ` (source: ${config.source})` : "";
|
|
24118
|
+
const required = config?.required ? " [REQUIRED]" : "";
|
|
24119
|
+
errorMessage += ` • ${varName}${required}${description}${source}
|
|
24120
|
+
`;
|
|
24121
|
+
});
|
|
24122
|
+
errorMessage += `
|
|
24123
|
+
\uD83D\uDCA1 You can set environment variables using:
|
|
24124
|
+
`;
|
|
24125
|
+
errorMessage += ` • enact env set <package> <VAR_NAME> <value> # Package-managed (shared)
|
|
24126
|
+
`;
|
|
24127
|
+
errorMessage += ` • enact env set <package> <VAR_NAME> --encrypt # For sensitive values
|
|
24128
|
+
`;
|
|
24129
|
+
errorMessage += ` • enact env set <VAR_NAME> <value> --project # Project-specific (.env file)
|
|
24130
|
+
`;
|
|
24131
|
+
const configLink = generateConfigLink(validation.missing, toolName);
|
|
24132
|
+
if (configLink) {
|
|
24133
|
+
errorMessage += `
|
|
24134
|
+
\uD83C\uDF10 Or use the web interface to configure all missing variables:
|
|
24135
|
+
`;
|
|
24136
|
+
errorMessage += ` ${configLink}
|
|
24137
|
+
`;
|
|
24138
|
+
}
|
|
24139
|
+
errorMessage += `
|
|
24140
|
+
⚠️ Execution aborted due to missing environment variables.`;
|
|
24141
|
+
return {
|
|
24142
|
+
valid: false,
|
|
24143
|
+
errorMessage
|
|
24144
|
+
};
|
|
24145
|
+
}
|
|
24146
|
+
return { valid: true };
|
|
24147
|
+
} catch (error) {
|
|
24148
|
+
logger_default.error("Failed to validate environment variables:", error);
|
|
24149
|
+
return {
|
|
24150
|
+
valid: false,
|
|
24151
|
+
errorMessage: `❌ Failed to validate environment variables: ${error instanceof Error ? error.message : String(error)}`
|
|
24152
|
+
};
|
|
24153
|
+
}
|
|
24154
|
+
}
|
|
21923
24155
|
server.registerTool("execute-tool-by-name-async", {
|
|
21924
24156
|
title: "Execute Enact Tool (Async)",
|
|
21925
24157
|
description: "Execute an Enact tool by its name using direct core integration with background execution for long-running operations",
|
|
@@ -21938,6 +24170,39 @@ server.registerTool("execute-tool-by-name-async", {
|
|
|
21938
24170
|
const { name, inputs = {}, timeout, verifyPolicy, skipVerification, force, dryRun, verbose, async = false } = params;
|
|
21939
24171
|
try {
|
|
21940
24172
|
logger_default.info(`Executing tool ${name} via direct core library`);
|
|
24173
|
+
let tool;
|
|
24174
|
+
try {
|
|
24175
|
+
tool = await enactCore2.getToolByName(name);
|
|
24176
|
+
if (!tool) {
|
|
24177
|
+
return {
|
|
24178
|
+
content: [{
|
|
24179
|
+
type: "text",
|
|
24180
|
+
text: `❌ Tool not found: ${name}`
|
|
24181
|
+
}],
|
|
24182
|
+
isError: true
|
|
24183
|
+
};
|
|
24184
|
+
}
|
|
24185
|
+
} catch (error) {
|
|
24186
|
+
return {
|
|
24187
|
+
content: [{
|
|
24188
|
+
type: "text",
|
|
24189
|
+
text: `❌ Tool not found: ${name}
|
|
24190
|
+
|
|
24191
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
24192
|
+
}],
|
|
24193
|
+
isError: true
|
|
24194
|
+
};
|
|
24195
|
+
}
|
|
24196
|
+
const envValidation = await validateMcpToolEnvironmentVariables(name, tool.env);
|
|
24197
|
+
if (!envValidation.valid) {
|
|
24198
|
+
return {
|
|
24199
|
+
content: [{
|
|
24200
|
+
type: "text",
|
|
24201
|
+
text: envValidation.errorMessage || "Environment validation failed"
|
|
24202
|
+
}],
|
|
24203
|
+
isError: true
|
|
24204
|
+
};
|
|
24205
|
+
}
|
|
21941
24206
|
const isLongRunningTool = name.includes("dagger") || name.includes("docker") || name.includes("build") || async;
|
|
21942
24207
|
if (isLongRunningTool) {
|
|
21943
24208
|
const operationId = `${name}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
@@ -22197,6 +24462,39 @@ server.registerTool("execute-tool-by-name", {
|
|
|
22197
24462
|
const { name, inputs = {}, timeout, verifyPolicy, skipVerification, force, dryRun, verbose } = params;
|
|
22198
24463
|
try {
|
|
22199
24464
|
logger_default.info(`Executing tool ${name} via direct core library`);
|
|
24465
|
+
let tool;
|
|
24466
|
+
try {
|
|
24467
|
+
tool = await enactCore2.getToolByName(name);
|
|
24468
|
+
if (!tool) {
|
|
24469
|
+
return {
|
|
24470
|
+
content: [{
|
|
24471
|
+
type: "text",
|
|
24472
|
+
text: `❌ Tool not found: ${name}`
|
|
24473
|
+
}],
|
|
24474
|
+
isError: true
|
|
24475
|
+
};
|
|
24476
|
+
}
|
|
24477
|
+
} catch (error) {
|
|
24478
|
+
return {
|
|
24479
|
+
content: [{
|
|
24480
|
+
type: "text",
|
|
24481
|
+
text: `❌ Tool not found: ${name}
|
|
24482
|
+
|
|
24483
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
24484
|
+
}],
|
|
24485
|
+
isError: true
|
|
24486
|
+
};
|
|
24487
|
+
}
|
|
24488
|
+
const envValidation = await validateMcpToolEnvironmentVariables(name, tool.env);
|
|
24489
|
+
if (!envValidation.valid) {
|
|
24490
|
+
return {
|
|
24491
|
+
content: [{
|
|
24492
|
+
type: "text",
|
|
24493
|
+
text: envValidation.errorMessage || "Environment validation failed"
|
|
24494
|
+
}],
|
|
24495
|
+
isError: true
|
|
24496
|
+
};
|
|
24497
|
+
}
|
|
22200
24498
|
const isLongRunningTool = name.includes("dagger") || name.includes("docker") || name.includes("build");
|
|
22201
24499
|
if (isLongRunningTool) {
|
|
22202
24500
|
logger_default.info(`⏳ Starting long-running operation: ${name} (this may take 1-2 minutes)`);
|
|
@@ -22348,69 +24646,30 @@ server.registerTool("enact-verify-tool", {
|
|
|
22348
24646
|
`;
|
|
22349
24647
|
resultText += `Policy: ${verificationResult.policy}
|
|
22350
24648
|
`;
|
|
22351
|
-
if (verificationResult.signatures && verificationResult.signatures.length > 0) {
|
|
22352
|
-
resultText += `Signatures found: ${verificationResult.signatures.length}
|
|
22353
|
-
`;
|
|
22354
|
-
}
|
|
22355
|
-
if (verificationResult.errors && verificationResult.errors.length > 0) {
|
|
22356
|
-
resultText += `Errors: ${verificationResult.errors.join(", ")}
|
|
22357
|
-
`;
|
|
22358
|
-
}
|
|
22359
|
-
resultText += `
|
|
22360
|
-
Full result:
|
|
22361
|
-
${safeJsonStringify(verificationResult)}`;
|
|
22362
|
-
return {
|
|
22363
|
-
content: [{
|
|
22364
|
-
type: "text",
|
|
22365
|
-
text: resultText
|
|
22366
|
-
}],
|
|
22367
|
-
isError: !verificationResult.verified
|
|
22368
|
-
};
|
|
22369
|
-
} catch (error) {
|
|
22370
|
-
logger_default.error(`Error verifying tool:`, error);
|
|
22371
|
-
return {
|
|
22372
|
-
content: [{
|
|
22373
|
-
type: "text",
|
|
22374
|
-
text: `Error verifying tool: ${error instanceof Error ? error.message : String(error)}`
|
|
22375
|
-
}],
|
|
22376
|
-
isError: true
|
|
22377
|
-
};
|
|
22378
|
-
}
|
|
22379
|
-
});
|
|
22380
|
-
server.registerTool("execute-raw-tool", {
|
|
22381
|
-
title: "Execute Raw Tool",
|
|
22382
|
-
description: "Execute an Enact tool from raw YAML definition using direct core integration",
|
|
22383
|
-
inputSchema: {
|
|
22384
|
-
yaml: exports_external.string().describe("YAML definition of the tool"),
|
|
22385
|
-
inputs: exports_external.record(exports_external.any()).optional().describe("Input parameters for the tool"),
|
|
22386
|
-
options: exports_external.record(exports_external.any()).optional().describe("Execution options")
|
|
22387
|
-
}
|
|
22388
|
-
}, async ({ yaml: toolYaml, inputs = {}, options = {} }) => {
|
|
22389
|
-
try {
|
|
22390
|
-
logger_default.info("Executing raw tool via direct core library");
|
|
22391
|
-
const result = await enactCore2.executeRawTool(toolYaml, inputs, options);
|
|
22392
|
-
if (!result.success) {
|
|
22393
|
-
return {
|
|
22394
|
-
content: [{
|
|
22395
|
-
type: "text",
|
|
22396
|
-
text: `Error executing raw tool: ${result.error?.message}`
|
|
22397
|
-
}],
|
|
22398
|
-
isError: true
|
|
22399
|
-
};
|
|
24649
|
+
if (verificationResult.signatures && verificationResult.signatures.length > 0) {
|
|
24650
|
+
resultText += `Signatures found: ${verificationResult.signatures.length}
|
|
24651
|
+
`;
|
|
24652
|
+
}
|
|
24653
|
+
if (verificationResult.errors && verificationResult.errors.length > 0) {
|
|
24654
|
+
resultText += `Errors: ${verificationResult.errors.join(", ")}
|
|
24655
|
+
`;
|
|
22400
24656
|
}
|
|
24657
|
+
resultText += `
|
|
24658
|
+
Full result:
|
|
24659
|
+
${safeJsonStringify(verificationResult)}`;
|
|
22401
24660
|
return {
|
|
22402
24661
|
content: [{
|
|
22403
24662
|
type: "text",
|
|
22404
|
-
text:
|
|
22405
|
-
|
|
22406
|
-
|
|
24663
|
+
text: resultText
|
|
24664
|
+
}],
|
|
24665
|
+
isError: !verificationResult.verified
|
|
22407
24666
|
};
|
|
22408
24667
|
} catch (error) {
|
|
22409
|
-
logger_default.error(`Error
|
|
24668
|
+
logger_default.error(`Error verifying tool:`, error);
|
|
22410
24669
|
return {
|
|
22411
24670
|
content: [{
|
|
22412
24671
|
type: "text",
|
|
22413
|
-
text: `
|
|
24672
|
+
text: `Error verifying tool: ${error instanceof Error ? error.message : String(error)}`
|
|
22414
24673
|
}],
|
|
22415
24674
|
isError: true
|
|
22416
24675
|
};
|
|
@@ -22476,16 +24735,17 @@ server.registerTool("enact-tool-exists", {
|
|
|
22476
24735
|
});
|
|
22477
24736
|
server.registerTool("enact-search-and-register-tools", {
|
|
22478
24737
|
title: "Search and Register Tools",
|
|
22479
|
-
description: "Search tools and register the first result as a tool using direct core integration",
|
|
24738
|
+
description: "Search tools and register the first result as a tool using direct core integration with signature verification",
|
|
22480
24739
|
inputSchema: {
|
|
22481
24740
|
query: exports_external.string().describe("Search query for tools"),
|
|
22482
24741
|
limit: exports_external.number().optional().describe("Maximum number of results"),
|
|
22483
24742
|
tags: exports_external.array(exports_external.string()).optional().describe("Filter by tags"),
|
|
22484
|
-
author: exports_external.string().optional().describe("Filter by author")
|
|
24743
|
+
author: exports_external.string().optional().describe("Filter by author"),
|
|
24744
|
+
verifyPolicy: exports_external.enum(["permissive", "enterprise", "paranoid"]).optional().describe("Verification policy for signature checking")
|
|
22485
24745
|
}
|
|
22486
|
-
}, async ({ query, limit, tags, author }) => {
|
|
24746
|
+
}, async ({ query, limit, tags, author, verifyPolicy = "permissive" }) => {
|
|
22487
24747
|
try {
|
|
22488
|
-
logger_default.info(`Searching and registering tools via direct core library: "${query}"`);
|
|
24748
|
+
logger_default.info(`Searching and registering tools via direct core library: "${query}" with policy: ${verifyPolicy}`);
|
|
22489
24749
|
const tools = await enactCore2.searchTools({
|
|
22490
24750
|
query,
|
|
22491
24751
|
limit,
|
|
@@ -22498,7 +24758,35 @@ server.registerTool("enact-search-and-register-tools", {
|
|
|
22498
24758
|
const firstTool = tools[0];
|
|
22499
24759
|
if (firstTool.name) {
|
|
22500
24760
|
try {
|
|
22501
|
-
|
|
24761
|
+
logger_default.info(`Verifying tool signatures for: ${firstTool.name} with policy: ${verifyPolicy}`);
|
|
24762
|
+
const policyKey = verifyPolicy.toUpperCase();
|
|
24763
|
+
const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
|
|
24764
|
+
const verificationResult = await verifyTool(firstTool, policy);
|
|
24765
|
+
if (!verificationResult.isValid) {
|
|
24766
|
+
logger_default.error(`Tool "${firstTool.name}" signature verification failed: ${verificationResult.message}`);
|
|
24767
|
+
return {
|
|
24768
|
+
content: [{
|
|
24769
|
+
type: "text",
|
|
24770
|
+
text: `❌ Tool "${firstTool.name}" signature verification failed.
|
|
24771
|
+
|
|
24772
|
+
Policy: ${verifyPolicy}
|
|
24773
|
+
Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}
|
|
24774
|
+
|
|
24775
|
+
Errors:
|
|
24776
|
+
${verificationResult.errors.map((e) => ` • ${e}`).join(`
|
|
24777
|
+
`)}
|
|
24778
|
+
|
|
24779
|
+
\uD83D\uDCA1 Use 'enact-register-tool' with a different verification policy or ensure the tool has valid signatures.`
|
|
24780
|
+
}],
|
|
24781
|
+
isError: true
|
|
24782
|
+
};
|
|
24783
|
+
}
|
|
24784
|
+
logger_default.info(`✅ Tool "${firstTool.name}" signature verification passed: ${verificationResult.message}`);
|
|
24785
|
+
await registerDynamicTool(firstTool, {
|
|
24786
|
+
isValid: verificationResult.isValid,
|
|
24787
|
+
message: verificationResult.message,
|
|
24788
|
+
policy: verifyPolicy
|
|
24789
|
+
});
|
|
22502
24790
|
newlyRegistered = 1;
|
|
22503
24791
|
logger_default.info(`Successfully registered tool: ${firstTool.name}`);
|
|
22504
24792
|
} catch (err) {
|
|
@@ -22565,6 +24853,8 @@ server.registerTool("enact-core-status", {
|
|
|
22565
24853
|
statusText += `• ✅ Command safety verification
|
|
22566
24854
|
`;
|
|
22567
24855
|
statusText += `• ✅ Output schema validation
|
|
24856
|
+
`;
|
|
24857
|
+
statusText += `• \uD83C\uDF10 Web-based environment manager
|
|
22568
24858
|
|
|
22569
24859
|
`;
|
|
22570
24860
|
statusText += `Performance Benefits:
|
|
@@ -22596,9 +24886,361 @@ server.registerTool("enact-core-status", {
|
|
|
22596
24886
|
};
|
|
22597
24887
|
}
|
|
22598
24888
|
});
|
|
22599
|
-
|
|
24889
|
+
server.registerTool("launch-env-manager-server", {
|
|
24890
|
+
title: "Launch Environment Manager Server",
|
|
24891
|
+
description: "Start the web-based environment variable manager server asynchronously",
|
|
24892
|
+
inputSchema: {
|
|
24893
|
+
port: exports_external.number().optional().describe("Port to run the server on (default: 5555)"),
|
|
24894
|
+
async: exports_external.boolean().optional().describe("Run in background (default: true)")
|
|
24895
|
+
}
|
|
24896
|
+
}, async ({ port = 5555, async = true }) => {
|
|
24897
|
+
try {
|
|
24898
|
+
if (webServerInstance) {
|
|
24899
|
+
return {
|
|
24900
|
+
content: [{
|
|
24901
|
+
type: "text",
|
|
24902
|
+
text: `\uD83C\uDF10 Environment Manager Server is already running on port ${webServerPort}
|
|
24903
|
+
|
|
24904
|
+
URL: http://localhost:${webServerPort}`
|
|
24905
|
+
}]
|
|
24906
|
+
};
|
|
24907
|
+
}
|
|
24908
|
+
if (async) {
|
|
24909
|
+
const operationId = `web-server-launch-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
24910
|
+
const launchPromise = startEnvManagerServer(port).then(({ server: webServer, port: actualPort }) => {
|
|
24911
|
+
webServerInstance = webServer;
|
|
24912
|
+
webServerPort = actualPort;
|
|
24913
|
+
logger_default.info(`\uD83C\uDF10 Environment Manager available at http://localhost:${actualPort}`);
|
|
24914
|
+
return { server: webServer, port: actualPort };
|
|
24915
|
+
});
|
|
24916
|
+
const operation = {
|
|
24917
|
+
id: operationId,
|
|
24918
|
+
name: "launch-env-manager-server",
|
|
24919
|
+
startTime: new Date,
|
|
24920
|
+
promise: launchPromise,
|
|
24921
|
+
status: "running",
|
|
24922
|
+
result: undefined,
|
|
24923
|
+
error: undefined
|
|
24924
|
+
};
|
|
24925
|
+
runningOperations.set(operationId, operation);
|
|
24926
|
+
launchPromise.then((result) => {
|
|
24927
|
+
operation.status = "completed";
|
|
24928
|
+
operation.result = result;
|
|
24929
|
+
logger_default.info(`Environment Manager Server started successfully on port ${result.port}`);
|
|
24930
|
+
}).catch((error) => {
|
|
24931
|
+
operation.status = "failed";
|
|
24932
|
+
operation.error = error;
|
|
24933
|
+
logger_default.error(`Failed to start Environment Manager Server:`, error);
|
|
24934
|
+
});
|
|
24935
|
+
return {
|
|
24936
|
+
content: [{
|
|
24937
|
+
type: "text",
|
|
24938
|
+
text: `\uD83D\uDE80 Starting Environment Manager Server asynchronously on port ${port}
|
|
24939
|
+
|
|
24940
|
+
Operation ID: ${operationId}
|
|
24941
|
+
Started: ${operation.startTime.toISOString()}
|
|
24942
|
+
|
|
24943
|
+
⏳ Use "check-operation-status" with operation ID "${operationId}" to check when the server is ready.
|
|
24944
|
+
|
|
24945
|
+
Once running, the server will be available at: http://localhost:${port}`
|
|
24946
|
+
}]
|
|
24947
|
+
};
|
|
24948
|
+
} else {
|
|
24949
|
+
const { server: webServer, port: actualPort } = await startEnvManagerServer(port);
|
|
24950
|
+
webServerInstance = webServer;
|
|
24951
|
+
webServerPort = actualPort;
|
|
24952
|
+
return {
|
|
24953
|
+
content: [{
|
|
24954
|
+
type: "text",
|
|
24955
|
+
text: `✅ Environment Manager Server started successfully!
|
|
24956
|
+
|
|
24957
|
+
URL: http://localhost:${actualPort}
|
|
24958
|
+
|
|
24959
|
+
The environment manager allows you to:
|
|
24960
|
+
• View all package namespaces and their environment variables
|
|
24961
|
+
• Add, edit, and delete environment variables
|
|
24962
|
+
• Create new package namespaces
|
|
24963
|
+
• Manage variables following the Enact package structure
|
|
24964
|
+
|
|
24965
|
+
Environment variables are stored in ~/.enact/env/ organized by package namespace.`
|
|
24966
|
+
}]
|
|
24967
|
+
};
|
|
24968
|
+
}
|
|
24969
|
+
} catch (error) {
|
|
24970
|
+
logger_default.error(`Error launching Environment Manager Server:`, error);
|
|
24971
|
+
return {
|
|
24972
|
+
content: [{
|
|
24973
|
+
type: "text",
|
|
24974
|
+
text: `❌ Error launching Environment Manager Server: ${error instanceof Error ? error.message : String(error)}`
|
|
24975
|
+
}],
|
|
24976
|
+
isError: true
|
|
24977
|
+
};
|
|
24978
|
+
}
|
|
24979
|
+
});
|
|
24980
|
+
server.registerTool("close-env-manager-server", {
|
|
24981
|
+
title: "Close Environment Manager Server",
|
|
24982
|
+
description: "Stop the web-based environment variable manager server",
|
|
24983
|
+
inputSchema: {
|
|
24984
|
+
force: exports_external.boolean().optional().describe("Force close the server (default: false)")
|
|
24985
|
+
}
|
|
24986
|
+
}, async ({ force = false }) => {
|
|
24987
|
+
try {
|
|
24988
|
+
if (!webServerInstance) {
|
|
24989
|
+
return {
|
|
24990
|
+
content: [{
|
|
24991
|
+
type: "text",
|
|
24992
|
+
text: `ℹ️ Environment Manager Server is not currently running`
|
|
24993
|
+
}]
|
|
24994
|
+
};
|
|
24995
|
+
}
|
|
24996
|
+
const currentPort = webServerPort;
|
|
24997
|
+
return new Promise((resolve) => {
|
|
24998
|
+
const timeout = force ? 1000 : 5000;
|
|
24999
|
+
const cleanup = () => {
|
|
25000
|
+
webServerInstance = null;
|
|
25001
|
+
webServerPort = null;
|
|
25002
|
+
resolve({
|
|
25003
|
+
content: [{
|
|
25004
|
+
type: "text",
|
|
25005
|
+
text: `✅ Environment Manager Server stopped successfully
|
|
25006
|
+
|
|
25007
|
+
Server was running on port ${currentPort}`
|
|
25008
|
+
}]
|
|
25009
|
+
});
|
|
25010
|
+
};
|
|
25011
|
+
if (force) {
|
|
25012
|
+
webServerInstance.close(cleanup);
|
|
25013
|
+
setTimeout(cleanup, timeout);
|
|
25014
|
+
} else {
|
|
25015
|
+
webServerInstance.close((err) => {
|
|
25016
|
+
if (err) {
|
|
25017
|
+
logger_default.error("Error during graceful shutdown:", err);
|
|
25018
|
+
resolve({
|
|
25019
|
+
content: [{
|
|
25020
|
+
type: "text",
|
|
25021
|
+
text: `⚠️ Server closed with warnings: ${err.message}
|
|
25022
|
+
|
|
25023
|
+
Server was running on port ${currentPort}`
|
|
25024
|
+
}]
|
|
25025
|
+
});
|
|
25026
|
+
} else {
|
|
25027
|
+
cleanup();
|
|
25028
|
+
}
|
|
25029
|
+
});
|
|
25030
|
+
setTimeout(() => {
|
|
25031
|
+
logger_default.warn("Graceful shutdown timeout, forcing close");
|
|
25032
|
+
cleanup();
|
|
25033
|
+
}, timeout);
|
|
25034
|
+
}
|
|
25035
|
+
});
|
|
25036
|
+
} catch (error) {
|
|
25037
|
+
logger_default.error(`Error closing Environment Manager Server:`, error);
|
|
25038
|
+
return {
|
|
25039
|
+
content: [{
|
|
25040
|
+
type: "text",
|
|
25041
|
+
text: `❌ Error closing Environment Manager Server: ${error instanceof Error ? error.message : String(error)}`
|
|
25042
|
+
}],
|
|
25043
|
+
isError: true
|
|
25044
|
+
};
|
|
25045
|
+
}
|
|
25046
|
+
});
|
|
25047
|
+
server.registerTool("get-env-manager-status", {
|
|
25048
|
+
title: "Get Environment Manager Status",
|
|
25049
|
+
description: "Check if the environment manager server is running and get its status",
|
|
25050
|
+
inputSchema: {}
|
|
25051
|
+
}, async () => {
|
|
25052
|
+
try {
|
|
25053
|
+
if (!webServerInstance || !webServerPort) {
|
|
25054
|
+
return {
|
|
25055
|
+
content: [{
|
|
25056
|
+
type: "text",
|
|
25057
|
+
text: `\uD83D\uDCCA Environment Manager Server Status: STOPPED
|
|
25058
|
+
|
|
25059
|
+
The server is not currently running.
|
|
25060
|
+
|
|
25061
|
+
\uD83D\uDCA1 Use "launch-env-manager-server" to start the server.`
|
|
25062
|
+
}]
|
|
25063
|
+
};
|
|
25064
|
+
}
|
|
25065
|
+
const isListening = webServerInstance.listening;
|
|
25066
|
+
return {
|
|
25067
|
+
content: [{
|
|
25068
|
+
type: "text",
|
|
25069
|
+
text: `\uD83D\uDCCA Environment Manager Server Status: ${isListening ? "RUNNING" : "STOPPED"}
|
|
25070
|
+
|
|
25071
|
+
${isListening ? `\uD83C\uDF10 URL: http://localhost:${webServerPort}
|
|
25072
|
+
|
|
25073
|
+
The environment manager allows you to:
|
|
25074
|
+
• View all package namespaces and their environment variables
|
|
25075
|
+
• Add, edit, and delete environment variables
|
|
25076
|
+
• Create new package namespaces
|
|
25077
|
+
• Manage variables following the Enact package structure` : "Server instance exists but is not listening"}
|
|
25078
|
+
|
|
25079
|
+
Environment variables are stored in ~/.enact/env/ organized by package namespace.`
|
|
25080
|
+
}]
|
|
25081
|
+
};
|
|
25082
|
+
} catch (error) {
|
|
25083
|
+
logger_default.error(`Error getting Environment Manager Server status:`, error);
|
|
25084
|
+
return {
|
|
25085
|
+
content: [{
|
|
25086
|
+
type: "text",
|
|
25087
|
+
text: `❌ Error getting Environment Manager Server status: ${error instanceof Error ? error.message : String(error)}`
|
|
25088
|
+
}],
|
|
25089
|
+
isError: true
|
|
25090
|
+
};
|
|
25091
|
+
}
|
|
25092
|
+
});
|
|
25093
|
+
server.registerTool("get-env-manager-url", {
|
|
25094
|
+
title: "Get Environment Manager URL",
|
|
25095
|
+
description: "Get the URL for the web-based environment variable manager",
|
|
25096
|
+
inputSchema: {}
|
|
25097
|
+
}, async () => {
|
|
25098
|
+
try {
|
|
25099
|
+
const port = webServerPort || 5555;
|
|
25100
|
+
return {
|
|
25101
|
+
content: [{
|
|
25102
|
+
type: "text",
|
|
25103
|
+
text: `\uD83C\uDF10 Environment Manager Web Interface
|
|
25104
|
+
|
|
25105
|
+
URL: http://localhost:${port}
|
|
25106
|
+
|
|
25107
|
+
The environment manager allows you to:
|
|
25108
|
+
• View all package namespaces and their environment variables
|
|
25109
|
+
• Add, edit, and delete environment variables
|
|
25110
|
+
• Create new package namespaces
|
|
25111
|
+
• Manage variables following the Enact package structure
|
|
25112
|
+
|
|
25113
|
+
Environment variables are stored in ~/.enact/env/ organized by package namespace.`
|
|
25114
|
+
}]
|
|
25115
|
+
};
|
|
25116
|
+
} catch (error) {
|
|
25117
|
+
logger_default.error(`Error getting env manager URL:`, error);
|
|
25118
|
+
return {
|
|
25119
|
+
content: [{
|
|
25120
|
+
type: "text",
|
|
25121
|
+
text: `Error getting environment manager URL: ${error instanceof Error ? error.message : String(error)}`
|
|
25122
|
+
}],
|
|
25123
|
+
isError: true
|
|
25124
|
+
};
|
|
25125
|
+
}
|
|
25126
|
+
});
|
|
25127
|
+
server.registerTool("list-package-env-vars", {
|
|
25128
|
+
title: "List Package Environment Variables",
|
|
25129
|
+
description: "List environment variables for a specific package namespace",
|
|
25130
|
+
inputSchema: {
|
|
25131
|
+
namespace: exports_external.string().describe("Package namespace (e.g., 'org/package')")
|
|
25132
|
+
}
|
|
25133
|
+
}, async ({ namespace }) => {
|
|
25134
|
+
try {
|
|
25135
|
+
const { getPackageEnvironmentVariables: getPackageEnvironmentVariables2 } = await Promise.resolve().then(() => (init_env_loader(), exports_env_loader));
|
|
25136
|
+
const { package: packageVars } = await getPackageEnvironmentVariables2(namespace);
|
|
25137
|
+
if (Object.keys(packageVars).length === 0) {
|
|
25138
|
+
return {
|
|
25139
|
+
content: [{
|
|
25140
|
+
type: "text",
|
|
25141
|
+
text: `\uD83D\uDCE6 No environment variables found for package namespace: ${namespace}
|
|
25142
|
+
|
|
25143
|
+
Use the web interface at http://localhost:5555 to add variables.`
|
|
25144
|
+
}]
|
|
25145
|
+
};
|
|
25146
|
+
}
|
|
25147
|
+
let result = `\uD83D\uDCE6 Environment Variables for ${namespace}
|
|
25148
|
+
`;
|
|
25149
|
+
result += `${"=".repeat(50)}
|
|
25150
|
+
|
|
25151
|
+
`;
|
|
25152
|
+
for (const [key, info] of Object.entries(packageVars)) {
|
|
25153
|
+
result += `\uD83D\uDD11 ${key}
|
|
25154
|
+
`;
|
|
25155
|
+
result += ` Value: ${info.encrypted ? "[encrypted]" : "[hidden]"}
|
|
25156
|
+
`;
|
|
25157
|
+
if (info.description) {
|
|
25158
|
+
result += ` Description: ${info.description}
|
|
25159
|
+
`;
|
|
25160
|
+
}
|
|
25161
|
+
result += `
|
|
25162
|
+
`;
|
|
25163
|
+
}
|
|
25164
|
+
result += `
|
|
25165
|
+
\uD83D\uDCA1 Use the web interface at http://localhost:5555 to view and edit these variables.`;
|
|
25166
|
+
return {
|
|
25167
|
+
content: [{
|
|
25168
|
+
type: "text",
|
|
25169
|
+
text: result
|
|
25170
|
+
}]
|
|
25171
|
+
};
|
|
25172
|
+
} catch (error) {
|
|
25173
|
+
logger_default.error(`Error listing package env vars:`, error);
|
|
25174
|
+
return {
|
|
25175
|
+
content: [{
|
|
25176
|
+
type: "text",
|
|
25177
|
+
text: `Error listing environment variables: ${error instanceof Error ? error.message : String(error)}`
|
|
25178
|
+
}],
|
|
25179
|
+
isError: true
|
|
25180
|
+
};
|
|
25181
|
+
}
|
|
25182
|
+
});
|
|
25183
|
+
server.registerTool("list-all-package-namespaces", {
|
|
25184
|
+
title: "List All Package Namespaces",
|
|
25185
|
+
description: "List all available package namespaces with environment variables",
|
|
25186
|
+
inputSchema: {}
|
|
25187
|
+
}, async () => {
|
|
25188
|
+
try {
|
|
25189
|
+
const { getAllPackageNamespaces: getAllPackageNamespaces2 } = await Promise.resolve().then(() => (init_env_manager_server(), exports_env_manager_server));
|
|
25190
|
+
const packages = await getAllPackageNamespaces2();
|
|
25191
|
+
if (packages.length === 0) {
|
|
25192
|
+
return {
|
|
25193
|
+
content: [{
|
|
25194
|
+
type: "text",
|
|
25195
|
+
text: `\uD83D\uDCE6 No package namespaces found
|
|
25196
|
+
|
|
25197
|
+
Use the web interface at http://localhost:5555 to create and manage packages.`
|
|
25198
|
+
}]
|
|
25199
|
+
};
|
|
25200
|
+
}
|
|
25201
|
+
let result = `\uD83D\uDCE6 Available Package Namespaces
|
|
25202
|
+
`;
|
|
25203
|
+
result += `${"=".repeat(40)}
|
|
25204
|
+
|
|
25205
|
+
`;
|
|
25206
|
+
for (const pkg of packages) {
|
|
25207
|
+
const varCount = Object.keys(pkg.variables).length;
|
|
25208
|
+
result += `\uD83C\uDFF7️ ${pkg.namespace}
|
|
25209
|
+
`;
|
|
25210
|
+
result += ` Variables: ${varCount}
|
|
25211
|
+
`;
|
|
25212
|
+
result += ` Path: ${pkg.path}
|
|
25213
|
+
|
|
25214
|
+
`;
|
|
25215
|
+
}
|
|
25216
|
+
result += `
|
|
25217
|
+
\uD83D\uDCA1 Use the web interface at http://localhost:5555 to manage these packages.`;
|
|
25218
|
+
return {
|
|
25219
|
+
content: [{
|
|
25220
|
+
type: "text",
|
|
25221
|
+
text: result
|
|
25222
|
+
}]
|
|
25223
|
+
};
|
|
25224
|
+
} catch (error) {
|
|
25225
|
+
logger_default.error(`Error listing package namespaces:`, error);
|
|
25226
|
+
return {
|
|
25227
|
+
content: [{
|
|
25228
|
+
type: "text",
|
|
25229
|
+
text: `Error listing package namespaces: ${error instanceof Error ? error.message : String(error)}`
|
|
25230
|
+
}],
|
|
25231
|
+
isError: true
|
|
25232
|
+
};
|
|
25233
|
+
}
|
|
25234
|
+
});
|
|
25235
|
+
async function registerDynamicTool(tool, verificationInfo) {
|
|
22600
25236
|
const toolName = `enact-${tool.name.replace(/[^a-zA-Z0-9-_]/g, "-")}`;
|
|
22601
|
-
|
|
25237
|
+
let description = tool.description || `Execute ${tool.name} tool`;
|
|
25238
|
+
const status = verificationInfo.isValid ? "✅" : "❌";
|
|
25239
|
+
description += `
|
|
25240
|
+
|
|
25241
|
+
\uD83D\uDD10 Signature Status: ${status} ${verificationInfo.message}`;
|
|
25242
|
+
description += `
|
|
25243
|
+
\uD83D\uDCCB Policy: ${verificationInfo.policy}`;
|
|
22602
25244
|
const inputSchema = {};
|
|
22603
25245
|
if (tool.inputSchema?.properties) {
|
|
22604
25246
|
for (const [key, prop] of Object.entries(tool.inputSchema.properties)) {
|
|
@@ -22721,13 +25363,14 @@ ${safeJsonStringify(tools)}`
|
|
|
22721
25363
|
});
|
|
22722
25364
|
server.registerTool("enact-register-tool", {
|
|
22723
25365
|
title: "Register Tool",
|
|
22724
|
-
description: "Register a tool as an MCP tool using direct core integration",
|
|
25366
|
+
description: "Register a tool as an MCP tool using direct core integration with mandatory signature verification",
|
|
22725
25367
|
inputSchema: {
|
|
22726
|
-
name: exports_external.string().describe("Name of the tool to register")
|
|
25368
|
+
name: exports_external.string().describe("Name of the tool to register"),
|
|
25369
|
+
verifyPolicy: exports_external.enum(["permissive", "enterprise", "paranoid"]).optional().describe("Verification policy for signature checking")
|
|
22727
25370
|
}
|
|
22728
|
-
}, async ({ name }) => {
|
|
25371
|
+
}, async ({ name, verifyPolicy = "permissive" }) => {
|
|
22729
25372
|
try {
|
|
22730
|
-
logger_default.info(`Registering tool via direct core library: ${name}`);
|
|
25373
|
+
logger_default.info(`Registering tool via direct core library: ${name} with policy: ${verifyPolicy}`);
|
|
22731
25374
|
const tool = await enactCore2.getToolInfo(name);
|
|
22732
25375
|
if (!tool) {
|
|
22733
25376
|
return {
|
|
@@ -22738,11 +25381,54 @@ server.registerTool("enact-register-tool", {
|
|
|
22738
25381
|
isError: true
|
|
22739
25382
|
};
|
|
22740
25383
|
}
|
|
22741
|
-
|
|
25384
|
+
logger_default.info(`Performing mandatory signature verification for: ${name} with policy: ${verifyPolicy}`);
|
|
25385
|
+
const policyKey = verifyPolicy.toUpperCase();
|
|
25386
|
+
const policy = VERIFICATION_POLICIES[policyKey] || VERIFICATION_POLICIES.PERMISSIVE;
|
|
25387
|
+
const verificationResult = await verifyTool(tool, policy);
|
|
25388
|
+
if (!verificationResult.isValid) {
|
|
25389
|
+
let errorMessage = `❌ Tool "${name}" signature verification failed.
|
|
25390
|
+
|
|
25391
|
+
`;
|
|
25392
|
+
errorMessage += `Policy: ${verifyPolicy}
|
|
25393
|
+
`;
|
|
25394
|
+
errorMessage += `Valid signatures: ${verificationResult.validSignatures}/${verificationResult.totalSignatures}
|
|
25395
|
+
`;
|
|
25396
|
+
if (verificationResult.errors.length > 0) {
|
|
25397
|
+
errorMessage += `
|
|
25398
|
+
Errors:
|
|
25399
|
+
`;
|
|
25400
|
+
verificationResult.errors.forEach((error) => {
|
|
25401
|
+
errorMessage += ` • ${error}
|
|
25402
|
+
`;
|
|
25403
|
+
});
|
|
25404
|
+
}
|
|
25405
|
+
errorMessage += `
|
|
25406
|
+
\uD83D\uDCA1 You can:
|
|
25407
|
+
`;
|
|
25408
|
+
errorMessage += ` • Use a different verification policy (permissive/enterprise/paranoid)
|
|
25409
|
+
`;
|
|
25410
|
+
errorMessage += ` • Verify the tool's signatures manually using 'enact sign verify'
|
|
25411
|
+
`;
|
|
25412
|
+
errorMessage += ` • Ensure the tool has valid cryptographic signatures before registration
|
|
25413
|
+
`;
|
|
25414
|
+
return {
|
|
25415
|
+
content: [{
|
|
25416
|
+
type: "text",
|
|
25417
|
+
text: errorMessage
|
|
25418
|
+
}],
|
|
25419
|
+
isError: true
|
|
25420
|
+
};
|
|
25421
|
+
}
|
|
25422
|
+
logger_default.info(`✅ Tool "${name}" signature verification passed: ${verificationResult.message}`);
|
|
25423
|
+
await registerDynamicTool(tool, {
|
|
25424
|
+
isValid: verificationResult.isValid,
|
|
25425
|
+
message: verificationResult.message,
|
|
25426
|
+
policy: verifyPolicy
|
|
25427
|
+
});
|
|
22742
25428
|
return {
|
|
22743
25429
|
content: [{
|
|
22744
25430
|
type: "text",
|
|
22745
|
-
text: `✅ Successfully registered tool: ${name}`
|
|
25431
|
+
text: `✅ Successfully registered tool: ${name} (signature verified with ${verifyPolicy} policy)`
|
|
22746
25432
|
}]
|
|
22747
25433
|
};
|
|
22748
25434
|
} catch (error) {
|
|
@@ -22803,9 +25489,26 @@ ${safeJsonStringify(allResults)}`
|
|
|
22803
25489
|
});
|
|
22804
25490
|
async function main() {
|
|
22805
25491
|
try {
|
|
25492
|
+
process.on("SIGINT", () => {
|
|
25493
|
+
logger_default.info("Received SIGINT, shutting down gracefully...");
|
|
25494
|
+
if (webServerInstance) {
|
|
25495
|
+
logger_default.info("Shutting down web server...");
|
|
25496
|
+
webServerInstance.close();
|
|
25497
|
+
}
|
|
25498
|
+
process.exit(0);
|
|
25499
|
+
});
|
|
25500
|
+
process.on("SIGTERM", () => {
|
|
25501
|
+
logger_default.info("Received SIGTERM, shutting down gracefully...");
|
|
25502
|
+
if (webServerInstance) {
|
|
25503
|
+
logger_default.info("Shutting down web server...");
|
|
25504
|
+
webServerInstance.close();
|
|
25505
|
+
}
|
|
25506
|
+
process.exit(0);
|
|
25507
|
+
});
|
|
22806
25508
|
const transport = new StdioServerTransport;
|
|
22807
25509
|
await server.connect(transport);
|
|
22808
25510
|
logger_default.info("\uD83D\uDE80 Enact MCP Server with Direct Core Integration started successfully");
|
|
25511
|
+
logger_default.info("\uD83D\uDCA1 Use 'launch-env-manager-server' tool to start the web interface for environment management");
|
|
22809
25512
|
} catch (error) {
|
|
22810
25513
|
console.error("❌ Server connection error:", error);
|
|
22811
25514
|
if (error instanceof Error) {
|